javascript - D3.js 堆叠条形图的动画更新

标签 javascript d3.js stackedbarseries

我正在尝试随着基础数据的更改而更新带有转换的堆积条形图。它每次都调用相同的“渲染”函数,并且在不涉及转换时工作良好。但是,我想动画化值的变化,从当前状态转换到下一个状态。

我已经在一定程度上解决了这个问题,但感觉我的解决方案很笨拙 - 希望有更好的方法来处理堆积条形图。

我的方法是执行以下操作:

  1. 加载数据
  2. 加载初始条件(转换要求)
  3. 加载最终条件(在转换内)
  4. 将当前数据复制到另一个数组中:prevData
  5. 间隔后重新加载数据

使用上述方法,如果 prevData 有值,则使用这些值来设置初始条件。我的问题是查找和设置初始条件感觉非常笨拙:

if (prevData.length > 0) {
                            //get the parent key so we know who's data we are now updating
                            var devKey = d3.select(this.parentNode).datum().key;

                            //find the data associated with its PREVIOUS value
                            var seriesData = seriesPrevData.find(function (s) { return (s.key == devKey); })
                            if (seriesData != null) {
                                //now find the date we are currently looking at
                                var day = seriesData.find(function (element) { return (element.data.Date.getTime() == d.data.Date.getTime()); });

                                if (day != null) {
                                    //now set the value appropriately
                                    //console.debug("prev height:" + devKey + ":" + day[1]);
                                    return (y(day[0]) - y(day[1]));
                                }
                            }

                        }

我所做的就是找到正确的键数组(由 d3.stack() 创建),然后尝试找到适当的先前数据条目(如果存在)。然而,搜索父节点,并通过数组搜索来找到所需的键和适当的数据元素,感觉很冗长。

所以,我的问题是,有更好的方法吗?或者其中的一部分?

  1. 查找与此元素关联的先前绑定(bind)数据值或在函数内更改之前的当前值。
  2. 找到当前正在更新的 key 的更好方法,而不是使用:d3.select(this.parentNode)...?我尝试过传递键值,但似乎没有得到正确的结果。我取得的最好成果是将一个关键函数传递给父级,并按照上述方式查找它。

抱歉,这篇文章很长,我刚刚花了一整天的时间来研究我的解决方案,但我真正需要的是某个项目的先前值,这让我感到沮丧。必须做所有这些“体操”才能得到我需要的东西,这看起来非常“不”D3.js :-)

谢谢

最佳答案

以下是动画条形图的简单示例。它将迭代数据集的两个不同版本,以展示如何使用 d3 轻松处理基础数据的更改。 (在此示例中)不需要为过渡/动画准备任何手动数据。

var data = [
  [1, 2, 3, 4, 5],
  [1, 6, 5, 3]
];

var c = d3.select('#canvas');

var currentDataIndex = -1;
function updateData() {

    // change the current data
    currentDataIndex = ++currentDataIndex % data.length;
    console.info('updating data, index:', currentDataIndex);
    var currentData = data[currentDataIndex];
  
    // get our elements and bind the current data to it
    var rects = c.selectAll('div.rect').data(currentData);

    // remove old items
    rects.exit()
        .transition()
        .style('opacity', 0)
        .remove(); 

    // add new items and define their appearance
    rects.enter()
        .append('div')
        .attr('class', 'rect')
        .style('width', '0px');

    // change new and existing items
    rects
        // will transition from the previous width to the current one
        // for new items, they will transition from 0px to the current value
        .transition()
        .duration('1000')
        .ease('circle')
        .style('width', function (d) { return d * 50 + 'px'; });
    
}

// initially set the data
updateData();

// keep changing the data every 2 seconds
window.setInterval(updateData, 2000);
div.rect {
  height: 40px;
  background-color: red;
}

div#canvas {
  padding: 20px;
  border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="canvas">  
</div>

关于javascript - D3.js 堆叠条形图的动画更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41666004/

相关文章:

javascript - 从 ui-select 框中进行选择后,所选择的选项不会像所选择的那样粘贴(不可见)

javascript - 在 SO 中输入问题时出现 "How to Ask"框。如何获得滚动效果?纯 CSS 还是 JS?

javascript - 使 webpack 5 Assets 加载器与 webpack-dev-server 一起工作

asp.net - 避免在 gridview 事件上回发

javascript - 人力车图将刻度旋转 -90 度

dictionary - D3.geo : responsive frame given a geojson object?

从 ggplot 中的频率分布中删除缺失值

javascript - D3.js - 补间弧位置,内半径和外半径 - D3.js Arc

r - ggplot2 中具有两种色阶的并排堆叠条形图

javascript - 带有可切换系列的 d3.js 堆积条