假设我有一些使用D3构建的复杂数据可视化。 我想不仅添加不同大小的基本rects,还要创建由不同图形组构建的单元集,例如在单个组元素中包含一些矩形,三角形指针,文本标签和背景矩形。
我主要运行var unit = d3.select('.unit').data(units).enter().append('g')
来创建这些容器。现在,如何正确添加内部内容,以便它不会使用简单的unit.append('rect')
在每次数据更新时添加多个欺骗项?
现在我必须做这样的事情if (!unit.select('.label').size()){//append the element} else {//update existing element}
。
如果我有例如单位内部的5个元素,所有这些if..then
很容易变得丑陋。
有没有更好的方法来管理这样的案例?
答案 0 :(得分:0)
您可以将复杂的绘图移动到单独的功能
var unit = d3.selectAll('.unit').data(units);
// ENTER
unit.enter().append('g')
.attr('class', 'unit')
// ... transform and other unit-level stuff here
// UPDATE
unit.transition().duration()
.call(drawUnit);
// EXIT
unit.exit()
.remove();
在drawUnit
函数中,您可以编写如下内容:
function drawUnit(units) {
units.each(function(d) {
var unit = d3.select(this); // select g.unit
// DRAW LABEL
var label = unit.selectAll('text')
.data([d]); // rejoin data from the unit to the label
// enter
label.enter()
.append('text');
// update
label
.text(function(d) { return d.label; });
// exit
// if you need to hide the labels then instead of `.data([d])` you can
// use something like this `.data(d.label.length ? [d] : [])`
// label.exit().remove();
// draw other inner elements of the unit
// DRAW ARROW
var arrow = unit.selectAll('.arrow').data([d]);
// ....
});
}
这是JSFiddle的更多评论:http://jsfiddle.net/fd6o4eey/1/