d3.js - d3 中高效的数据存储、分区和选择

标签 d3.js

我无法看到一些潜在的大规模重构的全局。我正在寻找一种同时解决两个问题的解决方案(如果存在的话)。我已经很长时间没有用 d3 编写代码了,而且一开始也不是很流利。

我创建了一个简单的 MCMC 演示。它看起来像这样: demo pic

所有数据都存在于数组 thetas 中,该数组的维度为 nChains x nIters,或 2 x ...(链长随着每次鼠标点击而增加)。

现在我想展示一个烙印,每条链的长度都相同。对于左图,老化将以不同颜色(例如,橙色和红色)显示每个链的第一个 biLength 点。实际上,第一个 biLength 已经存在的点将以不同的颜色显示。 在右侧的直方图上,我希望这些点有自己对应的条形。

我是否应该创建一个单独的数组来保存老化,在每个图上有效地绘制两个数据容器? (是否有如何执行此操作的示例?)或者,是否有某种方法可以将数据保存在 thetas 中但以不同方式处理子组件? (例子?)

下面是一些示例代码,展示了我目前如何绘制 thetas:

// Left plot update
function movePoints ()
    { 
    var tmp = chart.selectAll(".vis1points").data(thetas[0], function (d, i) { return i; } );
    tmp
        .enter().insert("svg:circle")
        .attr("class", "vis1points")
        .attr("cx", function (d, i) { return xx(i); })
        .attr("cy", yy)
        .attr("r", 3)
    tmp.transition()
        .duration(10)
        .attr("cx", function (d, i) { return xx(i); })
        .attr("cy", yy)
    tmp.exit()
        .transition().duration(10).attr("r",0).remove();

    if ( nChains == 2 ) {
        var tmp2 = chart.selectAll(".vis1points2").data(thetas[1], function (d, i) { return i; } );
        tmp2
        .enter().insert("svg:circle")
        .attr("class", "vis1points2")
        .attr("cx", function (d, i) { return xx(i); })
        .attr("cy", yy)
        .attr("r", 3)
        tmp2.transition()
        .duration(10)
        .attr("cx", function (d, i) { return xx(i); })
        .attr("cy", yy)
        tmp2.exit()
        .transition().duration(10).attr("r",0).remove();
    }
    };

坐标轴目前将 thetas 作为输入来推断范围和域限制。

对于右侧的直方图:

 // Creation involves... 
    var dataLength = thetas[0].length;
    this.histBars = this.vis.selectAll("rect.vis2bars")
        .data(that.histVals.counts[0])
        .enter().append("svg:rect")
        .attr("class", "vis2bars")
        .attr("x", function (d, i) { return that.xx2(i); }) 
        .attr("y", function (d, i) { return that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[0])/dataLength)); })    
        .attr("height",function (d, i) { return that.yy2(0)-that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[0])/dataLength)); })
        .attr("width", Math.floor(innerWidth2/numBins));
    this.histBars.transition()
        .attr("y", function (d, i) { return that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[0])/dataLength)); })    
        .attr("height",function (d, i) { return that.yy2(0)-that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[0])/dataLength)); })
        .duration(dur);

和更新:

    this.update = function( dur2 ) {
    var dataLength = thetas[0].length;
    var tmp2 = this.histBars.data(this.histVals.counts[0]); 
    var tmp3;
    if ( nChains > 1 ) { // fix
        tmp3 = this.histBars2.data(this.histVals.counts[1]);
    }
    var that = this;
    tmp2
        .transition()
        .delay( 0 ) // could tweak...
        .duration(dur2 - 10)
        .attr("y", function (d, i) { return that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[0])/dataLength)); })    
        .attr("height",function (d, i) { return that.yy2(0)-that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[0])/dataLength)); }); 

    // Add update for second data set
    if ( nChains > 1 ) {
        tmp3
        .transition()
        .attr("y", function (d, i) { return that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[1])/dataLength)); })    
        .attr("height",function (d, i) { return that.yy2(0)-that.yy2(that.maxDensity*(d/dataLength)/(d3.max(that.histVals.counts[1])/dataLength)); }); 
    } 

最佳答案

您可以在更新时动态更改圆圈的颜色,例如在此处:

tmp.transition()
    .duration(10)
    .attr("cx", function (d, i) { return xx(i); })
    .attr("cy", yy)
    .attr("fill", function(d) {
         if (d.isBiLengthPoint) {
              return "orange";
         } else {
              return "blue";
         }
     });

我假设目前您是根据 CSS 为圆圈着色,但对于您想要的效果,我真的认为动态加载它们是更好的解决方案。

或者您可以动态更改您的圈子的类并声明两个 CSS 类

tmp.transition()
    .attr("class", function(d) {
         if (d.isBiLengthPoint) {
              return "vis1points-bilength";
         } else {
              return "vis1points";
         }
     })
    .duration(10)
    .attr("cx", function (d, i) { return xx(i); })
    .attr("cy", yy)

在你的 CSS 中

 vis1points {
     fill: blue;
 }
 vis1points-bilength {
     fill: orange;
 }

关于d3.js - d3 中高效的数据存储、分区和选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18582563/

相关文章:

javascript - 如何创建适用于移动和桌面浏览器的平面图?

javascript - D3 : how to select the div from multiple divs with the same class by the inner html in D3?

d3.js 将比例调整为蓝色的 rgb() 范围

javascript - 看不见的向量?组合 d3.tile()、d3.zoom() 和 TopoJSON 向量

d3.js - d3 : how do the create and update selections work? 中的可重用图表

javascript - d3js svg viewBox 不允许计算 window.innerWidth - 170

html - D3 JS Arch,边界有圆圈

javascript - 可折叠缩进树的初始状态

javascript - 如何向 d3.xhr 调用添加全局监听器

javascript - 在时间序列图表 C3.js 中使用数组作为数据源