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"?> |