[英]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.