问题

我遇到了出现嵌套行图的问题.数据在控制台中,但也许我错过了关键的东西.我正在关注这个作为参考: https://amber.rbind.io/2017/05/02/nesting/

可能我错误地调用嵌套数据,或者我需要将其附加到svg?任何帮助非常感谢!

图表需要在x轴上有年份,y轴上的事件总和,每条线都应该是一个区域。

 <!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Nested Chart</title>
        <script src="../lib/d3.v5.min.js"></script>
        <style type="text/css">
            .pagebreak { page-break-before: always; }
            .axis path,
            .axis line {
                fill: none;
                stroke: black;
                shape-rendering: crispEdges;
            }
            .axis text {
                font-family: sans-serif;
                font-size: 11px;
            }
            .point {
                fill:none;
                size: 2px
            }
        </style>
    </head>

    <div style= "width:800px; margin:0 auto;" class ='body'></div>
    <div class="pagebreak"> </div>
    <body>

        <script type="text/javascript">

            var parseTime = d3.timeParse("%Y");


            var margin = {top: 20, right: 20, bottom: 30, left: 50},
                w = 960 - margin.left - margin.right,
                h = 500 - margin.top - margin.bottom;

            var padding =20;

 /////////////////get the data//////////////////               
            d3.csv("state-year-earthquakes.csv").then(function(dataset) {

            dataset.forEach(function(d) {
              d.date = parseTime(d.year);
              d.region  = d['region'];
              d.state = d['state'];
              d.count = d['count'];
              //console.log(d)
            });


/////////////////scales the data//////////////////
            var xScale = d3.scaleTime()
                .domain([d3.min(dataset,function (d) { return d.date }),d3.max(dataset,function (d) { return d.date }) ]).range([padding, w - padding * 2])

            var yScale = d3.scaleLinear()
                .domain([0, d3.max(dataset,function (d) { return d.count }) ]).range([h- padding, padding])    

            var xAxis = d3.axisBottom().scale(xScale);

            var yAxis = d3.axisLeft().scale(yScale);


/////////////////charts start here//////////////////

            var svg = d3.select("body").append("svg")
                .attr("width", w + margin.left + margin.right)
                .attr("height", h + margin.top + margin.bottom)
                .append("g")
                .attr("transform",
                      "translate(" + margin.left + "," + margin.top + ")");


//Define the line
            var valueLine = d3.line()
                .x(function(d) { return xScale(d.date); })
                .y(function(d) { return yScale(+d.count); })


            var nest = d3.nest()
              .key(function(d){
                return d.region;
              })
                .key(function(d){
                return d.date;
              })
              .rollup(function(leaves){
                    return d3.sum(leaves, function(d) {return (d.count)});
                })
              .entries(dataset)


            var color = d3.scaleOrdinal(d3.schemeCategory10); // set the colour scale

             console.log(nest)


            var regYear = svg.selectAll(".regYear")
                .data(nest)
                .enter()
                .append("g")

            // console.log(regYear)

            var paths = regYear.selectAll(".line")
                .data(function(d){ 
                  return d.values 
                })
                .enter()
                .append("path");

            console.log(paths)
            // Draw the line
            paths
              .attr("d", function(d){
                return d.values
              })
              .attr("class", "line")


            svg.append("g").attr("class", "axis").attr("transform", "translate(0," + (h - padding) + ")").call(xAxis);       
            //draw Y axis
            svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding + ",0)").call(yAxis);
            // add label
            svg.append("text").attr("x", (w/2)).attr("y", h+30).attr("text-anchor", "middle").text("Year");
            svg.append("text").attr("x", padding).attr("y", padding-20).attr("text-anchor", "middle").text("# of Events");            
            //add title
            svg.append("text").attr("x", (w/2)).attr("y", padding).attr("text-anchor", "middle").text("Events per Year by Category");   
            // add legend   
            var legend = svg.append("g")
            .attr("class", "legend")
            .attr("x", w - 65)
            .attr("y", 25)
            .attr("height", 100)
            .attr("width", 100);




////////////////////////////////////END///////////////////////////

            } );
        </script>

    </body>
</html>


 

data.csv

 state,region,year,count
Alabama,South,2010,1
Alabama,South,2011,1
Alabama,South,2012,0
Alabama,South,2013,0
Alabama,South,2014,2
Alabama,South,2015,6
Alaska,West,2010,2245
Alaska,West,2011,1409
Alaska,West,2012,1166
Alaska,West,2013,1329
Alaska,West,2014,1296
Alaska,West,2015,1575
Connecticut,Northeast,2010,0
Connecticut,Northeast,2011,0
Connecticut,Northeast,2012,0
Connecticut,Northeast,2013,0
Connecticut,Northeast,2014,0
Connecticut,Northeast,2015,1
Missouri,Midwest,2010,2
Missouri,Midwest,2011,3
Missouri,Midwest,2012,2
Missouri,Midwest,2013,0
Missouri,Midwest,2014,1
Missouri,Midwest,2015,5
 
 
 

  最佳答案

您有几个问题.首先,您不使用线生成器.它应该是:

 .attr("d", function(d) {
    return valueLine(d)
})
 

