【问题标题】:Why does removing, then re-adding bars to my stack bar chart change the position of the bars?为什么在我的堆叠条形图中删除然后重新添加条形会改变条形的位置?
【发布时间】:2024-04-21 17:05:02
【问题描述】:

在我的jsfiddle 中,如果您单击图例中的Pending 按钮,它应该会删除与该类别关联的条。这可行,但是当我单击Reset Legend 按钮(它为currateData 方法提供原始数据,以便Pending 条返回)时,它会将旧的待处理数据加载到不合适的位置。

我相信和这个方法有关:

function redrawPlot() {
    svg = d3.select('svg.chart')
        .attr('width', width)
        .attr('height', height);

    svg.selectAll('g.xaxis')
        .attr('transform', 'translate(0, ' + (height - margin.top - margin.bottom) + ')');
}

我无法删除此方法,因为我的代码比 jsfiddle 中显示的更复杂,这只是显示问题。我还需要在redraw方法中更新宽度和高度,所以不能随便去掉。

如何更改 redrawPlot() 方法,以便在重新填充图表时,在添加旧数据时不会弄乱条形位置?

【问题讨论】:

    标签: javascript d3.js bar-chart


    【解决方案1】:

    问题出在redrawPlot 函数中:

    var svg;
    
    function initPlot() {
        svg = d3.select('#graphTest') // <-- `svg` is the appended `g`
            .append('svg')
            // ...
            .append('g')
    
        // ...
    }
    
    // ...
    
    function redrawPlot() {
        svg = d3.select('svg.chart') // <-- redefining `svg` to be `svg`
    
        // ...
    }
    

    问题是您正在使用全局变量svg 并在redrawPlot 中重新定义它。如果您将 svg 的定义保留为原始定义,则图表会根据需要进行更新。通过添加var 使svg 的第二个定义局部于redrawPlot 解决了这个问题。

    作为旁注,尽量坚持reusable chart pattern 并避免使用全局变量。

    Demo

    如果要重新定义svg 变量

    免责声明/警告:这将导致无法维护的代码,不推荐。

    Demo 2

    【讨论】:

    • 感谢您抽出宝贵时间回复。不幸的是,我需要在那里重新定义 svg 变量,因为我正在处理更改绘图的多个实例。无论如何我可以重新定义变量,更改高度/宽度,并且仍然让我的所有条都处于正确的位置?
    • 所以使用你所说的我设置 svg = d3.select('g') 并且一切正常......感谢您的输入!