javascript – d3js拖动圈应该重新排列主边界圈中的其他圈子

前端之家收集整理的这篇文章主要介绍了javascript – d3js拖动圈应该重新排列主边界圈中的其他圈子前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有基于 this tutorial的气泡图.

我已经使用以下代码启用了气泡的拖动.这使得个别圈子可以拖动,但是在拖动圈子时,其他圈子不会自动调整.我使用的是包圆算法,请让我知道这个算法是可能的.

这是我的拖拽代码

// draggable
if(this.dragging){
    var drag = d3.behavior.drag()
    .on("drag",function( d,i) {
        var selection = d3.selectAll( '.selected');

        if( selection[0].indexOf( this)==-1) {
            selection.classed( "selected",false);
            selection = d3.select( this);
            selection.classed( "selected",true);
        } 

        selection.attr("transform",i) {
            d.x += d3.event.dx;
            d.y += d3.event.dy;
            return "translate(" + [ d.x,d.y ] + ")"
        })
        // reappend dragged element as last 
        // so that its stays on top 
        this.parentNode.appendChild( this);
        d3.event.sourceEvent.stopPropagation();
    });
    node.call( drag);
}

解决方法

这里有一些代码可能会达到您要查找的效果.这主要归功于Mike Bostock的 Bubble ChartCollision Detection示例.

这使用D3的pack layout来初始定位节点.然后,force layout用于在拖动节点时“自动调整”其他圆.

Working example at bl.ocks.org

var width = 900;
var height = 500;

var svg = d3.select("body").append("svg")
    .attr("width",width)
    .attr("height",height);

var nodes = d3.range(128).map(function () { return {radius: Math.random() * 16 + 8}; });
var nodesCopy = $.extend(true,[],nodes);

function dblclick(d) {
  d3.select(this).classed("fixed",d.fixed = false);
}

function dragstart(d) {
  d3.select(this).classed("fixed",d.fixed = true);
}

function collide(node) {
  var r = node.radius + 16;
  var nx1 = node.x - r;
  var nx2 = node.x + r;
  var ny1 = node.y - r;
  var ny2 = node.y + r;
  return function (quad,x1,y1,x2,y2) {
    if (quad.point && (quad.point !== node)) {
      var x = node.x - quad.point.x;
      var y = node.y - quad.point.y;
      var l = Math.sqrt(x * x + y * y);
      var npr = node.radius + quad.point.radius;
      if (l < npr) {
        l = (l - npr) / l * 0.5;
        x *= l;
        node.x -= x;
        y *= l;
        node.y -= y;
        quad.point.x += x;
        quad.point.y += y;
      }
    }
    return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
  };
}

function packup() {
  var pack = d3.layout.pack()
      .sort(null)
      .size([width,height])
      .padding(0)
      .value(function (d) { return d.radius; });

  svg.selectAll(".node")
      .data(pack.nodes({"children": nodes})
      .filter(function (d) { return !d.children; }))
    .enter().append("circle")
      .attr("r",function (d) { return d.radius; })
      .attr("cx",function (d) { return d.x; })
      .attr("cy",function (d) { return d.y; });
}

function forceup() {
  var force = d3.layout.force()
      .nodes(nodes)
      .gravity(0.05)
      .charge(0)
      .size([width,height])
      .start();

  var drag = force.drag().on("dragstart",dragstart);

  force.on("tick",function () {
    var q = d3.geom.quadtree(nodes);
    var i = 0;
    var n = nodes.length;

    while (++i < n) {
      q.visit(collide(nodes[i]));
    }

    svg.selectAll("circle")
        .attr("cx",function (d) { return d.x; })
        .attr("cy",function (d) { return d.y; });
  });

  d3.selectAll("circle")
    .on("dblclick",dblclick)
    .call(drag);
}

function reset() {
  svg.selectAll("*").remove();
  nodes = $.extend(true,nodesCopy);
  packup();
  forceup();
}

packup();
forceup();
原文链接:https://www.f2er.com/js/154453.html

猜你在找的JavaScript相关文章