如何更新d3中的子元素?

时间:2014-07-17 11:24:56

标签: javascript d3.js

我想绘制节点(用于强制布局,但在这个问题中我只留下节点,以最小化代码),它具有位置,颜色,文本等属性,并使用g内的多个元素绘制。

我正在尝试实施“常规更新模式”,这就是我所拥有的:

var update = function(data) {
    var nodes = svg.selectAll('g').data(data);

    var nodeenter = nodes.enter().append('g')

    // append + update
    nodes.attr('transform', function(d, i) {
            return 'translate(' +
                (radius + i * radius * 2) + ',' +
                (height / 2 + d.height)
            +')';
        });

    // append
    nodeenter.append('circle')
        .attr('r', radius)
        .style('fill', function (d) { return d.color; });
    nodeenter.append('text')
        .text(function (d) { return d.text });

    // remove
    nodes.exit().remove();
};

它会更新组transform属性,它会添加和删除带有子元素的节点,但如何更新子元素内的属性,例如fill的{​​{1}}和circle"text"

这是JSFiddle的所有代码,它说明了问题:http://jsfiddle.net/2kqLC/2/

2 个答案:

答案 0 :(得分:1)

只需在初始更新选择上进行新的子选择并编辑其属性。

nodes.select('text').text(function (d) { return d.text });
nodes.select('circle').style('fill', function (d) { return d.color; });

jsfiddle.net/2kqLC/3

答案 1 :(得分:0)

Imperative方法工作得很好,但可以更新以避免重复设置属性的代码:

var update = function(data) {
    var nodes = svg.selectAll('g').data(data);

    // append
    var nodeenter = nodes.enter().append('g');
    nodeenter.append('circle').attr('r', radius);
    nodeenter.append('text');

    // append + update
    nodes.attr('transform', function(d, i) {
            return 'translate(' +
                (radius + i * radius * 2) + ',' +
                (height / 2 + d.height)
            +')';
        });

    nodes.select('text').text(function (d) { return d.text });
    nodes.select('circle').style('fill', function (d) { return d.color; });

    // remove
    nodes.exit().remove();
};

http://jsfiddle.net/2kqLC/5/