d3v4强制为每个现有节点添加两个新的嵌套节点

时间:2019-01-20 09:27:48

标签: d3.js force-layout

对于我的力仿真中的每个节点,作为仿真的一部分,我想在其下面的任一侧(请参见下图)创建两个新节点。我无法成功地将新节点绘制为原始节点的嵌套选择。在“ Plunker”中,您可以看到“ Cow sharks”模式,并且“ multiply”模式理想情况下应在相同位置包含四个与“ cow sharks”模式相似的节点,并在下面放置八个(每个两个)节点。 我创建了一个矩阵,以嵌套数组的形式保存新节点的数据,因此每个子数组中将有两个元素,总共有x个子数组,x是原始节点的数量。我在我认为新节点位置应该位于的位置添加了x和y坐标(我不确定我是否正确计算了位置)。 看来我已经成功创建了新的节点元素(如果在DOM中查看,它们就会存在),但是没有正确绘制。有人可以指出正确的方向,以在力模拟中正确添加新节点作为嵌套选择吗?谢谢

enter image description here

下面是我的代码,下面是代码:https://plnkr.co/edit/UgZyjfsGmDRRkEAx66mJ?p=preview

    var matrix = [];

    var i;

    for (i = 0; i < nodes.length; i++) {
      var newarr = [];
      var obj1 = {};
      var obj2 = {};
      obj1['x'] = nodes[i].x + (0.1 * width) * Math.cos((5 * Math.PI) / 4);
      obj2['x'] = nodes[i].x + (0.1 * width) * Math.sin((7 * Math.PI) / 4);
      obj1['y'] = nodes[i].y + (0.1 * width) * Math.cos((5 * Math.PI) / 4);
      obj2['y'] = nodes[i].y + (0.1 * width) * Math.sin((7 * Math.PI) / 4);
      newarr.push(obj1)
      newarr.push(obj2)
      matrix.push(newarr);
    }

    var newNodes = filterNodes('family_common', 'Cow Sharks');

    circles = g.selectAll(".sharks").data(newNodes);

    circles.exit()
      .transition()
      .duration(750)
      .attr("r", 0)
      .remove();

    circles.transition().duration(750)
      .attr("fill", function(d) {
        return colorScale(d.family)
      }).attr("r", function(d) {
        return radiusScale(+d.size);
      })



    circles.enter().append("circle").attr("class", "sharks")
      .attr("id", function(d) {
        var cname = d.name;
        cname = cname.split(' ');
        return cname[0] + '_' + cname[1];
      })
      .attr("fill", function(d) {
        return colorScale(d.family)
      }).attr("r", function(d) {
        return radiusScale(+d.size);
      })
      .attr('stroke', '')


    //here is where I attempt to create two new nodes for each of the cow shark nodes
    //but it's not working

    g.selectAll(".sharks").data(matrix)
      .selectAll(".sharkbabies")
      .data(function(d, i) {
        return d;
      })
      .enter().append('circle')
      .attr("class", "sharkbabies")
      .attr("cx", function(d) {
        return d.x
      })
      .attr("cy", function(d, i) {
        return d.y
      })
      .attr("r", 15)
      .attr("fill", "#81BC00");

  }

这是我针对相同功能的第二种方法(在plunkr中非常有用):

    var nodes = filterNodes('family_common', 'Cow Sharks');
    var matrix = [];

    nodes = $.grep(nodes, function(e) {
      return e.size != 0;
    });

    var i;

    for (i = 0; i < nodes.length; i++) {
      var newarr = [];
      var obj1 = {};
      var obj2 = {};
      obj1['x'] = nodes[i].x + (0.1 * width) * Math.cos((5 * Math.PI) / 4);
      obj2['x'] = nodes[i].x - (0.1 * width) * Math.sin((7 * Math.PI) / 4);
      obj1['y'] = nodes[i].y + (0.1 * width) * Math.cos((5 * Math.PI) / 4);
      obj2['y'] = nodes[i].y + (0.1 * width) * Math.sin((7 * Math.PI) / 4);
      newarr.push(obj1)
      newarr.push(obj2)
      matrix.push(newarr);
      nodes[i]['new'] = newarr;
    }



    var newCircles = g.selectAll(".sharks").data(nodes);


    newCircles.exit()
      .transition()
      .duration(750)
      .attr("r", 0)
      .remove();

    var newCirclesE =
      newCircles.enter().append("circle").attr("class", "sharks")
      .attr("id", function(d) {
        var cname = d.name;
        cname = cname.split(' ');
        return cname[0] + '_' + cname[1];
      })
      .attr("fill", function(d) {
        return colorScale(d.family)
      }).attr("r", function(d) {
        return radiusScale(+d.size);
      })
      .attr('stroke', '');

    var smallCircles = newCircles.merge(newCirclesE)
      .selectAll(".sharkbabies").data(function(d){
        return d.new;
      });

    smallCircles.enter().append('circle')
      .attr("class", "sharkbabies")
      .attr("cx", function(d) {
        return d.x
      })
      .attr("cy", function(d, i) {
        return d.y
      })
      .attr("r", 15)
      .attr("fill", "#81BC00");


    simulation.nodes(nodes)
      .on('tick', ticked);

    simulation.alpha(1).restart();

0 个答案:

没有答案