javascript 无法在D3js的折线图中显示线条

kmbjn2e3  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(148)

我有三个对象数组。
我想创建一个3线图表,三个数组的日期相同。peakUsage和avgUsage的Y值相同,因此它们是水平直线
此代码显示了Y轴和X轴,但无法绘制实际的直线。

data: { x: Date; y: number }[],
peakUsage: { x: Date; y: number }[],
avgUsage: { x: Date; y: number }[]

const axisThickness = 60;
  const width = (params.width || 500) - axisThickness;
  const height = (params.height || 500) - axisThickness;

  const { document } = new JSDOM('').window;

  // Create D3 container with SVG element
  const div = d3.select(document.body).append('div');
  const svg = div
    .attr('class', 'container')
    .append('svg')
    .attr('xmlns', 'http://www.w3.org/2000/svg')
    .attr('width', width + axisThickness)
    .attr('height', height + axisThickness);

  const yScale = d3.scaleLinear().range([height, 0]);

  yScale.domain([0, Math.max(...data.map((d) => d.y))]);

  const xScale = d3
    .scaleTime()
    .range([0, width])
    .domain(
      d3.extent(data, function (d) {
        return new Date(d.x);
      }) as Date[]
    );

  const g = svg.append('g').attr('transform', `translate(${axisThickness},${axisThickness / 2})`);

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

  g.append('g')
    .call(
      d3
        .axisLeft(yScale)
        .tickFormat(function (d) {
          return `${d}`; // Label text
        })
        .ticks(8)
    )
    .append('text')
    .attr('transform', 'rotate(-90)') 
    .attr('y', 6)
    .attr('dy', '-5.1em')
    .attr('text-anchor', 'end')
    .attr('fill', 'black')
    .text('Est. kWh');

  g.selectAll('.line')
    .enter()
    .append('path')
    .data(data)
    .attr('fill', 'none')
    .attr('stroke', 'green')
    .attr('stroke-width', 1.5)
    .attr('d', function (d) {
      return d3
        .line()
        .x(function (d: any) {
          return xScale(d.x);
        })
        .y(function (d: any) {
          return yScale(d.y);
        }) as any;
    });

  g.selectAll('.line')
    .enter()
    .append('path')
    .data(peakUsage)
    .attr('fill', 'none')
    .attr('stroke', 'Orange')
    .attr('stroke-width', 1.5)
    .attr(
      'd',
      d3
        .line()
        .x(function (d: any) {
          return xScale(d.x);
        })
        .y(function (d: any) {
          return yScale(d.y);
        }) as any
    );
  g.selectAll('.line')
    .enter()
    .append('path')
    .data(avgUsage)
    .attr('fill', 'none')
    .attr('stroke', 'blue')
    .attr('stroke-width', 1.5)
    .attr(
      'd',
      d3
        .line()
        .x(function (d: any) {
          return xScale(d.x);
        })
        .y(function (d: any) {
          return yScale(d.y);
        }) as any
    );

我做错了什么?

yuvru6vn

yuvru6vn1#

此位的顺序错误:

g.selectAll('.line')
    .enter()
    .append('path')
    .data(data)

它应该是:

g.selectAll('.line')
    .data(data)
    .enter()
    .append('path')

但是这并不能解决你的问题。因为你为每一行单独使用了3个不同的数组(一个更好的方法是只使用一个数组和3个内部数组,但这是另一个问题...),你可以简单地声明行生成器...

const lineGenerator = d3.line()
    .x(function (d: any) {
      return xScale(d.x);
    })
    .y(function (d: any) {
      return yScale(d.y);
    })

...然后,对每个路径执行以下操作:

g.append('path')
    .attr('fill', 'foo')
    .attr('stroke', 'bar')
    .attr('stroke-width', 'baz')
    .attr('d', lineGenerator(pathDataHere))
    //the data for each line -----^

相关问题