在D3图表中使用SVG组作为更复杂的条形图

时间:2015-03-04 20:47:41

标签: javascript svg d3.js

假设我有一些使用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很容易变得丑陋。

有没有更好的方法来管理这样的案例?

1 个答案:

答案 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/