代码之家  ›  专栏  ›  技术社区  ›  sprucegoose

在d3中,两个数据集之间的转换,从单线图到多行图

  •  0
  • sprucegoose  · 技术社区  · 8 年前

    我正试图建立一个从一行到多行的图表。我已经把这两个图表分开了,但合并起来有困难。我的想法是,我要显示每年销售的所有水果的总数,然后显示每年销售的每个水果的数量。

    这是我使用的模板: http://bl.ocks.org/d3noob/a048edddbf83bff03a34

    在我的代码中,单行显示得很好。当我单击“更新”时,轴会按应该的方式更新,但数据不会更新。任何帮助都将非常感谢。

    我的密码在一个破车里,这里: https://plnkr.co/edit/dgwsGLIRbZ2qm7faEvSw?p=preview

    代码也在下面。

        <!DOCTYPE html>
        <meta charset="utf-8">
        <style>
        body { font: 12px Arial;}
        path {
            stroke: #333;
            stroke-width: 2;
            fill: none;
        }
        .axis path,
        .axis line {
            fill: none;
            stroke: grey;
            stroke-width: 1;
            shape-rendering: crispEdges;
        }
        </style>
        <body>
        <div id="option">
          <input name="updateButton" id="updateData" type="button" value="Update" />
            <input name="revertButton" type="button" value="Revert" onclick="revertData()" />
        </div>
    
        <script src="https://d3js.org/d3.v4.min.js"></script>
        <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    
        <script>
    
        var margin = {top: 30, right: 20, bottom: 30, left: 50},
            width = 800 - margin.left - margin.right,
            height = 470 - margin.top - margin.bottom;
    
        var x = d3.scaleLinear().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);
    
        var xAxis = d3.axisBottom().scale(x)
            .ticks(7)
            .tickFormat(d3.format("d"))
    
        var yAxis = d3.axisLeft().scale(y)
            .ticks(5);
    
        var valueline = d3.line()
            .x(function(d) { return x(d.Year); })
            .y(function(d) { return y(d.Count); });
    
        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.csv("datab.csv", function(error, data2) {
          d3.csv("dataa.csv", function(error, data) {
            data.forEach(function(d) {
                d.Year = +d.Year;
                d.Count = +d.Count;
            });
    
            x.domain(d3.extent(data, function(d) { return d.Year; }));
            y.domain([0, d3.max(data, function(d) { return d.Count; })]);
    
            dataNest1 = d3.nest()
                    .key(function(d) {return d.Type;})
                    .entries(data);
    
            var result1 = dataNest1.filter(function(val,idx, arr){
                  return $("." + val.key)
                })
    
          var calls = d3.select("svg").selectAll(".line")
            .data(result1, function(d){return d.key})
    
            var color1 = d3.scaleOrdinal().range(["#333",  "none", "none", "none", "none", "none"]);
    
          calls.enter().append("path")
              .attr("class", "line")
            .attr("stroke","#333")
            .attr("d", function(d){
              return valueline(d.values)
            })
            .attr("transform",
                  "translate(" + margin.left + "," + margin.top + ")");
    
              svg.append("g")
                  .attr("class", "x axis")
                  .attr("transform", "translate(0," + height + ")")
                  .call(xAxis);
    
              svg.append("g")
                  .attr("class", "y axis")
                  .call(yAxis);
    
                d3.select('#updateData').on('click',function(){
                  updateData(data2)
                })
         });
        });
    
        function updateData(data2) {
    
                data2.forEach(function(d) {
                    d.Year = +d.Year;
                    d.Count = +d.Count;
                });
    
              dataNest = d3.nest()
                      .key(function(d) {return d.Descriptor;})
                      .entries(data2);
    
                var result = dataNest.filter(function(val,idx, arr){
                          return $("." + val.key)
                        })
    
                x.domain(d3.extent(data2, function(d) { return d.Year; }));
                y.domain([0, d3.max(data2, function(d) { return d.Count; })]);
    
            var svg = d3.select("body").transition();
            svg.selectAll('.circle').duration(0).remove()
    
            d3.select("svg").selectAll(".line")
            .data(result, function(d){return d.key})
    
            d3.select("svg").selectAll("path.line")
                .transition()
                .duration(700)
              .style("stroke", "#333")
                    .attr("d", function(d){
                        return valueline(d.values)
                    });
    
                // svg.select(".line")   // change the line
                //     .duration(750)
                //     .attr("d", valueline(rats));
    
                svg.select(".x.axis")
                    .transition()
                    .duration(750)
                    .call(xAxis);
                svg.select(".y.axis")
                    .duration(750)
                    .call(yAxis);
    
        }
    
        function revertData() {
    
            // Get the data again
            d3.csv("totalsbyyear.csv", function(error, data) {
                data.forEach(function(d) {
                    d.Year = +d.Year;
                    d.Count = +d.Count;
                });
    
                // Scale the range of the data again
                x.domain(d3.extent(data, function(d) { return d.Year; }));
                y.domain([0, d3.max(data, function(d) { return d.Count; })]);
    
            // Select the section we want to apply our changes to
            var svg = d3.select("body").transition();
    
            // Make the changes
                svg.select(".line")   // change the line
                    .duration(750)
                    .attr("d", valueline(data));
                svg.select(".x.axis") // change the x axis
                    .duration(750)
                    .call(xAxis);
                svg.select(".y.axis") // change the y axis
                    .duration(750)
                    .call(yAxis);
    
            });
        }
    
        </script>
        </body>
    
    2 回复  |  直到 8 年前
        1
  •  0
  •   Ian H    8 年前

    这里有一些问题。第一个问题是,您的数据集非常不同,我在代码中没有看到任何地方可以补偿同一年有多个不同的结果。这是您需要通过修改csv文件或在updatedata函数中只提取一个水果来解决的问题。

    我已经对您的punker做了一些更改,允许updateFunction工作,但不修复输入数据,这并不重要。

    https://plnkr.co/edit/DSg09NWPrBADLLbcL5cx?p=preview

    需要解决的主要问题是

    d3.select("svg").selectAll("path.line")
      .data(result, function(d){return d.key})
      .transition()
      .duration(700)
      .style("stroke", "#337")
         .attr("d", function(d){
         return valueline(result)
       });
    

    打开d3.csv datab.csv 调用updatedata函数,而不是将其包装在主表创建函数周围。

        2
  •  0
  •   sprucegoose    8 年前

    我问的问题可能不清楚。我知道我需要做什么才能使它按预期工作。代码在这里:

    https://plnkr.co/edit/YrABkbc8l9oeT1ywMspy?p=preview

        <!DOCTYPE html>
        <meta charset="utf-8">
        <style>
        body { font: 12px Arial;}
        path {
            stroke: #333;
            stroke-width: 2;
            fill: none;
        }
        .axis path,
        .axis line {
            fill: none;
            stroke: grey;
            stroke-width: 1;
            shape-rendering: crispEdges;
        }
        </style>
        <body>
    
        <div id="option">
          <input name="updateButton" id="updateData" type="button" value="Update" />
            <input name="revertButton" type="button" value="Revert" onclick="revertData()" />
        </div>
    
        <script src="https://d3js.org/d3.v4.min.js"></script>
        <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    
        <script>
    
        var margin = {top: 30, right: 200, bottom: 30, left: 50},
            width = 850 - margin.left - margin.right,
            height = 470 - margin.top - margin.bottom;
    
        var x = d3.scaleLinear().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);
    
        var xAxis = d3.axisBottom().scale(x)
            .ticks(7)
            .tickFormat(d3.format("d"))
    
        var yAxis = d3.axisLeft().scale(y)
            .ticks(5);
    
        var valueline = d3.line()
            .x(function(d) { return x(d.Year); })
            .y(function(d) { return y(d.Count); });
    
        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.csv("datab.csv", function(error, data2) {
          d3.csv("dataa.csv", function(error, data) {
            data.forEach(function(d) {
                d.Year = +d.Year;
                d.Count = +d.Count;
            });
    
            x.domain(d3.extent(data, function(d) { return d.Year; }));
            y.domain([0, d3.max(data, function(d) { return d.Count; })]);
    
            svg.append("path")
                .attr("class", "line")
                .attr("d", valueline(data));
    
            svg.append("text")
                .attr("transform", function(d) { return "translate(" + x(2017) + "," + y(35074) + ")"; })
                .attr("x", 3)
                .attr("dy", "0.35em")
                .attr('class','toplinetext')
                .style("font", "10px sans-serif")
                .text(function(d) { return "All"; });
    
            circles = svg.selectAll("circle")
                  .data(data)
                  .enter()
                  .append("circle")
                  .attr('class','circle')
                  .attr('cx',function(d){ return x(d.Year)})
                  .attr('cy',function(d){ return y(d.Count)})
                  .attr('r',3)
    
              svg.append("g")
                  .attr("class", "x axis")
                  .attr("transform", "translate(0," + height + ")")
                  .call(xAxis);
    
              svg.append("g")
                  .attr("class", "y axis")
                  .call(yAxis);
    
              svg.exit().remove();
    
                d3.select('#updateData').on('click',function(){
                  updateData(data2)
                })
         });
        });
    
        function updateData(data2) {
    
              data2.forEach(function(d) {
                    d.Year = +d.Year;
                    d.Count = +d.Count;
                });
    
              var notapples = data2.filter(function(d){return d.Descriptor == "Peach" || d.Descriptor == "Pear" || d.Descriptor == "Plum" || d.Descriptor == "Banana"})
    
              dataNest = d3.nest()
                      .key(function(d) {return d.Descriptor;})
                      .entries(notapples);
    
                var result = dataNest.filter(function(val,idx, arr){
                          return $("." + val.key)
                        })
    
             $('.toplinetext').text('Apples');
    
    
                x.domain(d3.extent(data2, function(d) { return d.Year; }));
                y.domain([0, d3.max(data2, function(d) { return d.Count; })]);
    
            var svg = d3.select("body").transition();
            svg.selectAll('.circle').duration(0).remove()
    
            var typeOfCall = d3.select("svg").selectAll(".dline")
              .data(result, function(d){return d.key})
              .enter().append("g")
              .attr("class", function(d){return "type " + d.key})
              .attr("transform",
                    "translate(" + margin.left + "," + margin.top + ")");
    
              var color2 = d3.scaleOrdinal().range(["#ff0000",  "#333", "#333", "#333", "#333", "#333"]);
    
            typeOfCall.append("path")
              .attr("height", 0)
                .transition()
                .duration(700)
                .attr("class", "line")
              .style("stroke", function(d,i) { return color2(d.key); })
                    .attr("d", function(d){
                        return valueline(d.values)
                    });
    
              typeOfCall.append("text")
                 .datum(function(d) { return {id: d.Descriptor, value: d.values[d.values.length - 1]}; })
                  .attr("transform", function(d) { return "translate(" + x(d.value.Year) + "," + y(d.value.Count) + ")"; })
                  .attr("x", 3)
                  .attr("dy", "0.35em")
                  .style("font", "10px sans-serif")
                  .text(function(d) { return d.value.Descriptor; });
    
                typeOfCall.exit().remove();
    
                apples = data2.filter(function(d){return d.Descriptor == "Apple"})
    
                svg.select(".line")
                    .duration(750)
                    .attr("d", valueline(apples));
    
                svg.select(".x.axis")
                    .transition()
                    .duration(750)
                    .call(xAxis);
                svg.select(".y.axis")
                    .duration(750)
                    .call(yAxis);
        }
    
        function revertData() {
    
            // Get the data again
            d3.csv("totalsbyyear.csv", function(error, data) {
                data.forEach(function(d) {
                    d.Year = +d.Year;
                    d.Count = +d.Count;
                });
    
              $('.toplinetext').text('All');
              $('.Peach,.Pear,.Banana,.Plum').remove();
                // Scale the range of the data again
                x.domain(d3.extent(data, function(d) { return d.Year; }));
                y.domain([0, d3.max(data, function(d) { return d.Count; })]);
    
            // Select the section we want to apply our changes to
            var svg = d3.select("body").transition();
    
            // Make the changes
                svg.select(".line")   // change the line
                    .duration(750)
                    .attr("d", valueline(data));
                svg.select(".x.axis") // change the x axis
                    .duration(750)
                    .call(xAxis);
                svg.select(".y.axis") // change the y axis
                    .duration(750)
                    .call(yAxis);
    
            });
        }
    
        </script>
        </body>