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毫秒,它将在上一个绘制的顶部绘制一个正确的折线图,而不是向右移动。
答案 0 :(得分:0)
您的主要问题是您在每个刻度(.append(path)
)添加新路径。
您需要做的是为图形中已有的路径设置动画。并为路径指定一个id
或class
,因为在图形中将有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>
)
}