其次,您正在解析日期字符串,但再次将其转换为字符串.所以,更改行生成器(或者不将其用作键,返回字符串):

 var valueLine = d3.line()
    .x(function(d) {
        return xScale(new Date(d.key));
    })
    .y(function(d) {
        return yScale(d.value);
    })
 

最后,行生成器的每个数据必须是数组本身.所以:

 var paths = regYear.selectAll(".line")
    .data(function(d) {
        return [d.values]
    })
 

这是您的代码与这些更改(以及路径的一些CSS):

 path {
  fill: none;
  stroke: black;
} 
 <!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <title>Nested Chart</title>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <style type="text/css">
      .pagebreak {
        page-break-before: always;
      }

      .axis path,
      .axis line {
        fill: none;
        stroke: black;
        shape-rendering: crispEdges;
      }

      .axis text {
        font-family: sans-serif;
        font-size: 11px;
      }

      .point {
        fill: none;
        size: 2px
      }

    </style>
  </head>

  <div style="width:800px; margin:0 auto;" class='body'></div>
  <div class="pagebreak"> </div>

  <body>

    <script type="text/javascript">
      var parseTime = d3.timeParse("%Y");


      var margin = {
          top: 20,
          right: 20,
          bottom: 30,
          left: 50
        },
        w = 960 - margin.left - margin.right,
        h = 500 - margin.top - margin.bottom;

      var padding = 20;

      /////////////////get the data//////////////////               
      const csv = `state,region,year,count
Alabama,South,2010,1
Alabama,South,2011,1
Alabama,South,2012,0
Alabama,South,2013,0
Alabama,South,2014,2
Alabama,South,2015,6
Alaska,West,2010,2245
Alaska,West,2011,1409
Alaska,West,2012,1166
Alaska,West,2013,1329
Alaska,West,2014,1296
Alaska,West,2015,1575
Connecticut,Northeast,2010,0
Connecticut,Northeast,2011,0
Connecticut,Northeast,2012,0
Connecticut,Northeast,2013,0
Connecticut,Northeast,2014,0
Connecticut,Northeast,2015,1
Missouri,Midwest,2010,2
Missouri,Midwest,2011,3
Missouri,Midwest,2012,2
Missouri,Midwest,2013,0
Missouri,Midwest,2014,1
Missouri,Midwest,2015,5`;

      const dataset = d3.csvParse(csv);

      dataset.forEach(function(d) {
        d.date = parseTime(d.year);
        d.region = d['region'];
        d.state = d['state'];
        d.count = d['count'];
        //console.log(d)
      });


      /////////////////scales the data//////////////////
      var xScale = d3.scaleTime()
        .domain([d3.min(dataset, function(d) {
          return d.date
        }), d3.max(dataset, function(d) {
          return d.date
        })]).range([padding, w - padding * 2])

      var yScale = d3.scaleLinear()
        .domain([0, d3.max(dataset, function(d) {
          return d.count
        })]).range([h - padding, padding])

      var xAxis = d3.axisBottom().scale(xScale);

      var yAxis = d3.axisLeft().scale(yScale);


      /////////////////charts start here//////////////////

      var svg = d3.select("body").append("svg")
        .attr("width", w + margin.left + margin.right)
        .attr("height", h + margin.top + margin.bottom)
        .append("g")
        .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");


      //Define the line
      var valueLine = d3.line()
        .x(function(d) {
          return xScale(new Date(d.key));
        })
        .y(function(d) {
          return yScale(d.value);
        })


      var nest = d3.nest()
        .key(function(d) {
          return d.region;
        })
        .key(function(d) {
          return d.date;
        })
        .rollup(function(leaves) {
          return d3.sum(leaves, function(d) {
            return (d.count)
          });
        })
        .entries(dataset)


      var color = d3.scaleOrdinal(d3.schemeCategory10); // set the colour scale


      var regYear = svg.selectAll(".regYear")
        .data(nest)
        .enter()
        .append("g")

      // console.log(regYear)

      var paths = regYear.selectAll(".line")
        .data(function(d) {
          return [d.values]
        })
        .enter()
        .append("path");

      // Draw the line
      paths
        .attr("d", function(d) {
          return valueLine(d)
        })
        .attr("class", "line")


      svg.append("g").attr("class", "axis").attr("transform", "translate(0," + (h - padding) + ")").call(xAxis);
      //draw Y axis
      svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding + ",0)").call(yAxis);
      // add label
      svg.append("text").attr("x", (w / 2)).attr("y", h + 30).attr("text-anchor", "middle").text("Year");
      svg.append("text").attr("x", padding).attr("y", padding - 20).attr("text-anchor", "middle").text("# of Events");
      //add title
      svg.append("text").attr("x", (w / 2)).attr("y", padding).attr("text-anchor", "middle").text("Events per Year by Category");
      // add legend   
      var legend = svg.append("g")
        .attr("class", "legend")
        .attr("x", w - 65)
        .attr("y", 25)
        .attr("height", 100)
        .attr("width", 100);




      ////////////////////////////////////END///////////////////////////

    </script>

  </body>

</html> 

  相同标签的其他问题

javascriptd3.jsnestedlinechart