D3.js v6 路径未在折线图中对齐

D3.js v6 path not aligning inside line chart

我有两个折线图。一个我编码 here and the other here 我复制粘贴来比较为什么我的没有正确对齐。两个图表都没有使用转换来平移线条。我在正确对齐的图表中缺少什么。谢谢。

图表工作不正常:

var svg = d3.select("body") //create Svg element
   .append("svg")
   .attr("height",500)
   .attr("width", 700)
   .style("border", "solid 1px red")
   .attr("transform","translate(100,0)"); // To align svg at the center in the output tab.
var data = [
    { day:0, stock_value: 0 },
    { day:5, stock_value: 100 },
    { day:10, stock_value: 200 },
    { day:15, stock_value: 400 },
    { day:20, stock_value:150 }];

var xScale = d3.scaleLinear()
              .domain(d3.extent(data, d => d.day))
              .range([0,500]);

var yScale = d3.scaleLinear()
              .domain(d3.extent(data, d => d.stock_value))
              .range([400,0]);

svg.append('g')
  .call(d3.axisBottom(xScale))
  .attr('transform','translate(70,450)');

svg.append('g')
  .call(d3.axisLeft(yScale))
  .attr('transform','translate(70,50)');

svg.append('text')
  .text('days')
  .attr('transform','translate(270,490)');

svg.append('text')
  .text('value')
  .attr('transform','translate(30,300) rotate(-90)')

var generator = d3.line()
                  .x(function(d) { return xScale(d.day); })
                  .y(function(d) { return yScale(d.stock_value); });

svg.append('path')
  .datum(data)
  .attr('d', generator)
  .attr('fill','none')
  .attr('stroke','blue')
  .attr('stroke-width','2px');

你走对了!

看起来我们需要对我们的路径应用与我们在这里应用到我们的轴相同的变换。

您可以在屏幕截图中看到,x 轴和 y 轴都在 svg 中使用变换进行了偏移——这样可以在 space 内部看到 y 轴为 svg 创建,在红线内。如果我们应用该变换,那么我们将看不到我们的 y 轴。

所以为了让我们的路径与我们的轴对齐,我们需要对我们的路径应用相同的变换。 :)

Updated pen.

顺便说一句,在D3中,你会经常遇到的一件事就是所谓的“margin convention”。当然,这完全取决于您,不使用它肯定会有争论,但如果它有帮助,the creator of D3 wrote up a demo of the margin convention that I think illustrates it pretty well which is linked here.

希望对您有所帮助! ✌️

var margin = {top: 20, right: 20, bottom: 60, left: 80},
     width = 700 - margin.left - margin.right,
     height = 700 - margin.top - margin.bottom;

var svg = d3.select("body") //create Svg element
   .append("svg")
   .attr("height",500)
   .attr("width", 700)
   .style("border", "solid 1px red")
   .attr("transform","translate(100,0)"); // To align svg at the center in the output tab.

var data = [
    { day:0, stock_value: 0 },
    { day:5, stock_value: 100 },
    { day:10, stock_value: 200 },
    { day:15, stock_value: 400 },
    { day:20, stock_value:150 }];

var xScale = d3.scaleLinear()
              .domain(d3.extent(data, d => d.day))
              .range([0,500]);

var yScale = d3.scaleLinear()
              .domain(d3.extent(data, d => d.stock_value))
              .range([400,0]);

svg.append('g')
  .call(d3.axisBottom(xScale))
  .attr('transform',`translate(, ${450})`);

svg.append('g')
  .call(d3.axisLeft(yScale))
  .attr('transform',`translate(,)`);

svg.append('text')
  .text('days')
  .attr('transform','translate(270,490)');

svg.append('text')
  .text('value')
  .attr('transform','translate(30,300) rotate(-90)')

var generator = d3.line()
                  .x(function(d) { return xScale(d.day); })
                  .y(function(d) { return yScale(d.stock_value); });

svg.append('path')
  .datum(data)
  .attr('d', generator)
  .attr('fill','none')
  .attr('stroke','blue')
  .attr('stroke-width','2px')

// both of your axes are having a transform applied to account for your svg's margins, so apply the same values to your path here:

  .attr('transform',`translate(,)`);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>