line chart with dropdown selector
| [ | |
| { | |
| "state":"Maine", | |
| "produce":"apples", | |
| "year":1900, | |
| "value":"131" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"apples", | |
| "year":1950, | |
| "value":"231" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"apples", | |
| "year":2000, | |
| "value":"191" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"apples", | |
| "year":2015, | |
| "value":"302" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"apples", | |
| "year":1900, | |
| "value":"31" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"apples", | |
| "year":1950, | |
| "value":"331" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"apples", | |
| "year":2000, | |
| "value":"291" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"apples", | |
| "year":2015, | |
| "value":"250" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"apples", | |
| "year":1900, | |
| "value":"11" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"apples", | |
| "year":1950, | |
| "value":"230" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"apples", | |
| "year":2000, | |
| "value":"185" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"apples", | |
| "year":2015, | |
| "value":"310" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"pears", | |
| "year":1900, | |
| "value":"171" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"pears", | |
| "year":1950, | |
| "value":"121" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"pears", | |
| "year":2000, | |
| "value":"231" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"pears", | |
| "year":2015, | |
| "value":"202" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"pears", | |
| "year":1900, | |
| "value":"73" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"pears", | |
| "year":1950, | |
| "value":"151" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"pears", | |
| "year":2000, | |
| "value":"399" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"pears", | |
| "year":2015, | |
| "value":"140" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"pears", | |
| "year":1900, | |
| "value":"146" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"pears", | |
| "year":1950, | |
| "value":"130" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"pears", | |
| "year":2000, | |
| "value":"195" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"pears", | |
| "year":2015, | |
| "value":"210" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"tomatoes", | |
| "year":1900, | |
| "value":"71" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"tomatoes", | |
| "year":1950, | |
| "value":"221" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"tomatoes", | |
| "year":2000, | |
| "value":"31" | |
| }, | |
| { | |
| "state":"Maine", | |
| "produce":"tomatoes", | |
| "year":2015, | |
| "value":"102" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"tomatoes", | |
| "year":1900, | |
| "value":"173" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"tomatoes", | |
| "year":1950, | |
| "value":"194" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"tomatoes", | |
| "year":2000, | |
| "value":"195" | |
| }, | |
| { | |
| "state":"Pennsylvania", | |
| "produce":"tomatoes", | |
| "year":2015, | |
| "value":"230" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"tomatoes", | |
| "year":1900, | |
| "value":"216" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"tomatoes", | |
| "year":1950, | |
| "value":"184" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"tomatoes", | |
| "year":2000, | |
| "value":"125" | |
| }, | |
| { | |
| "state":"Ohio", | |
| "produce":"tomatoes", | |
| "year":2015, | |
| "value":"150" | |
| } | |
| ] |
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> /* set the CSS */ | |
| body { font: 12px Arial;} | |
| path { | |
| stroke: #ccc; | |
| stroke-width: 2; | |
| fill: none; | |
| } | |
| .axis path, | |
| .axis line { | |
| fill: none; | |
| stroke: grey; | |
| stroke-width: 1; | |
| shape-rendering: crispEdges; | |
| } | |
| #legendContainer{ | |
| position:absolute; | |
| top:60px; | |
| left:10px; | |
| overflow: auto; | |
| height:490px; | |
| width:110px; | |
| } | |
| #legend{ | |
| width:90px; | |
| height:200px; | |
| } | |
| .legend { | |
| font-size: 12px; | |
| font-weight: normal; | |
| text-anchor: left; | |
| } | |
| .legendcheckbox{ | |
| cursor: pointer; | |
| } | |
| #showAll{ | |
| position:absolute; | |
| top:600px; | |
| left:880px; | |
| } | |
| #clearAll{ | |
| position:absolute; | |
| top:600px; | |
| left:950px; | |
| } | |
| input{ | |
| border-radius:5px; | |
| padding:5px 10px; | |
| background:#999; | |
| border:0; | |
| color:#fff; | |
| } | |
| #inds{ | |
| position:absolute; | |
| top:10px; | |
| left:10px; | |
| } | |
| </style> | |
| <body> | |
| <!-- load the d3.js library --> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script src="//code.jquery.com/jquery-1.10.2.js"></script> | |
| <select id="inds"> | |
| <option value="apples" selected="selected">apples</option> | |
| <option value="pears">pears</option> | |
| <option value="tomatoes">tomatoes</option> | |
| </select> | |
| <div id="legendContainer" class="legendContainer"> | |
| <svg id="legend"></svg> | |
| </div> | |
| <div id="showAll"> | |
| <input name="showAllButton" | |
| type="button" | |
| value="Show All" | |
| onclick="showAll()" /> | |
| </div> | |
| <div id="clearAll"> | |
| <input name="clearAllButton" | |
| type="button" | |
| value="Clear All" | |
| onclick="clearAll()" /> | |
| </div> | |
| <script> | |
| function filterJSON(json, key, value) { | |
| var result = []; | |
| json.forEach(function(val,idx,arr){ | |
| if(val[key] == value){ | |
| result.push(val) | |
| } | |
| }) | |
| return result; | |
| } | |
| // Set the dimensions of the canvas / graph | |
| var margin = {top: 50, right: 20, bottom: 30, left: 160}, | |
| width = 1000 - margin.left - margin.right, | |
| height = 550 - margin.top - margin.bottom; | |
| // Parse the date / time | |
| // Set the ranges | |
| var x = d3.time.scale().range([0, width]); | |
| var y = d3.scale.linear().range([height, 0]); | |
| // Define the axes | |
| var xAxis = d3.svg.axis().scale(x) | |
| .orient("bottom").ticks(5) | |
| .tickFormat(d3.time.format("%Y")) | |
| var yAxis = d3.svg.axis().scale(y) | |
| .orient("left").ticks(5); | |
| // Define the line | |
| var stateline = d3.svg.line() | |
| .interpolate("cardinal") | |
| .x(function(d) { return x(d.year); }) | |
| .y(function(d) { return y(d.value); }); | |
| // Adds the svg canvas | |
| var svg = d3.select("body") | |
| .append("svg") | |
| .attr("width", width + margin.left + margin.right) | |
| .attr("height", height + margin.top + margin.bottom) | |
| .append("g") | |
| .attr("transform", | |
| "translate(" + margin.left + "," + margin.top + ")"); | |
| var data; | |
| // Get the data | |
| d3.json("data.json", function(error, json) { | |
| console.log(json) | |
| json.forEach(function(d) { | |
| d.value = +d.value; | |
| }); | |
| d3.select('#inds') | |
| .on("change", function () { | |
| var sect = document.getElementById("inds"); | |
| var section = sect.options[sect.selectedIndex].value; | |
| data = filterJSON(json, 'produce', section); | |
| //debugger | |
| data.forEach(function(d) { | |
| d.value = +d.value; | |
| //d.year = parseDate(String(d.year)); | |
| d.active = true; | |
| }); | |
| //debugger | |
| updateGraph(data); | |
| jQuery('h1.page-header').html(section); | |
| }); | |
| // generate initial graph | |
| data = filterJSON(json, 'produce', 'apples'); | |
| updateGraph(data); | |
| }); | |
| var color = d3.scale.ordinal().range(["#48A36D", "#0096ff", "#ff007e"]); | |
| function updateGraph(data) { | |
| // Scale the range of the data | |
| x.domain(d3.extent(data, function(d) { return d.year; })); | |
| y.domain([d3.min(data, function(d) { return d.value; }), d3.max(data, function(d) { return d.value; })]); | |
| // Nest the entries by state | |
| dataNest = d3.nest() | |
| .key(function(d) {return d.state;}) | |
| .entries(data); | |
| var result = dataNest.filter(function(val,idx, arr){ | |
| return $("." + val.key).attr("fill") != "#ccc" | |
| // matching the data with selector status | |
| }) | |
| var state = svg.selectAll(".line") | |
| .data(result, function(d){return d.key}); | |
| state.enter().append("path") | |
| .attr("class", "line"); | |
| state.transition() | |
| .style("stroke", function(d,i) { return d.color = color(d.key); }) | |
| .attr("id", function(d){ return 'tag'+d.key.replace(/\s+/g, '');}) // assign ID | |
| .attr("d", function(d){ | |
| return stateline(d.values) | |
| }); | |
| state.exit().remove(); | |
| var legend = d3.select("#legend") | |
| .selectAll("text") | |
| .data(dataNest, function(d){return d.key}); | |
| //checkboxes | |
| legend.enter().append("rect") | |
| .attr("width", 10) | |
| .attr("height", 10) | |
| .attr("x", 0) | |
| .attr("y", function (d, i) { return 0 +i*15; }) // spacing | |
| .attr("fill",function(d) { | |
| return color(d.key); | |
| }) | |
| .attr("class", function(d,i){return "legendcheckbox " + d.key}) | |
| .on("click", function(d){ | |
| d.active = !d.active; | |
| d3.select(this).attr("fill", function(d){ | |
| if(d3.select(this).attr("fill") == "#ccc"){ | |
| return color(d.key); | |
| }else { | |
| return "#ccc"; | |
| } | |
| }) | |
| var result = dataNest.filter(function(val,idx, arr){ | |
| return $("." + val.key).attr("fill") != "#ccc" | |
| // matching the data with selector status | |
| }) | |
| // Hide or show the lines based on the ID | |
| svg.selectAll(".line").data(result, function(d){return d.key}) | |
| .enter() | |
| .append("path") | |
| .attr("class", "line") | |
| .style("stroke", function(d,i) { return d.color = color(d.key); }) | |
| .attr("d", function(d){ | |
| return stateline(d.values); | |
| }); | |
| svg.selectAll(".line").data(result, function(d){return d.key}).exit().remove() | |
| }) | |
| // Add the Legend text | |
| legend.enter().append("text") | |
| .attr("x", 15) | |
| .attr("y", function(d,i){return 10 +i*15;}) | |
| .attr("class", "legend"); | |
| legend.transition() | |
| .style("fill", "#777" ) | |
| .text(function(d){return d.key;}); | |
| legend.exit().remove(); | |
| svg.selectAll(".axis").remove(); | |
| // Add the X Axis | |
| svg.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0," + height + ")") | |
| .call(xAxis); | |
| // Add the Y Axis | |
| svg.append("g") | |
| .attr("class", "y axis") | |
| .call(yAxis); | |
| }; | |
| function clearAll(){ | |
| d3.selectAll(".line") | |
| .transition().duration(100) | |
| .attr("d", function(d){ | |
| return null; | |
| }); | |
| d3.select("#legend").selectAll("rect") | |
| .transition().duration(100) | |
| .attr("fill", "#ccc"); | |
| }; | |
| function showAll(){ | |
| d3.selectAll(".line") | |
| .transition().duration(100) | |
| .attr("d", function(d){ | |
| return stateline(d.values); | |
| }); | |
| d3.select("#legend").selectAll("rect") | |
| .attr("fill",function(d) { | |
| if (d.active == true){ | |
| return color(d.key); | |
| } | |
| }) | |
| }; | |
| </script> | |
| </body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment