简体   繁体   中英

D3: update data in group selection with additional ('g')

For my chart I had to create groups which contain several elements (line, rect, text). I did my setup like in this question: D3: update data with multiple elements in a group

I defined my groups like this:

var group = groupContainer.selectAll('g')
    .data(items);
var groupEnter = group.enter()
    .append('g');

For each group element I appended a rect and did the update (later for my brushing event).

// append
groupEnter.append('rect')
    .attr('class', 'item')
    .style('fill', function (d) { return d.color; })
    .attr('x', function (d) { return x1(d.x); })
    .attr('y', function (d) { return y1(d.y); })
    .attr('width', '50')
    .attr('height', '50');

//update
group.select('rect')
    .attr('x', function (d) { return x1(d.x); })
    .attr('y', function (d) { return y1(d.y); });

This works! Now when I want to put another group element between my group and the rect, the update won't work anymore.

// append
groupEnter.append('g').append('rect') // here is the change
    .attr('class', 'item')
    .style('fill', function (d) { return d.color; })
    .attr('x', function (d) { return x1(d.x); })
    .attr('y', function (d) { return y1(d.y); })
    .attr('width', '50')
    .attr('height', '50');

//update
group.select('rect')
    .attr('x', function (d) { return x1(d.x); })
    .attr('y', function (d) { return y1(d.y); });

The selection group.select('rect') is the same as before. What am I doing wrong?

EDIT: I investigated my problem furthermore. It seems like the update method has the wrong data mapping. Without the group element (the working example), I get for

group.select('rect')
    .attr('x', function (d) { console.log(d); return x1(d.x); })
    .attr('y', function (d) { return y1(d.y); });

the ouput:

item 1 item 2 item 3 item 4 item 5 item 6 item 7 item 8 item 9 item 10

For the version with the group element I just get the output:

item 2 item 2 item 4 item 4 item 6 item 6 item 8 item 8 item 10 item 10

Some rects get drawn as well, but not all. I guess only 2, 4, 6, 8, 10. Whats wrong with the mapping? Do I have to re-map my data?

I did manage it by adding the optional data() parameter to match the elements.

var group = groupContainer.selectAll('g')
    .data(items, function (d) { return d.id; });

Can someone comment why I would need this optional parameter for matching when I use an additional append('g')?

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