Skip to content

Instantly share code, notes, and snippets.

@mbaba
Created April 17, 2015 10:09
Show Gist options
  • Save mbaba/463be48790cbc655a13b to your computer and use it in GitHub Desktop.
Save mbaba/463be48790cbc655a13b to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
<link rel="stylesheet" type="text/css" href="main.css">
<title>Matrix</title>
</head>
<body>
<script type="text/javascript">
// variables
var w = 1500;
var h = 800;
var padding = [85, 105, 85, 105];
var labels = ["Time pressure", "Discrimination", "Communication Problem", "Cooperation Problem", "Lack of Control", "Job Insecurity", "Difficult Customers", "Supervisor-Employee Problem", "Irregular Hours", "Human Resources Policy"]
var widthScaleCountry = d3.scale.ordinal()
.rangeRoundBands([0, w - padding[1] - padding[3] ], 0.1);
var heightScaleLabel = d3.scale.ordinal()
.rangeRoundBands([ padding[0], h - padding[2] ], 0.1);
var rScale = d3.scale.sqrt()
.domain([1, 81])
.range([3, 20]);
var xAxisCountryBottom = d3.svg.axis()
.scale(widthScaleCountry)
.orient("bottom");
var xAxisCountryTop = d3.svg.axis()
.scale(widthScaleCountry)
.orient("top");
var yAxisLabelLeft = d3.svg.axis()
.scale(heightScaleLabel)
.orient("left");
var yAxisLabelRight = d3.svg.axis()
.scale(heightScaleLabel)
.orient("right");
d3.select("body")
.append("div")
.attr("id", "wrapper");
d3.select("div", "#wrapper")
.append("div")
.attr("id", "container");
var matrix = d3.select("#container")
.append("svg")
.attr("width", w)
.attr("height", h);
var tooltip = d3.select("body")
.append("div")
.attr("class", "tooltip");
d3.csv("psychosocial_risk_major_concerns.csv", function(data) {
console.log(data);
widthScaleCountry.domain(data.map(function(d) { return d.country; } ));
heightScaleLabel.domain(labels);
// time_pressure
var circles = matrix.selectAll(".time-pressure")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 125)
.attr("r", function(d) {
return rScale(+d.time_pressure);})
.attr("class", "time-pressure");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Time Pressure - ' + d.time_pressure + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "time-pressure")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// discrimination
var circles = matrix.selectAll(".discrimination")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 195)
.attr("r", function(d) {
return rScale(+d.discrimination);})
.attr("class", "discrimination");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Discrimination - ' + d.discrimination + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "discrimination")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// communication_problem
var circles = matrix.selectAll(".communication")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 260)
.attr("r", function(d) {
return rScale(+d.communication_problem);})
.attr("class", "communication");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Communication Problem - ' + d.communication_problem + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "communication")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// cooperation_problem
var circles = matrix.selectAll(".cooperation")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 325)
.attr("r", function(d) {
return rScale(+d.cooperation_problem);})
.attr("class", "cooperation");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Cooperation Problem - ' + d.cooperation_problem + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "cooperation")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// lack_control
var circles = matrix.selectAll(".lack-control")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 377)
.attr("r", function(d) {
return rScale(+d.lack_control);})
.attr("class", "lack-control");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Lack of Control - ' + d.lack_control + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "lack-control")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// job_insecurity
var circles = matrix.selectAll(".job-insecurity")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 435)
.attr("r", function(d) {
return rScale(+d.job_insecurity);})
.attr("class", "job-insecurity");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Job Insecurity - ' + d.job_insecurity + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "job-insecurity")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// difficult-customers
var circles = matrix.selectAll(".difficult-customers")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 500)
.attr("r", function(d) {
return rScale(+d.difficult_customers);})
.attr("class", "difficult-customers");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Difficult Customers - ' + d.difficult_customers + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "difficult-customers")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// supervisor_employee_problem
var circles = matrix.selectAll(".supervisor-employee")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 570)
.attr("r", function(d) {
return rScale(+d.supervisor_employee_problem);})
.attr("class", "supervisor-employee");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Supervisor Employee Problem - ' + d.supervisor_employee_problem + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "supervisor-employee")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// human_resources_policy
var circles = matrix.selectAll(".human-resources-policy")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 690)
.attr("r", function(d) {
return rScale(+d.human_resources_policy);})
.attr("class", "human-resources-policy");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Human Resources Policy - ' + d.human_resources_policy + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "human-resources-policy")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// irregular_hours
var circles = matrix.selectAll(".irregular-hours")
.data(data)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
return widthScaleCountry(d.country) + padding[3] + 20;
})
.attr("cy", 625)
.attr("r", function(d) {
return rScale(+d.irregular_hours);})
.attr("class", "irregular-hours");
circles.on("mouseover", function(d) {
d3.select(this)
.classed("hover", true)
.attr("class", "hover-matrix")
tooltip = d3.select(".tooltip");
tooltip.html('<span class="country">' + d.country + '</span>' + '<br />' + 'Irregular Hours - ' + d.irregular_hours + '%')
.style("top", d3.event.pageY - 12 + "px")
.style("opacity", 0.9)
})
circles.on("mouseout", function() {
d3.select(this)
.classed("hover", false)
.attr("class", "irregular-hours")
tooltip.style("opacity", 0)
})
circles.on("mousemove", function (d) {
var tool_width = d3.select(".tooltip").node().getBoundingClientRect().width;
if(d3.event.pageX > (w - tool_width)) {
tooltip.style("left", d3.event.pageX - tool_width - 12 + "px")
} else {
tooltip.style("left", d3.event.pageX + 12 + "px")
}
})
// axis
matrix.append("g")
.attr("class", "x matrix-axis")
.attr("transform", "translate("+ padding[3] + "," + (padding[2]) + ")")
.call(xAxisCountryTop)
.selectAll("text")
.style("text-anchor", "end")
.attr("dy", "10")
.attr("transform", function(d) {
return "rotate(90)"
});
matrix.append("g")
.attr("class", "x matrix-axis")
.attr("transform", "translate("+ padding[3] + "," + (h - padding[2]) + ")")
.call(xAxisCountryBottom)
.selectAll("text")
.style("text-anchor", "start")
.attr("dy", "-5")
.attr("transform", function(d) {
return "rotate(90)"
});
matrix.append("g")
.attr("class", "y matrix-axis")
.attr("transform", "translate(" + (padding[3]) + ",0)")
.call(yAxisLabelLeft)
.selectAll(".tick text")
.call(wrap, heightScaleLabel.rangeBand());
matrix.append("g")
.attr("class", "y matrix-axis")
.attr("transform", "translate(" + (w - padding[1]) + ",0)")
.call(yAxisLabelRight)
.selectAll(".tick text")
.call(wrap, heightScaleLabel.rangeBand());
// line brakes
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
// line breaks
});
</script>
</body>
body {
background-color: #d2d0cc;
font-family: Helvetica, Arial, sans-serif;
font-size: 16px;
}
h1 {
font-size: 28px;
font-weight: bold;
font-variant: small-caps;
text-align: center;
line-height: 14px;
color: dimgrey;
}
a {
text-decoration: none;
}
a:link, a:visited {
color: dimgrey;
border-bottom: 2px dotted dimgrey;
}
a:hover {
color: #ffc04c;
border-bottom: 2px dotted #ffc04c;
}
.chart-title {
font-size: 20px;
font-weight: bold;
font-variant: small-caps;
letter-spacing: 2px;
padding-top: 5px;
padding-bottom: 5px;
text-align: center;
color: dimgrey;
}
.text {
padding: 1px 1%;
margin-left: 1%;
margin-right: 1%;
margin-bottom: 25px;
background-color: #ededeb;
text-align: left;
}
.axis path, .axis line {
fill: none;
stroke: dimgrey;
shape-rendering: crispEdges;
}
.matrix-axis path, .matrix-axis line {
visibility: hidden;
}
.axis text, .matrix-axis text, .label {
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
fill: dimgrey;
}
.label {
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
font-weight: bold;
letter-spacing: 2px;
fill: dimgrey;
}
#wrapper {
width: 85%;
height: 100%;
margin: 0 auto;
position: relative;
}
#container {
padding: 1px 1%;
margin-left: 1%;
margin-right: 1%;
margin-bottom: 25px;
background-color: #ededeb;
text-align: center;
}
#col-left1, #col-left2, #col-left3, #col-left4, #col-left5, #col-right1, #col-right2, #col-right3, #col-right4, #col-right5 {
margin-bottom: 25px;
padding-left: 1%;
padding-bottom: 1%;
width: 47%;
background-color: #ededeb;
}
#col-left1, #col-left2, #col-left3, #col-left4, #col-left5 {
float: left;
margin-left: 1%;
}
#col-right1, #col-right2, #col-right3, #col-right4, #col-right5 {
float: right;
margin-right: 1%
}
svg {
fill: #ff7b00;
}
/*Circles*/
.time-pressure {
fill: #a6cee3;
}
.discrimination {
fill: #1f78b4;
}
.communication {
fill: #b2df8a;
}
.cooperation {
fill: #33a02c;
}
.lack-control {
fill: #fb9a99;
}
.job-insecurity {
fill: #e31a1c;
}
.difficult-customers {
fill: #fdbf6f;
}
.supervisor-employee {
fill: #b15928;
}
.irregular-hours {
fill: #cab2d6;
}
.human-resources-policy {
fill: #6a3d9a;
}
/*ToolTip*/
.tooltip {
padding: 3px;
background-color: #d2d0cc;
border-radius: 4px;
position: absolute;
font-size: 11px;
line-height: 14px;
opacity: 0;
}
.country {
font-weight: bold;
font-size: 11px;
}
.hover {
cursor: crosshair;
}
.hover-matrix {
fill: #ff7b00;
cursor: crosshair;
}
country time_pressure discrimination communication_problem cooperation_problem lack_control job_insecurity difficult_customers supervisor_employee_problem irregular_hours human_resources_policy work_related_stress violence bullying_harassment
Austria 57 2.9 22.8 17 10.5 18.4 46.6 17 22.8 8.9 49 10.2 12.3
Belgium 57.4 8 37.8 32.1 21.4 19.3 47 19.8 23.6 15.4 28 19.7 18.3
Bulgaria 49 7.7 19.1 24.8 20.8 37.7 50.6 22.3 11.1 19.5 52.3 32.4 33.8
Croatia 42.5 3.6 17.5 14 11.3 23.5 41.5 9.3 11.4 8.6 29.9 13.2 14.5
Cyprus 66.4 18 31.6 30 29.6 25.1 56.1 27.6 25.3 21.9 44 16.5 14.5
Czech Republic 55.4 28.7 65.5 62.3 62.4 43.7 79 59.6 42.4 33.5 22.6 19.7 23.5
Denmark 68.5 3.2 38 32.1 12.5 30.8 45.5 18.1 19.1 14 28.5 7.5 6.6
Estonia 54.1 1.3 23.3 14 18 20 55.7 12.4 20.7 12.9 21.1 1.7 1.8
Finland 71 2.6 36.3 19.2 12.7 35.5 42.2 20.4 28 13.7 18.2 4.7 0.7
France 53.2 12.1 38 35.2 30.6 25.3 48.5 30.1 26.3 20.6 48.7 29.6 24.9
Germany 66.8 3.7 25.8 24.1 16.1 22.2 52.7 19.6 27 10.9 50.4 14.5 18.6
Greece 52 5.7 14.8 21.2 23.2 24.4 66.7 16.2 11.5 13.7 42.9 11.3 9.5
Hungary 37.4 1.3 11.6 9.8 4.1 40 41.8 3.7 7.2 4 21.9 2.6 1.5
Ireland 52.5 5.5 37.4 25.4 20.4 42.2 63.9 23.6 26.8 16 27.7 19.1 21.5
Italy 31.4 1.5 17.2 21.7 14.6 19.7 34.5 13.9 7.4 8.1 11.7 3.8 2.2
Latvia 50.9 1.7 14 18.4 27.8 24.5 66.8 17.4 26.4 21.7 30.6 23.4 23
Lithuania 41.3 3.5 17.2 20.8 24.2 27.5 54.7 16.5 10.3 17.5 15.8 5.5 3.9
Luxembourg 57.3 3.9 28.8 30.5 16 18.6 52.9 17.8 24 12 43 14.4 14
Malta 46.1 1.4 14.4 17.2 17.7 11 47 11.4 17.6 8.8 23.1 4.6 4
Netherlands 55.3 3.1 30.5 22.2 15.9 19 41.5 15.7 23.9 9.5 19.3 4.2 2.2
Norway 73.2 2 24.4 21.4 11.9 16.1 41 3.5 25.1 13.4 68.7 25.8 43.6
Poland 42.5 1.9 15.4 19 15.7 30.6 57.8 15.8 12.3 8.2 65 31.9 29.3
Portugal 63.9 19.7 41.9 42.2 37.2 43.4 52.7 31.4 26.2 32.5 70.7 52.5 52.9
Romania 43.7 14.9 29.2 30 29.4 32.6 44.3 28.2 24.1 23.6 62.6 44.1 44.1
Slovakia 53.1 3.2 17.3 11.7 10 37 31.7 10.5 13.1 8.9 24 6.8 4.1
Slovenia 49.5 1.2 17.3 11.2 10.4 25.9 47.5 14.2 16.7 6.5 43.6 2 0.4
Spain 42.7 1.6 13.3 12.5 12.9 13.3 45.2 11.1 15.3 9.6 38.1 23.5 22.8
Sweden 80.1 3.3 37.9 31.4 23.9 22.5 49.6 18.3 31.8 15.3 18.3 5.1 0.5
Switzerland 64 6.4 34.3 26.2 18.7 25.3 48.4 22.7 29.9 11.2 36.5 15.5 18.7
Turkey 42.3 22.9 38.3 41.1 44.4 39.1 42.8 35.7 31.2 39.3 66.4 65.3 75.5
United Kingdom 48.8 6.1 32.5 22.6 13.8 32 55.8 15.6 22.1 10.3 22.7 16.1 14.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment