首页 > 解决方案 > 如何在更新时正确调整 d3 条形图箱的宽度?

问题描述

我正在尝试在我的角度应用程序中实现 d3 条形图。当我提取新数据时,沿 x 轴的 bin 数量会发生变化,但 bin 不会适当调整大小和移动。加载时,箱与轴刻度正确对齐,但在更改之后,存在间距和对齐问题。有人可以告诉我如何使垃圾箱像轴一样动态并正确更新吗?

我在这里在 stackblitz 上重现了我的问题:https ://stackblitz.com/edit/angular-d3-bin-resize-error

我用来更新图表的代码在这里:

async draw() {
    var color_scale = this.color_scale;
    var height = this.hght;
    var filteredCountsData = await this.filterData();

    var t = d3.transition()
        .duration(2000);

    var max_value = d3.max(filteredCountsData, function(d : any) {
        return +d.count;
    });
    var x_scale = this.x_scale.domain(filteredCountsData.map(function(d) {
        return d.category;
    }));

    var y_scale = this.y_scale.domain([0, max_value]);

    this.color_scale.domain([0, max_value]);

    var bars = this.svg.selectAll('.bar')
        .data(filteredCountsData);

    bars
        .exit()
        .remove();

    var new_bars = bars
        .enter()
        .append('rect')
        .attr('class', 'bar')
        .attr('x', function(d : any) {
            return x_scale(d.category);
        })
        .attr('width', x_scale.bandwidth())
        .attr('y', height)
        .attr('height', 0)

    new_bars.merge(bars) // @ts-ignore
        .transition(t)
        .attr('width', x_scale.bandwidth())
        .attr('y', function(d : any) {
            return y_scale(+d.count);
        })
        .attr('height', function(d : any) {
            return height - y_scale(+d.count)
        })
        .attr('fill', function(d) {
            return color_scale(+d.count);
        })

    this.svg.select('.x.axis')
        .transition(t)
        .call(this.x_axis);

    this.svg.select('.y.axis')
        .transition(t)
        .call(this.y_axis); // @ts-ignore
}

如果您查看 stackblitz 链接并单击更改 bins 按钮,直到 bins 数量发生变化,您可以重现间距错误。

标签: angulard3.js

解决方案


我认为您忘记xmerge. 所以合并将导致:

    new_bars.merge(bars) // @ts-ignore
        .transition(t)
        .attr('width', x_scale.bandwidth())
        .attr('y', function(d : any) {
            return y_scale(+d.count);
        })
        .attr('x', function(d : any) {
            return x_scale(d.category);
        })
        .attr('height', function(d : any) {
            return height - y_scale(+d.count)
        })
        .attr('fill', function(d) {
            return color_scale(+d.count);
        })

推荐阅读