如何重新定位节点并将其转换为另一个焦点?

时间:2019-02-14 07:26:19

标签: d3.js force-layout

我是D3的新手,并且喜欢它,到目前为止,我正在使用多焦点力布局,并得到了我想做得很好的一部分,我想知道是否可以重新定位某些节点根据时间范围。
我的意思是,目前您所看到的是我创建的fiddle中的6(橙色),5(蓝色)和3(绿色)节点,所以我希望它们通过彼此平移来定位自己第二天的数据可能是5(橙色),6(蓝色)和4(绿色),这意味着一个橙色节点移到绿色簇。

var data = [
  {"id": 0, "name": "x", "r":5 },
  {"id": 0, "name": "x", "r":5 },
  {"id": 0, "name": "x", "r":5 },
  {"id": 0, "name": "x", "r":5 },
  {"id": 0, "name": "x", "r":5 },

  {"id": 1, "name": "y", "r":5 },
  {"id": 1, "name": "y", "r":5 },
  {"id": 1, "name": "y", "r":5 },
  {"id": 1, "name": "y", "r":5 },
  {"id": 1, "name": "y", "r":5 },
  {"id": 1, "name": "y", "r":5 },

  {"id": 2, "name": "z", "r":5 },
  {"id": 2, "name": "z", "r":5 },
  {"id": 2, "name": "z", "r":5 },
];

var width = window.innerWidth,
    height = 410;

var fill = d3.scale.category10();

var nodes = [], labels = [],
    foci = [{x: 0, y: 10}, {x: 100, y: 210}, {x: 600, y: 210}];

var svg = d3.select("body").append("svg")
    .attr("width", "100%")
    .attr("height", height)
    //.attr("domflag", '');

var force = d3.layout.force()
    .nodes(nodes)
    .links([])
    .charge(-10)
    //.chargeDistance(100)
    .gravity(0.1)
    .friction(0.8)
    .size([width, height])
    .on("tick", tick);

//var node = svg.selectAll("circle");
var node = svg.selectAll("g");

var counter = 0;

function tick(e) {
  var k = .1 * e.alpha;

  // Push nodes toward their designated focus.
  nodes.forEach(function(o, i) {
    o.y += (foci[o.id].y - o.y) * k;
    o.x += (foci[o.id].x - o.x) * k;
  });

  node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

}


var timer = setInterval(function(){

  if (nodes.length > data.length-1) { clearInterval(timer); return;}

  var item = data[counter];
  nodes.push({id: item.id, r: item.r, name: item.name});
  force.start();

  node = node.data(nodes);

  var n = node.enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
      .style('cursor', 'pointer')
      .on('mousedown', function() {
         var sel = d3.select(this);
         //``sel.moveToFront();
      })
      .call(force.drag);

  n.append("circle")
      .attr("r",  function(d) { return d.r; })
      .style("fill", function(d) { return fill(d.id); })

  n.append("text")
      .text(function(d){
          return d.name;
      })
      .style("font-size", function(d) {
          return Math.min(2 * d.r, (2 * d.r - 8) / this.getComputedTextLength() * 16) + "px"; 
       })
      .attr("dy", ".35em")

  counter++;
}, 100);
node {
    stroke-width: 1.5px;
  }
  .node:hover circle {
    fill: grey !important;
  }
  
  text {
    font: 18px 'Open Sans', sans-serif;;
    text-anchor: middle;
    pointer-events: none;
    fill: white;
  }
  circle {
    fill: #ccc;
    stroke: white ;
    stroke-width: 2px;
  }
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>
<h2>D3.js Multi-Foci Force layout </h2>

我在这里创建了fiddle
我想知道的是如何将节点转换为另一个群集并格式化数据以在时间中循环。
我正在使用D3 V3进行开发。

0 个答案:

没有答案