Javascript 接收新数据时如何更新d3图表

Javascript 接收新数据时如何更新d3图表,javascript,angular,typescript,d3.js,charts,Javascript,Angular,Typescript,D3.js,Charts,如何使用新数据更新d3图表: 我在ngOnchanges上执行三项功能: this.removeSvg(this.data); this.createSvg(); this.drawBars(this.data); 其中createSvg(): 并删除vg(): 和牵引杆(数据:任何[]): 但它不会刷新图表,即使我确信数据正在刷新(因此对于第一个图表,我们继续使用所有其他图表,就好像它是相同的数据一样) 有什么帮助吗?也许移除或退出在这里是错误

如何使用新数据更新d3图表: 我在ngOnchanges上执行三项功能:

        this.removeSvg(this.data);
        this.createSvg();
        this.drawBars(this.data);
其中createSvg():

并删除vg():

和牵引杆(数据:任何[]):

但它不会刷新图表,即使我确信数据正在刷新(因此对于第一个图表,我们继续使用所有其他图表,就好像它是相同的数据一样)
有什么帮助吗?也许移除或退出在这里是错误的

在D3中,可以通过选择操作DOM。在
牵引杆()
功能中,您使用
输入
选项,该选项描述了新数据的情况。 要描述已更改的数据发生了什么变化,请使用
更新
选项;对于离开的数据,使用退出选择。要跟踪更新的数据,您需要在
data()
调用中使用一个键函数来唯一标识每个元素

以获取更深入的概述

牵引杆()功能中:

private drawBars(data: any[]): void {
    // ...
    let t = svg.transition().duration(500);
    
    this.svg.selectAll("bars")
        .data(data, d => d)
        .join(
        enter => enter
            .append("rect")
            .attr("x", d => x(d.xAxis))
            .attr("y", d => y(d.yAxis))
            .attr("width", x.bandwidth())
            .attr("height", (d) => this.height - y(d.yAxis))
            .attr("fill", "rgb(13, 185, 240)"),
        update => update.call(update => update.transition(t)
            .attr("x", d => x(d.xAxis))
            .attr("y", d => y(d.yAxis))
            .attr("height", (d) => this.height - y(d.yAxis))),
        exit => exit.call(exit => exit.transition(t)
            .attr("x", 0)
            .attr("y", 0)
            .attr("height", 0)
            .remove()))
}
这无助于在更新数据时进行转换。

已解决

对于任何面临此问题的人,我建议他采用以下解决方案: 只需保持一切原样,但确保在每次更改时刷新数据,然后使用以下命令清空svg中的所有元素:

his.svg.selectAll("*").remove()

,然后用新数据再次绘制图表。

感谢@Hugo Elhaj Lahsen的回复,但没有成功!它会在新图表条的顶部不断添加以前的图表条
private drawBars(data: any[]): void {
    // Create the X-axis band scale
    const x = d3.scaleBand()
        .range([this.axisMin, 340])
        .domain(data.map(d => d.xAxis))
        .padding(0);

    // Create the Y-axis band scale
    const y = d3.scaleLinear()
        .domain([0, this.axisMax])
        .range([this.height, 0])
        .nice();


    // Create and fill the bars
    this.svg.selectAll("bars")
        .data(data)
        .enter()
        .append("rect")
        .attr("x", d => x(d.xAxis))
        .attr("y", d => y(d.yAxis))
        .attr("width", x.bandwidth())
        .attr("height", (d) => this.height - y(d.yAxis))
        .attr("fill", "rgb(13, 185, 240)");
}
private drawBars(data: any[]): void {
    // ...
    let t = svg.transition().duration(500);
    
    this.svg.selectAll("bars")
        .data(data, d => d)
        .join(
        enter => enter
            .append("rect")
            .attr("x", d => x(d.xAxis))
            .attr("y", d => y(d.yAxis))
            .attr("width", x.bandwidth())
            .attr("height", (d) => this.height - y(d.yAxis))
            .attr("fill", "rgb(13, 185, 240)"),
        update => update.call(update => update.transition(t)
            .attr("x", d => x(d.xAxis))
            .attr("y", d => y(d.yAxis))
            .attr("height", (d) => this.height - y(d.yAxis))),
        exit => exit.call(exit => exit.transition(t)
            .attr("x", 0)
            .attr("y", 0)
            .attr("height", 0)
            .remove()))
}
this.svg.selectAll("bars")
        .data(data, d => d)
        .join(
            enter => enter
                .append("rect")
                .attr("x", d => x(d.xAxis))
                .attr("y", d => y(d.yAxis))
                .attr("width", x.bandwidth())
                .attr("height", (d) => this.height - y(d.yAxis))
                .attr("fill", "rgb(13, 185, 240)"),
            update => update.call(update => update
                .transition(t)
                .attr("x", d => x(d.xAxis))
                .attr("y", d => y(d.yAxis))
                .attr("height", (d) => this.height - y(d.yAxis))),
            exit => exit.call(exit => exit
                .transition(t)
                .attr("x", 0)
                .attr("y", 0)
                .attr("height", 0)
                .remove()))
his.svg.selectAll("*").remove()