javascript - d3.js:使用 <g> 分组(通过数据连接进入/更新/退出循环)

标签 javascript d3.js svg

我制作了一个 JSFiddle 来直观地解释我的问题:https://jsfiddle.net/nph/poyxrmn7/

我尝试在 d3 代码中有效地使用 元素,以适合过渡的方式移动对象组。

举个例子,我正在尝试制作一个带有标记点的图表。我可以这样做,并且有效:

var labeledCircles1 = function(data){
  var svg = d3.select('svg');

  var circles = svg.selectAll('circle')
    .data(data);

  circles.enter().append('circle')
  circles.exit().remove()
  circles
    .attr('cx', function(d,i){ return i; })
    .attr('cy', function(d){ return d; })
    .attr('r', 10)

  var texts = svg.selectAll('text')
    .data(data)

  texts.enter().append('text')
  texts.exit().remove()
  texts
    .text(function(d){ return d; })
    .attr('x', function(d,i){ return i; })
    .attr('y', function(d){ return d; })
    .attr('dy', -10)
};

它输出类似这样的内容:

<svg>
  <circle cx="0" cy="10" r="10"></circle>
  <circle cx="1" cy="30" r="10"></circle>
  <text x="0" y="10" dy="-10">10</text>
  <text x="1" y="30" dy="-10">30</text>
</svg>

但这需要大量重复自己,如果我要向每个点添加更多元素,我就必须再次重复自己。它也不会在生成的 svg 中对元素进行逻辑分组,如上所示。

我希望能够只指定一次位置,并且让组更符合逻辑。我想要输出这个的代码:

<svg>
  <g transform="translate(0,10)">
    <circle r="10"></circle>
    <circle r="10"></circle>
  </g>
  <g transform="translate(1,30)">
    <text dy="-10">10</text>
    <text dy="-10">30</text>
  </g>
</svg>

但我不知道该怎么做。如何开始已经很清楚了:

var svg = d3.select('svg');

var groups = svg.selectAll('.group')
  .data(data)

groups.enter().append('g')
  .attr('class', 'group')
groups.exit().remove();
groups
  .attr('transform', function(d,i){
    var x = i * 20 + 50;
    var y = d + 20;
    return 'translate(' + x + ',' + y + ')';
  })

但是我不知道如何从那里继续。

如果我附加到groups,它第一次会起作用,但是当我更改数据集时,它会重新绘制我的circletext元素:

groups.append('circle')
  .attr('r', 10)

groups.append('text')
  .text(function(d) { return d; })
  .attr('dy', -10);

但是如果我对组执行selectAll,那么(当然)它根本不会绘制元素。

我确信我缺少一些简单的东西,但我不确定是什么。

(这似乎很可能是重复的,但我找不到其他人解决这个一般问题。)

最佳答案

如果您想一次性添加数据,最简单的方法是

    <g>
    <text></text>
    <circle></circle>
</g>
<g>
    <text></text>
    <circle></circle>
</g>
<g>
    <text></text>
    <circle></circle>
</g>
<g>
    <text></text>
    <circle></circle>
</g>
<g>
    <text></text>
    <circle></circle>
</g>

以及js函数

var labeledCircles3 = function(data) {
    var svg = d3.select('#svg3');
    var groups = svg.selectAll('g').data(data)

    // exit
    groups.exit().remove()

    // new
    var newGroups = groups.enter()
    var newgroup = newGroups.append('g')
    newgroup.append('text')
    newgroup.append('circle')

    // update + new
    groups = newGroups.merge(groups)
    groups.select('text')
        .text(function(d){ return d; })
        .attr('x', function(d,i){ return i * 20 + 50; })
        .attr('y', function(d){ return d + 20; })
        .attr('dy', -10)
    groups.select('circle')
        .attr('cx', function(d,i){ return i * 20 + 50; })
        .attr('cy', function(d){ return d + 20; })
        .attr('r', 10)
}

关于javascript - d3.js:使用 <g> 分组(通过数据连接进入/更新/退出循环),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43297888/

相关文章:

javascript - 如何在 three.js 中切割现有几何体

javascript - jquery 中的 NaN 错误。已经尝试过 ParseInt,仍然不起作用

javascript - D3 选择 html -- 传递函数时索引从 1 而不是 0 开始

javascript - 将对象函数传递给 d3 中的 data()

javascript - DiscordJS 检测用户何时加入公会

javascript - 通过 JavaScript 进行文件上传验证

javascript - d3.js 中的转换树形图

javascript - 如何在D3.js中平滑地绘制从起点到终点的路径

javascript - 交互式 donut 网络图表

javascript - createElementNS 是否始终离线工作?特别是 SVG 命名空间