как обновить график d3 при получении новых ДАННЫХ - PullRequest
0 голосов
/ 04 августа 2020

Как обновить диаграмму d3 новыми данными: я реализую на ngOnchanges три функции:

        this.removeSvg(this.data);
        this.createSvg();
        this.drawBars(this.data);

где createSvg ():

private createSvg(): void {
    this.svg = d3.select("figure#histogram")
        .append("svg")
        .attr("width", '100%')
        .attr("height", '100%')
        .append("g")
        .attr("transform", "translate(" + this.margin + "," + this.margin + ")");
}

и removeSvg ():

       this.svg = d3.select("figure#histogram")
       .exit().remove()
       d3.select("#histogram").select("svg").remove();

и drawBars (data: any []):

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)");
}

, но он не обновляет график, даже если я уверен, что данные обновляются (поэтому для первого графика мы продолжаем имея все остальные диаграммы, как будто это те же данные) любая помощь? возможно удаление или выход здесь ложны!

Ответы [ 3 ]

1 голос
/ 05 августа 2020

В D3 манипулирование DOM может выполняться с помощью выделений. В вашей функции drawBars() вы используете выбор enter, который описывает, что происходит с новыми данными. Чтобы описать, что происходит с данными, которые изменились, используйте выбор update; для уходящих данных используйте выбор exit. Чтобы отслеживать обновленные данные, вам потребуется ключевая функция в вызове data(), которая однозначно идентифицирует каждый элемент.

См. Этот учебник для более подробного обзора.

В вашей drawBars() функции:

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()))
}
0 голосов
/ 05 августа 2020

решено!

для любого, кто сталкивается с этой проблемой, я советую ему следующее решение: просто сохраните все как есть, но обязательно обновляйте sh данные при каждом изменении, затем очищайте svg всех его элементов с помощью:

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

, затем снова нарисуйте диаграмму с новыми данными.

0 голосов
/ 05 августа 2020
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()))

это не помогло сделать переход при обновлении данных.

...