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

Popular posts from this blog

Hatching array of circles in AutoCAD using c# -

ios - UITEXTFIELD InputView Uipicker not working in swift -

Python Pig Latin Translator -