簡體   English   中英

用 d3 + react 繪制路徑(折線圖)

[英]Draw a path (line chart) with d3 + react

帶有 Redux 實現的 React 組件中的 D3 折線圖。

設法繪制 xAxis 和 yAxis 但線路徑是: MNaN,36LNaN,28.0000000000000007LNaN,36LNaN,20LNaN,20LNaN,30.6666666666666664LNaN,28.000000000000000004LNaN

數據來自 getDerivedStateFromProps 生命周期中的 nextProps 但沒有傳遞到lineGenerator

這是我的組件:

import * as d3 from 'd3';
import React, { Component } from 'react';

const width = 400;
const height = 200;
const margin = { top: 20, right: 5, bottom: 20, left: 35 };
const green = '#00ded0';

class CPULineChart extends Component {
  state = {
    cpu: null, // svg path command for all cpu points
    // d3 helpers
    xScale: d3.scaleTime().range([margin.left, width - margin.right]),
    yScale: d3.scaleLinear().range([height - margin.bottom, margin.top]),
    lineGenerator: d3.line()
  };

  xAxis = d3
    .axisBottom()
    .scale(this.state.xScale)
    .tickFormat(d3.timeFormat('%b'));
  yAxis = d3.axisBottom().scale(this.state.yScale);

  static getDerivedStateFromProps(nextProps, prevState) {
    if (!nextProps.data) return null; // data hasn't been loaded yet so do nothing
    const { data } = nextProps;
    const { yScale, xScale, lineGenerator } = prevState;

    // data has changed, so recalculate scale domains
    const timeDomain = d3.extent(data, d => d.date);
    const cpuMax = d3.max(data, d => d.high);
    xScale.domain(timeDomain);
    yScale.domain([0, cpuMax]);

    // Calculate line for CPU
    lineGenerator.x(d => xScale(d.date));
    lineGenerator.y(d => yScale(d.high));

    const cpu = lineGenerator(data);

    console.log(cpu);
    return cpu;
  }

  componentDidUpdate() {
    d3.select(this.refs.xAxis).call(this.xAxis);
    d3.select(this.refs.yAxis).call(this.yAxis);
  }

  render() {
    return (
      <svg width={width} height={height}>
        <path d={this.state.cpu} fill="none" stroke={green} strokeWidth="2" />
        <g ref="xAxis" transform={`translate(0, ${height - margin.bottom})`} />
        <g ref="yAxis" transform={`translate(${margin.left}, 0)`} />
      </svg>
    );
  }
}

export default CPULineChart;

從父組件傳遞數據:

<CPULineChart data={data} />

和數據

 {
    "date": "2015-10-1 1:00 PM GMT+1:00",
    "high": 0.135,
    "low": 20
  },
  {
    "date": "2015-10-1 2:00 PM GMT+1:00",
    "high": 0.09,
    "low": 20
  },
  {
    "date": "2015-10-1 3:00 PM GMT+1:00",
    "high": 0.1,
    "low": 20
  }

使用xScale: d3.scaleTime()... x 值需要是Date()對象。 傳遞/獲取的數據包含作為字符串提供的date屬性 - 需要轉換。 用於xScale timeDomain需要與日期相關。

可以通過更改以下兩行來解決問題:

const timeDomain = d3.extent(data, d => new Date(d.date));

和 lineGenerator 相同:

lineGenerator.x(d => xScale(new Date(d.date)));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM