我正在学习如何在Mike的Towards Reusable Charts article,Christophe Viau的The D3 Reusable API Speech(10到20分钟)和我在Stackoverflow上找到的a fiddle之后创建D3js可重用模块。我的简化可重用模块预计会生成4 x 2矩形,但是目前只生成2个矩形然后无法正确循环其余的数据:
//Data
var data = [
{row: 0, col: 0, value: [{x: 1, y: 19}, {x: 2, y: 20}]}, // <= This only is produced!
{row: 0, col: 1, value: [{x: 1, y: 24}, {x: 2, y: 27}]}, // <= from there it fails
{row: 1, col: 1, value: [{x: 1, y: 31}, {x: 2, y: 26}]},
{row: 1, col: 2, value: [{x: 1, y: 29}, {x: 2, y: 19}]}
];
JS应循环我的数据:
function exports(_selection) { // create function to export
_selection.each(function(_data) { // loop
var test_data = _data.value;
var rectW = (_data.row+2)*10,
rectH = (_data.col+1)*10;
// Select all bars and bind data:
var bars = svg.selectAll(".bar")
.data(test_data)
.enter().append("rect");
console.log(i+": "+JSON.stringify(_data.value));
// design svg elements
bars.attr("class","bar")
.attr({
'width': rectH,
'x': function (d){ console.log(" log place1! "); return d.x * 10;},
'y': function (d){ return d.y * 4;},
'height': rectH*4});
console.log(" log place2! ");
});
}// exports end
如何让它循环? fiddle。
答案 0 :(得分:1)
每次call(chart)
函数结束时,重新选择之前插入svg的条形图而不创建任何新条形图。此外,巧合的是,由于您已将// design svg elements
指定为bars
的结果,因此预先存在的条形图不会作为后续更新的一部分进行重新绘制(在enter()
下)仅仅是data()
绑定的结果。
您可能想要为每对条形创建一个容器。您可以使用d3绑定而不是您编写的for
循环。像这样:
// Module and custom settings
var chart = d3.coolmodules.barChart()
.width(800).height(800);
// Runs
svg.selectAll("g").data(data)
.enter()
.append('g')
.attr('transform', function(d, i) {
return 'translate(' + (i*50) + ',0)';// Space the <g>'s horizontally
})
.call(chart);
另一个重要的变化是替换
var bars = svg.selectAll(".bar")
与
var bars = d3.select(this).selectAll(".bar")
后者对分配给一对条形的每个g
进行操作。前者是在整个svg上运作的。可重用组件似乎不适合访问您创建的svg
。将d3选择传递给模块函数的主要原因是指定容器。这样,该组件只涉及布置其子女,而父母&#34;使用该组件的代码负责定位父容器。
这里是updated fiddle。