D3折线图。
设法绘制xAxis和yAxis,但线路径为: MNaN,36LNaN,28.000000000000007LNaN,36LNaN,20LNaN,20LNaN,30.666666666666664LNaN,28.000000000000007LNaN,24.000000000000004
数据来自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
}
答案 0 :(得分:1)
对于xScale: d3.scaleTime()...
,x值必须是Date()
对象。传递/获取的数据包含以字符串形式提供的date
属性-需要转换。用于timeDomain
的{{1}}也需要与日期相关。
可以通过更改以下两行来解决问题:
xScale
与lineGenerator中的相同:
const timeDomain = d3.extent(data, d => new Date(d.date));