折线图未与x轴对齐

时间:2018-05-22 08:19:53

标签: javascript d3.js svg

我想使用这些数据创建一个折线图:

var mydata = [
  {
    "year": "2019",
    "myvalue": "50"
  },
  {
    "year": "2018",
    "myvalue": "50"
  },
  {
    "year": "2017",
    "myvalue": "NaN"
  },
  {
    "year": "2016",
    "myvalue": "NaN"
  },
  {
    "year": "2015",
    "myvalue": "10"
  },
  {
    "year": "2014",
    "myvalue": "25.6"
  },
  {
    "year": "2013",
    "myvalue": "4.2"
  },
  {
    "year": "2012",
    "myvalue": "60"
  },
  {
    "year": "2011",
    "myvalue": "826"
  },
  {
    "year": "2010",
    "myvalue": "32"
  },
  {
    "year": "2009",
    "myvalue": "50"
  },
  {
    "year": "2008",
    "myvalue": "70"
  }
];

整个代码HERE

我构建的图表有效,但它有一些问题:缺少一些x轴刻度线,线图(和圆圈)没有被x轴(如此图所示):

enter image description here

1 个答案:

答案 0 :(得分:3)

您的代码需要大量的重构。但是,仅解决问题中陈述的问题,您有3个问题:

  1. 您正在将边距应用于<g>元素,然后再将其应用于轴组。放下translate

    thisSvg.append('g')
        .attr('class', 'y axis')
        .attr('transform', 'translate(' + margin.left + ', 0)')
    
  2. 您没有解析日期。在调用您的比例时,year值为字符串,而不是日期对象。解析日期:

    mydata.forEach(function(d) {
        d.year = parseTime(d.year)
    })
    
  3. 如果不首先设置比例域,则无法调用轴。

  4. 总之,这是您的代码,包含这些更改:

    var mydata = [{
        "year": "2019",
        "myvalue": "50"
      },
      {
        "year": "2018",
        "myvalue": "50"
      },
      {
        "year": "2017",
        "myvalue": "NaN"
      },
      {
        "year": "2016",
        "myvalue": "NaN"
      },
      {
        "year": "2015",
        "myvalue": "10"
      },
      {
        "year": "2014",
        "myvalue": "25.6"
      },
      {
        "year": "2013",
        "myvalue": "4.2"
      },
      {
        "year": "2012",
        "myvalue": "60"
      },
      {
        "year": "2011",
        "myvalue": "826"
      },
      {
        "year": "2010",
        "myvalue": "32"
      },
      {
        "year": "2009",
        "myvalue": "50"
      },
      {
        "year": "2008",
        "myvalue": "70"
      }
    ];
    
    var margin = {
      top: 10,
      right: 10,
      bottom: 50,
      left: 40
    };
    
    var svg = d3.select('#linechart')
      .append('svg')
      .attr('width', 600)
      .attr('height', 200);
    
    var parseTime = d3.timeParse("%Y");
    
    mydata.forEach(function(d) {
      d.year = parseTime(d.year)
    })
    
    var values = createAxisLine(svg);
    var x = values[0];
    var y = values[1];
    var width = values[2];
    var height = values[3];
    var svg2 = values[4];
    
    createChartLine(svg, x, y, width, height, svg2);
    
    function createAxisLine(thisSvg) {
      var width = thisSvg.attr('width') - margin.left - margin.right;
      var height = thisSvg.attr('height') - margin.top - margin.bottom;
    
      thisSvg = thisSvg.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
    
      var x = d3.scaleTime()
        .rangeRound([0, width]);
    
      var y = d3.scaleLinear()
        .rangeRound([height, 0]);
    
      x.domain(d3.extent(mydata, function(d) {
        return d.year;
      }));
      y.domain([0, 1000]);
    
      var xAxis = d3.axisBottom(x); //.tickSize(0, 0);
      var yAxis = d3.axisLeft(y);
    
      thisSvg.append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0, ' + height + ')')
        .call(xAxis)
        .selectAll('text')
        .style('text-anchor', 'end')
        .attr('dx', '-.8em')
        .attr('dy', '.15em')
        .attr('transform', 'rotate(-65)');
    
      thisSvg.append('g')
        .attr('class', 'y axis')
        .call(yAxis)
        .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '.71em')
        .style('text-anchor', 'end');
    
      return [x, y, width, height, thisSvg];
    }
    
    function createChartLine(thisSvg, x, y, width, height, thisSvg) {
      var lines = thisSvg
        .attr('transform', function(d) {
          return 'translate(' + margin.left + ', ' + margin.top + ')';
        });
    
      var line = d3.line()
        .x(function(d) {
          return x(d.year);
        })
        .y(function(d) {
          return y(d.myvalue);
        })
        .defined(function(d) { // for missing (0) data
          if (isNaN(d.myvalue)) {
            d.myvalue = 0;
          }
          return d.myvalue !== 0;
        });
    
      lines.append('path')
        .data([mydata])
        .attr('class', 'mylines')
        .attr('fill', 'none')
        .attr('stroke', 'steelblue')
        .attr('stroke-width', 1.5)
        .attr('d', line);
    
      thisSvg.append('g').attr('class', 'circles')
        .selectAll('.dot')
        .data(mydata)
        .enter()
        .append('circle')
        .attr('class', 'dot')
        .attr('cx', function(d) {
          return x(d.year);
        })
        .attr('cy', function(d) {
          return y(d.myvalue);
        })
        .attr('r', 3);
    }
    <script src='https://d3js.org/d3.v5.js' charset='utf-8'></script>
    <div style='height:50px;'></div>
    <div id='linechart'></div>