A visualization of a 7 Likert scale using d3v4. Based on the diverging stacked bar chart example from mbostock
forked from john-guerra's block: 7-Likert scale results visualization D3 v4
license: gpl-3.0 |
A visualization of a 7 Likert scale using d3v4. Based on the diverging stacked bar chart example from mbostock
forked from john-guerra's block: 7-Likert scale results visualization D3 v4
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<svg width="960" height="500"></svg> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/d3-color.v1.min.js"></script> | |
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script> | |
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> | |
<script> | |
var LIKERT_MAX = 7; | |
var LIKERT_NEUTRAL = Math.round(LIKERT_MAX/2); | |
var svg = d3.select("svg"), | |
margin = {top: 20, right: 30, bottom: 30, left: 60}, | |
width = +svg.attr("width"), | |
height = +svg.attr("height"); | |
var y = d3.scaleBand() | |
.padding(0.1) | |
.rangeRound([margin.top, height - margin.bottom]); | |
var x = d3.scaleLinear() | |
.rangeRound([margin.left, width - margin.right]); | |
var z = d3.scaleSequential(d3.interpolateRdBu) | |
.domain([-3,3]); | |
d3.csv("results.csv", function (err, data) { | |
if (err) throw err; | |
var series = d3.stack() | |
.keys(d3.range(1,LIKERT_MAX+1)) | |
.offset(stackOffsetLikert) | |
(data); | |
y.domain(data.map(function(d) { return d.question; })); | |
x.domain([d3.min(series, stackMin), d3.max(series, stackMax)]); | |
svg.append("g") | |
.selectAll("g") | |
.data(series) | |
.enter().append("g") | |
.attr("fill", function(d) { return z(+d.key - LIKERT_NEUTRAL); }) | |
.selectAll("rect") | |
.data(function(d) { return d; }) | |
.enter().append("rect") | |
.attr("height", y.bandwidth) | |
.attr("y", function(d) { return y(d.data.question); }) | |
.attr("x", function(d) { return x(d[0]); }) | |
.attr("width", function(d) { return x(d[1]) - x(d[0]); }) | |
svg.append("g") | |
.attr("transform", "translate(0," + (height-margin.bottom) + ")") | |
.call(d3.axisBottom(x)); | |
svg.append("g") | |
.attr("transform", "translate(" + margin.left + ",0)") | |
.call(d3.axisLeft(y)); | |
function stackMin(serie) { | |
return d3.min(serie, function(d) { return d[0]; }); | |
} | |
function stackMax(serie) { | |
return d3.max(serie, function(d) { return d[1]; }); | |
} | |
// Assumes that the series include answers in the LIKERT_MAX Likert scale (default 7), therefore | |
// 1-3 are negative, 4 is neutral and 5-7 are positive | |
function stackOffsetLikert(series, order) { | |
if (!((n = series.length) > 1)) return; | |
for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) { | |
// Stack the neutral and positive values | |
for (yp = yn = 0, i = LIKERT_NEUTRAL-1; i < n; ++i) { | |
dy = (d = series[order[i]][j])[1] - d[0]; | |
if (i=== (LIKERT_NEUTRAL-1)) { | |
//neutral goes centered in the middle | |
d[0] = yp -dy/2, d[1] = yp += dy/2; | |
} else { | |
d[0] = yp, d[1] = yp += dy; | |
} | |
} | |
// Now stack the negative values | |
for (yp = yn = 0, i = LIKERT_NEUTRAL-1; i >= 0 ; --i) { | |
dy = (d = series[order[i]][j])[1] - d[0]; | |
if (i=== (LIKERT_NEUTRAL-1)) { | |
yp -= dy/2; | |
} else | |
if (i <(LIKERT_NEUTRAL-1)) { | |
d[1] = yp, d[0] = yp -= dy; | |
} | |
} | |
} | |
} | |
}) | |
</script> |
���� JFIF � � �� �Exif MM * J R( �i Z � � � T� \ �� !http://ns.adobe.com/xap/1.0/ <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.4.0"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about=""/> </rdf:RDF> </x:xmpmeta> <?xpacket end="w"?> |