如何在 React 和 D3(实时折线图)中正确转换


componentDidMount(){
this.createBarChart()
window.setInterval(()=>{
this.props.data.push(Math.random()*500)
this.createBarChart()
this.props.data.shift()
},500)
}
createBarChart(){
const delay = transition().duration(500)
const node = this.svgNode.current
const dataMax = max(this.props.data)
const yScale = scaleLinear()
.domain([0,dataMax])
.range([0,500])
const xScale = scaleBand()
.range([0,500])
.domain(this.props.data)
let valueline = line()
.x((d)=>xScale(d))
.y(d=>500-yScale(d))
.curve(curveCardinal)
select(node)
.append('path')
.datum(this.props.data)
.attr('stroke', 'steelblue')
.attr('fill', 'none')
.attr('d', valueline)
.attr('transform', null)
.transition(delay)
.attr('transform', `translate(${+xScale(-1)})`)
}
render(){
return (
<svg width={500} height={500} ref={this.svgNode}></svg>
)
}

我知道你不应该改变道具,我稍后会解决这个问题并处理本地状态中的所有内容,但我想解决的问题是让折线图像实时时间序列图一样正确过渡。

我现在用这段代码得到的是,每 500 毫秒它会在上一次绘制的顶部绘制正确的折线图,而不是向右移动。

您的主要问题是在每个刻度(.append(path)(处添加一个新路径。

您需要做的是对图形中已有的路径进行动画处理。并为路径提供idclass,因为图形中将有超过 1 个path(轴还包含路径(

tick(setInterval( 上调用不同的函数。

键盘上的;键坏了吗?

componentDidMount(){
this.createBarChart();
}
createBarChart(){
const delay = transition().duration(500);
const node = this.svgNode.current;
const dataMax = max(this.props.data);
const yScale = scaleLinear()
.domain([0,dataMax])
.range([500,0]);
this.props.xScale = scaleBand()
.range([0,500])
.domain(this.props.data);
this.props.valueline = line()
.x(d=>xScale(d))
.y(d=>yScale(d))
.curve(curveCardinal);
select(node)
.append('path')
.attr("class", "line")
.datum(this.props.data)
.attr('stroke', 'steelblue')
.attr('fill', 'none')
.transition()
.duration(500)
.ease(d3.easeLinear) // you don't want cubic interpolation
.on("start", this.updateBarChart.bind(this));
}
updateBarChart() {
this.props.data.push(Math.random()*500);
// this is not the path but the Component
let line = select(this.svgNode.current).select(".line")
.attr('d', this.props.valueline)
.attr('transform', null);
d3.active(line.node())
.attr('transform', `translate(${+this.props.xScale(-1)})`)
.transition()
.on("start", tick);
this.props.data.shift();
}
render(){
return (
<svg width={500} height={500} ref={this.svgNode}></svg>
)
}

最新更新