简体   繁体   中英

How to update subelements in d3?

I want to draw nodes (for force layout, but in this question I leave just nodes, to minimize the code), which have properties like position, color, text, and is drawn using several elements inside g .

I am trying to implement "General update pattern", and here is what I have:

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();
};

It updates group transform attribute, it adds and removes nodes with subelements, but how do I update attributes inside subelements, like fill of the circle , and "text" of text ?

Here is JSFiddle with all the code, which illustrates the problem: http://jsfiddle.net/2kqLC/2/

Just make a new sub selection on the initial update selection and edit its attributes.

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

jsfiddle.net/2kqLC/3

Method of Imperative works jsut fine, but could be updated to escape duplication of code which sets attributes:

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/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM