javascript - Use multi-tier dropdown (that uses jquery) to filter data and display d3 bar chart -
i have bar chart want user able create using series of dropdown selections.
i have first part done-- select type of produce, produce itself, , bar chart appears.
the problem second filter isn't working. want second filter take data that's been filtered produce type , filter again, year.
any thoughts or input helpful.
plunker: https://plnkr.co/edit/xllk6di5y4pvfgzj3nku?p=preview
code below:
<!doctype html> <meta charset="utf-8"> <style> body { font: 12px arial;} .bar { fill: #0078a5; } .bar:hover { fill: #18b7f2; } #tooltip { position: absolute; width: auto; height: auto; padding: 4px 6px; background-color: #fff; border:1px solid #eee; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; pointer-events: none; } #tooltip.hidden { display: none; } #pop{ background-color: #fff; border:1px solid #eee; } #tooltip p { margin: 0; font-family: sans-serif; font-size: 14px; } .axis { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispedges; } .x.axis path { display: none; } #legendcontainer{ position:absolute; top:85px; left:10px; overflow: auto; height:360px; width:120px; font-family:helvetica, arial, sans-serif; font-size:11px; } #legend{ width:100px; height:200px; } .legend { font-size: 12px; font-weight: normal; text-anchor: left; cursor: pointer; } #bar{ background:#ccc; color:#222; padding:8px 15px; margin-right:6px; border-radius:5px; float:left; width:20px; } .active{ background:#0b3774 !important; color:#fff !important; } #dropdown{ clear:both; } </style> <body> <script src="https://d3js.org/d3.v3.min.js"></script> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <div id="dropdown"> <div class="ccms_form_element cfdiv_custom" id="indselectors"> <label>dimension:</label> <select size="1" id="dimensions" class=" validate['required']" title="" type="select" name="style"> <option value="">-select-</option> <option value="fruit">fruit</option> <option value="vegetables">vegetables</option> </select> <div class="clear"></div> <div id="error-message-style"></div> </div> <div id="secondarydrop"> <div id="fruit" class="style-sub-1" style="display: none;" name="stylesub1"> <label>fruit</label> <select class="inds"> <option value="">- select -</option> <option value="apples">apples</option> <option value="pears">pears</option> </select> </div> <div id="vegetables" class="style-sub-1" style="display: none;" name="stylesub1"> <label>vegetables</label> <select class="inds"> <option value="">- select -</option> <option value="tomatoes">tomatoes</option> </select> </div> </div> <div class="clear"></div> <div id="error-message-style-sub-1"></div> </div> <div id="tertiarydrop"> <div id="apples" class="style-sub-2" style="display: none;" name="stylesub2"> <label>year</label> <select class="years"> <option value="">- select year -</option> <option value="2005">1950</option> <option value="2010">2000</option> </select> </div> <div id="pears" class="style-sub-2" style="display: none;" name="stylesub2"> <label>year</label> <select class="years"> <option value="">- select year -</option> <option value="2005">1900</option> <option value="2010">2015</option> </select> </div> <div id="tomatoes" class="style-sub-2" style="display: none;" name="stylesub2"> <label>year</label> <select class="years"> <option value="">- select year -</option> <option value="2005">2000</option> <option value="2010">2015</option> </select> </div> <div class="clear"></div> <div id="error-message-style-sub-2"></div> </div> </div> <div id="legendcontainer" class="legendcontainer"> <svg id="legend"></svg> </div> <div id="tooltip" class="hidden"> <p><span id="state"></span></p> </div> <script> $("#dimensions").change ( function () { var targid = $(this).val (); $("div.style-sub-1").hide (); $('#' + targid).show (); } ); $(".inds").change ( function () { var targid = $(this).val (); $("div.style-sub-2").hide (); $('#' + targid).show (); } ); function filterjson(json, key, value) { var result = []; (var foo in json) { if (json[foo][key] === value) { result.push(json[foo]); } } return result; } var margin = {top: 20, right: 20, bottom: 130, left: 160}, width = 1200 - margin.left - margin.right, height = 500 - margin.top - margin.bottom, padding = 0.25; var x = d3.scale.ordinal() .rangeroundbands([0, width - margin.left - margin.right], padding); var y = d3.scale.linear() .range([height, 0]); var xaxis = d3.svg.axis() .scale(x) .orient("bottom"); var yaxis = d3.svg.axis() .scale(y) .orient("left") .ticks(10); 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 + ")"); d3.json("data.json", function(error, json) { if (error) throw error; json.foreach(function(d) { d.year = "" + d.year + ""; d.value = +d.value; }); $('.inds') .on("change", function () { var prod = $(this).val(); console.log("prod:", prod); data = filterjson(json, 'produce', prod); console.log("data: ", data); updategraph(data); $('.years') .on("change", function () { var yr = $(this).val(); yr = +yr; console.log("yr:", yr); data1 = filterjson(data, 'year', yr); console.log("data: ", data1); updategraph(data1); }); }); }); function updategraph(data) { data.sort(function(a,b) {return a.value-b.value;}); x.domain(data.map(function(d) { return d.state; })); y.domain([0, d3.max(data, function(d) { return d.value; })]); var color = d3.scale.category20b(); var bars = svg.selectall(".bar") .data(data); bars .enter().append("rect") .attr("class", "bar"); bars.transition() .attr("id", function(d){ return 'tag'+d.state.replace(/\s+/g, '');}) .attr("x", function(d) { return x(d.state); }) .attr("width", x.rangeband()) .attr("y", function(d) {return y(d.value); }) .attr("height", function(d) { return height - y(d.value); }); bars.exit().remove(); svg.selectall(".axis").remove(); var legend = d3.select("#legend") .selectall("text") .data(data); legend.enter().append("text") .attr("x", 0) .attr("y", function(d,i){return 10 +i*15;}) .attr("class", "legend") .style("fill", "#0078a5") .on("click", function(d){ // determine if current line visible d.active = !d.active; // hide or show elements based on id d3.select("#tag"+d.state.replace(/\s+/g, '')) .transition() .duration(100) .style("fill", "#ff3300"); var xposition = parsefloat(d3.select(this).attr("x")) + x.rangeband() + 100; var yposition = parsefloat(d3.select(this).attr("y")) / 2 + height / 2; //update tooltip position , value d3.select("#tooltip") .style("left", xposition + "px") .style("top", yposition + "px") .select("#state") .text(d.state + ": " + d.year + ": " + d.value); d3.select("#tooltip").classed("hidden", false); }); legend.transition() .text(function(d){return d.state;}); legend.exit().remove(); svg.append("g") .attr("class", "y axis") .call(yaxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("value"); }; </script>
data:
[ { "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" } ]
this piece of code make year
property of each element of data string instead of number.
json.foreach(function(d) { d.year = "" + d.year + ""; d.value = +d.value; });
so that, in filterjson
function, when doing strict comparison (===
) between input value (which number) , year
property (which string) , result false
.
i update code replace ===
operator ==
:
if (json[foo][key] == value) { result.push(json[foo]); }
the updated plunker here: https://plnkr.co/edit/1nzudo8wal5sr5srm1rq?p=preview
Comments
Post a Comment