跟踪两个下拉列表中的值

时间:2015-12-07 06:23:03

标签: javascript d3.js

我有一个条形图,从两个下拉列表中提取一个值 - 年份和类型。当我更改这些选项时,条形图并不总是显示正确的数据。我认为我过滤不正确,我想知道什么是更好的方法来解决这个问题。谢谢!

Plunker is here.

代码:

<!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;
    }
    </style>
    <body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <label for="years">Year: </label>
    <select id="years">
        <option value="1900">1900</option>
        <option value="1950">1950</option>
        <option value="2000">2000</option>
        <option value="2015" selected="selected">2015</option>
    </select>
    <label for="inds">Type: </label>
    <select id="inds">
            <option value="apples">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="tooltip" class="hidden">
        <p><span id="state"></span></p>
    </div>

    <script>

    function filterJSON(json, key, value) {
      var result = [];
      for (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;
        });

        var myYear = d3.select("#years").node().value;
        var myInd = d3.select("#inds").node().value;

        console.log("myYear: ", myYear);
        console.log("myInd: ", myInd);

        d3.select('#years')
                .on("change", function () {     
                    var timeo = document.getElementById("years");
                    var yearo = timeo.options[timeo.selectedIndex].value;

                    data = filterJSON(json, 'year', yearo);
                    updateGraph(data);

                });

        d3.select('#inds')
                .on("change", function () {     
                    var sect = document.getElementById("inds");
                    var section = sect.options[sect.selectedIndex].value;

                    data = filterJSON(json, 'produce', section);
                    updateGraph(data);
        });

        // initial graph / defaults     
    var pop = filterJSON(json, 'year', "2015");
    var data = filterJSON(pop, 'produce', 'apples');
    updateGraph(data);

    });

    function updateGraph(data) {  
        // data.sort(function(a,b) {return b.state-a.state;});
        data.forEach(function(d) {
            d.active = true;
        });

        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")
              .on("mouseover", function(d) {
                    //Get this bar's x/y values, then augment for the tooltip
                    var xPosition = parseFloat(d3.select(this).attr("x")) + x.rangeBand() + 100;
                    var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + height / 2;
                    //Update the tooltip position and value
                    d3.select("#tooltip")
                        .style("left", xPosition + "px")
                        .style("top", yPosition + "px")                     
                        .select("#state")
                        .text(d.state + ": " + d.produce + ": " + d.year + ": " + d.value);
                    d3.select("#tooltip").classed("hidden", false);
              })
              .on("mouseout", function() {
                    d3.select("#tooltip").classed("hidden", true);
              })
                .on("click", function(d){
                    d3.select(this).style("fill", "#ff3300");
                });

        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 is visible 
                    d.active = !d.active;
                    // Hide or show the elements based on the 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 the tooltip position and 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>

数据:

[
    {
      "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"
    }
    ]

1 个答案:

答案 0 :(得分:1)

您可以使用过滤器而不是每个属性,并将两个循环合并为一个,如下所示:

<input type='text' placeholder='Write your comment here' />

工作代码here

希望这有帮助!