javascript - D3 - 在循环中插入内部元素

标签 javascript d3.js svg

this question 的后续内容:

我正在 D3 中创建一个平行坐标图表,它将代表多个品牌的数据。每个品牌在四列中每一列都有一个点,全部包含在 g 元素内 .line-group:

在我的上一个问题(上面链接)中,我询问如何为每个品牌绘制一条连接四个点的路径,我正在使用下面的代码执行此操作:

    var svg = d3.selectAll('svg'),
        line = d3.svg.line(),
        circles = svg.selectAll('.line-group')
                     .selectAll('circle'),
        circleCoords = [];

    for ( i = 0; i < circles.length; i++ ) {
      circles[i].forEach( function(d) {
        var cx = d.getAttribute('cx'),
            cy = d.getAttribute('cy');

        circleCoords.push([cx, cy]);
      });

      svg.append('path')
         .attr({ 'd' : line( circleCoords ) });

      circleCoords = [];
    };

这会将路径附加到 svg,如下所示:

<g class="line-group">
    <circle r="5" cx="425.2290564534928" cy="0" data-brand="Brand Y"></circle>
    <circle r="5" cx="855.0959051939095" cy="59.347826086956466" data-brand="Brand Y"></circle>
    <circle r="5" cx="1558.2469152243186" cy="229.1306884480747" data-brand="Brand Y"></circle>
    <circle r="5" cx="2301.687268451202" cy="0" data-brand="Brand Y"></circle>
</g>

<g class="line-group">
    <circle r="5" cx="339.08350155311" cy="41.49035025017887" data-brand="Brand Z"></circle>
    <circle r="5" cx="988.2304636988625" cy="161.08695652173915" data-brand="Brand Z"></circle>
    <circle r="5" cx="1705.337437853109" cy="170.04667444574085" data-brand="Brand Z"></circle>
    <circle r="5" cx="2088.4372304285025" cy="112.10192697768763" data-brand="Brand Z"></circle>
</g>

<path d="M425.2290564534928,0L855.0959051939095,59.347826086956466L1558.2469152243186,229.1306884480747L2301.687268451202,0"></path>

<path d="M339.08350155311,41.49035025017887L988.2304636988625,161.08695652173915L1705.337437853109,170.04667444574085L2088.4372304285025,112.10192697768763"></path>

虽然这有效,但这些路径无法访问加入 .line-group 的数据(并且有点无组织)。如何在正确的 .line-group 内绘制每个路径,使其看起来像这样:

<g class="line-group">
    <circle r="5" cx="425.2290564534928" cy="0" data-brand="Brand Y"></circle>
    <circle r="5" cx="855.0959051939095" cy="59.347826086956466" data-brand="Brand Y"></circle>
    <circle r="5" cx="1558.2469152243186" cy="229.1306884480747" data-brand="Brand Y"></circle>
    <circle r="5" cx="2301.687268451202" cy="0" data-brand="Brand Y"></circle>
    <path d="M425.2290564534928,0L855.0959051939095,59.347826086956466L1558.2469152243186,229.1306884480747L2301.687268451202,0"></path>
</g>

<g class="line-group">
    <circle r="5" cx="339.08350155311" cy="41.49035025017887" data-brand="Brand Z"></circle>
    <circle r="5" cx="988.2304636988625" cy="161.08695652173915" data-brand="Brand Z"></circle>
    <circle r="5" cx="1705.337437853109" cy="170.04667444574085" data-brand="Brand Z"></circle>
    <circle r="5" cx="2088.4372304285025" cy="112.10192697768763" data-brand="Brand Z"></circle>
    <path d="M339.08350155311,41.49035025017887L988.2304636988625,161.08695652173915L1705.337437853109,170.04667444574085L2088.4372304285025,112.10192697768763"></path>
</g>

最佳答案

以下是对操作顺序进行更改的快速重构:

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

svg.selectAll('.line-group').each(function(){
  var lg = d3.select(this),
      circleCoords = [];
  lg.selectAll("circle").each(function(){
    var c = d3.select(this),
      cx = c.attr('cx'),
      cy = c.attr('cy');
    circleCoords.push([cx, cy]);
  });
  lg.append('path')
    .attr({
      'd': line(circleCoords)
    });
});

