未显示嵌套折线图

问题描述 投票:1回答:1

我在显示嵌套的折线图时遇到问题。数据在控制台中,但是也许我缺少一些关键的东西。我正在关注此作为参考: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

javascript d3.js nested linechart
1个回答
0
投票

您有几个问题。首先,您没有使用线路生成器。应该是:

.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>
© www.soinside.com 2019 - 2024. All rights reserved.