d3 数据绑定不使用 join 创建子元素

Sco*_*ott 2 d3.js

我完全被难住了,希望任何能把我踢向正确方向的人伸出援助之手。我正在尝试创建组g和其中的单个矩形。这join对父母来说很有用g,但它并不能创造孩子。我缺少什么?(我正在考虑加入!)

我尝试join用 an替换enter().append('g')也无济于事,所以我错过了一些东西。

这是一个jsfiddle

var svg = d3.select("div#canvas")
                    .append("svg")
                    .attr("width", '100%')
                    .attr("height", '100%');

let NodeData = [
    {
        'x': 20,
        'y': 20,
        'id': 'abc',
        'fill': '#D4C2F1'
    },
    {
        'x': 20,
        'y': 80,
        'id': 'def',
        'fill': '#B3D2C5'
    },
];

function updateNodes(data) {

    var groups = svg.selectAll('g').data(data)
                    .join('g')
                        .attr('node-id', function (d) { return d.id; })
                        .attr('transform', function (d) { return `translate(${d.x}, ${d.y})` });

    var rects = groups.selectAll('rect')
                    .data(function (d) { return d; })
                    .join('rect')
                        .attr('x', 0)
                        .attr('y', 0)
                        .attr('width', 80)
                        .attr('height', 20)
                        .attr('stroke', '#666666')
                        .attr('fill', function (d) { return d.fill; });
}

updateNodes(NodeData);
Run Code Online (Sandbox Code Playgroud)

And*_*eid 5

selection.data()需要一个数组(或返回数组的函数)。.data()尝试创建子项时,您没有传递数组rect。您正在传递一个对象 - 原始数据数组中的单个项目,因此不会输入任何元素。

要解决这个问题,您可以简单地使用:

var rects = groups.selectAll('rect')
                .data(function (d) { return [d]; })
Run Code Online (Sandbox Code Playgroud)

更新了小提琴

但是,如果您只是将父级的数据按原样传递给单个子级,那么这不是最好的方法。您不需要使用嵌套的进入/更新/退出循环,您只需附加到父级:

var groups = svg.selectAll('g').data(data)
   .join('g')
   .attr('node-id', function (d) { return d.id; })
   .attr('transform', function (d) { return `translate(${d.x}, ${d.y})` });

var rects = groups.append("rect")
   .attr('x', 0)
   .attr('y', 0)
   .attr('width', 80)
   .attr('height', 20)
   .attr('stroke', '#666666')
   .attr('fill', function (d) { return d.fill; });
Run Code Online (Sandbox Code Playgroud)

改装小提琴

新的子元素rect继承其父元素的绑定数据,如下所示:

var rects = groups.selectAll('rect')
                .data(function (d) { return [d]; })
Run Code Online (Sandbox Code Playgroud)
var groups = svg.selectAll('g').data(data)
   .join('g')
   .attr('node-id', function (d) { return d.id; })
   .attr('transform', function (d) { return `translate(${d.x}, ${d.y})` });

var rects = groups.append("rect")
   .attr('x', 0)
   .attr('y', 0)
   .attr('width', 80)
   .attr('height', 20)
   .attr('stroke', '#666666')
   .attr('fill', function (d) { return d.fill; });
Run Code Online (Sandbox Code Playgroud)