产品:

  <g class="line-group">
    <circle r="5" cx="425.2290564534928" cy="0" data-brand="Brand Y"></circle>
    <circle r="5" cx="855.0959051939095" cy="59.347826086956466" data-brand="Brand Y"></circle>
    <circle r="5" cx="1558.2469152243186" cy="229.1306884480747" data-brand="Brand Y"></circle>
    <circle r="5" cx="2301.687268451202" cy="0" data-brand="Brand Y"></circle>
    <path d="M425.2290564534928,0L855.0959051939095,59.347826086956466L1558.2469152243186,229.1306884480747L2301.687268451202,0"></path>
  </g>
  <g class="line-group">
    <circle r="5" cx="339.08350155311" cy="41.49035025017887" data-brand="Brand Z"></circle>
    <circle r="5" cx="988.2304636988625" cy="161.08695652173915" data-brand="Brand Z"></circle>
    <circle r="5" cx="1705.337437853109" cy="170.04667444574085" data-brand="Brand Z"></circle>
    <circle r="5" cx="2088.4372304285025" cy="112.10192697768763" data-brand="Brand Z"></circle>
    <path d="M339.08350155311,41.49035025017887L988.2304636988625,161.08695652173915L1705.337437853109,170.04667444574085L2088.4372304285025,112.10192697768763"></path>
  </g>
<小时/>

完整代码:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  
  <style>
    path {
      fill: none;
      stroke: steelblue
    }
  </style>
</head>

<body>
  <svg width="3000" height="600">
    <g class="line-group">
      <circle r="5" cx="425.2290564534928" cy="0" data-brand="Brand Y"></circle>
      <circle r="5" cx="855.0959051939095" cy="59.347826086956466" data-brand="Brand Y"></circle>
      <circle r="5" cx="1558.2469152243186" cy="229.1306884480747" data-brand="Brand Y"></circle>
      <circle r="5" cx="2301.687268451202" cy="0" data-brand="Brand Y"></circle>
    </g>

    <g class="line-group">
      <circle r="5" cx="339.08350155311" cy="41.49035025017887" data-brand="Brand Z"></circle>
      <circle r="5" cx="988.2304636988625" cy="161.08695652173915" data-brand="Brand Z"></circle>
      <circle r="5" cx="1705.337437853109" cy="170.04667444574085" data-brand="Brand Z"></circle>
      <circle r="5" cx="2088.4372304285025" cy="112.10192697768763" data-brand="Brand Z"></circle>
    </g>
  </svg>

  <script>
    var svg = d3.select('svg'),
      line = d3.svg.line();

    svg.selectAll('.line-group').each(function(){
      var lg = d3.select(this),
          circleCoords = [];
      lg.selectAll("circle").each(function(){
        var c = d3.select(this),
          cx = c.attr('cx'),
          cy = c.attr('cy');
        circleCoords.push([cx, cy]);
      });
      lg.append('path')
        .attr({
          'd': line(circleCoords)
        });
    });
  </script>
</body>

</html>

关于javascript - D3 - 在循环中插入内部元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38210868/

相关文章:

javascript - PhantomJS - 从点击事件加载的内容不会加载到 DOM

javascript - 将插入符号位置保持在文本输入中的可见位置 - firefox 行为不当

canvas - Dart 从 Canvas 上的 SVG 文件中绘制 ID

javascript - svg<g>元素的BBox计算

javascript - 为什么在 javascript 中不调用覆盖的 toString()

javascript - 在 IE7 中,如何在 jquery .click 事件期间使用 ajax 调用设置全局变量或元素值?

d3.js - 使用 d3.wordcloud 重绘词云

javascript - 对条形图中的 x 轴使用序数刻度 ('d3.scale.ordinal' )

javascript - 在 .nest() 调用后使用 d3.js 将数据放入表中

css - SVG 和 CSS 用于渐变的浏览器资源量有什么不同吗?