我无法看到一些潜在的大规模重构的全局。我正在寻找一种同时解决两个问题的解决方案(如果存在的话)。我已经很长时间没有用 d3 编写代码了,而且一开始也不是很流利。
我创建了一个简单的 MCMC 演示。它看起来像这样:
所有数据都存在于数组 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/