d3 v5在缩放轴时使用嵌套值

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

我有以下代码根据区域和日期嵌套我的数据。我遇到的问题是,我不知道如何定义yScale来动态绘制轴,以便返回嵌套数据的最大和(嵌套数据的最大val高于数据集bc中的最大val。它是汇总的)。因此,我的yAxis被截断了,并且图表未显示所有数据。

在代码中,如果我将域硬编码为.domain([0,3500]),则该轴正确,但否则不正确。我不想对域进行硬编码。如何引用嵌套值?

编辑以显示注释中提供的代码,当脚本在整个数据集上运行时,这很有帮助,但不能完全解决。请参阅底部的图片。

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

      // var yScale = d3.scaleLinear()
      //   .domain([0, 3500])
      //   .range([h - padding, padding]) //not supposed to hard code the scale but it is not working 
<!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
      }

      .dot {
        fill: #ffab00;
        stroke: #fff;
        }



    </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
        California,West,2010,546
        California,West,2012,243
        California,West,2013,240
        Wyoming,West,2015,198
        California,West,2011,195
        California,West,2014,191`;

      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) {
          console.log(d.count)
          return d.count ///ERROR HERE
        })]).range([h - padding, padding])

      // var yScale = d3.scaleLinear()
      //   .domain([0, 3500])
      //   .range([h - padding, padding]) //not supposed to hard code the scale but it is not working otherwise...commented out above

      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 + ")");

      var svg1 = 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)

        console.log(nest)


      // Set the color scheme
        var colors = d3.scaleOrdinal()
          .domain(["South", "West", "Northeast","Midwest"])
          .range(["#EF5285", "#88F284" , "#5965A3","#900C3F"]);


      var regYear = svg.selectAll(".regYear")
        .data(nest)
        .enter()
        .append("g")
        .attr("stroke", function(d){ return colors(d.key)}); // Adding color!

      // 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")
        .style("fill", "none");



    svg.selectAll(".dot")
        .data(dataset)
        .enter().append("circle") // Uses the enter().append() method
        .attr("class", "dot") // Assign a class for styling
        .attr("cx", function(d, i) { return xScale(i) })
        .attr("cy", function(d) { return yScale(d.count) })//this is not working
        .attr("r", 5);


      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>


enter image description here

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

我注意到您的d.count的数据类型为string,因此最大值将不正确。

© www.soinside.com 2019 - 2024. All rights reserved.