d3数据绑定未使用联接创建子元素

时间:2019-02-28 19:59:16

标签: d3.js

我很沮丧,很乐意任何能向正确方向踢我的人的帮助。我正在尝试创建组g和其中的单个矩形。 join非常适合g的父级,但不会创建子级。我想念什么? (我正在考虑加入!)

我尝试将join替换为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);

1 个答案:

答案 0 :(得分:2)

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

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

var rects = groups.selectAll('rect')
                .data(function (d) { return [d]; })

更新了fiddle

但是,如果您只是将父母的原样传递给单个孩子,则这不是最佳方法。您不需要使用嵌套的输入/更新/退出循环,只需附加到父项即可:

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

修改后的fiddle

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

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.append('rect')
     .attr('x', 0)
     .attr('y', 0)
     .attr('width', 80)
     .attr('height', 20)
     .attr('stroke', '#666666')
     .attr('fill', function (d) { return d.fill; });
     
  rects.each(function(d) {
    console.log(d);
  })
}

updateNodes(NodeData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.0/d3.min.js"></script>
<div id="canvas" style="border: 1px solid #D9D9D9; width: 100%; height: 600px; margin-top: 6px"></div>