2016-08-18 2 views
0

ich mit d3.js neu bin, was ich versuche zu tun, die Nähe dieses: http://codepen.io/fabiobiondi/pen/nFxyDGriff kollidieren mit einer d3.js Mehr Brennpunkten Kraft Layout

// GROUPS: 0 Web | 1: Adobe | 2: hybrid 
var data = [ 
    {"id": 0, "name": "AngularJS", "r": 50 }, 
    {"id": 0, "name": "HTML5", "r": 40 }, 
    {"id": 0, "name": "Javascript", "r": 30 }, 
    {"id": 0, "name": "NodeJs", "r": 30 }, 
    {"id": 0, "name": "D3.js", "r": 40 }, 
    {"id": 0, "name": "CreateJS", "r": 45 }, 
    {"id": 0, "name": "Cordova", "r": 40 }, 
    {"id": 0, "name": "CSS", "r": 40 }, 
    {"id": 0, "name": "SVG", "r": 20 }, 
    {"id": 0, "name": "PHP", "r": 20 }, 
    {"id": 0, "name": "jQuery", "r": 30 }, 

    {"id": 1, "name": "Actionscript", "r": 50 }, 
    {"id": 1, "name": "Flash", "r": 32 }, 
    {"id": 1, "name": "Flex", "r": 50 }, 
    {"id": 1, "name": "AIR", "r": 40 }, 
    {"id": 1, "name": "Photoshop", "r": 30 }, 
    {"id": 1, "name": "Illustrator", "r": 30 }, 

    {"id": 2, "name": "Node Webkit", "r": 40 }, 
    {"id": 2, "name": "Chrome App", "r": 30 }, 
    {"id": 2, "name": "Cordova", "r": 45 }, 
]; 

var width = window.innerWidth, 
    height = 450; 

var fill = d3.scale.category10(); 

var nodes = [], labels = [], 
    foci = [{x: 0, y: 150}, {x: 350, y: 150}, {x: 200, y: 150}]; 

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

var force = d3.layout.force() 
    .nodes(nodes) 
    .links([]) 
    .charge(-400) 
    //.chargeDistance(200) 
    .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); 


d3.selection.prototype.moveToFront = function() { 
    return this.each(function(){ 
    this.parentNode.appendChild(this); 
    }); 
}; 

function resize() { 
    width = window.innerWidth; 
    force.size([width, height]); 
    force.start(); 
} 

d3.select(window).on('resize', resize); 

Was ich nicht verstehe, ist Wie kann ich kontrollieren, wie die Kreise kollidieren können oder nicht.

Ich habe versucht kollidieren Funktion wie diese https://bl.ocks.org/mbostock/1804919, aber ich verstehe nicht, wie es funktioniert. Wenn ich den Füllwert ändere, vermeiden Kreise sich selbst. Was ich möchte ist kollidieren zu lassen, aber nicht zu viel (sagen wir 10px), um sicher zu sein, dass der Text darin niemals versteckt ist.

Antwort

1

Ich habe dieses Beispiel implementiert: https://bl.ocks.org/mbostock/7881887

ich hinzugefügt, um die Kollisionsfunktion:

// Resolves collisions between d and all other circles. 
function collide(alpha) { 
    var quadtree = d3.geom.quadtree(nodes); 
    return function(d) { 
    //console.log(d) 
    var r = d.r + maxRadius + Math.max(padding, clusterPadding), 
     nx1 = d.x - r, 
     nx2 = d.x + r, 
     ny1 = d.y - r, 
     ny2 = d.y + r; 
    quadtree.visit(function(quad, x1, y1, x2, y2) { 
     if (quad.point && (quad.point !== d)) { 
     var x = d.x - quad.point.x, 
      y = d.y - quad.point.y, 
      l = Math.sqrt(x * x + y * y), 
      r = d.r + quad.point.r + (d.cluster === quad.point.cluster ? padding : clusterPadding); 
     if (l < r) { 
      l = (l - r)/l * alpha; 
      d.x -= x *= l; 
      d.y -= y *= l; 
      quad.point.x += x; 
      quad.point.y += y; 
     } 
     } 
     return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
    }); 
    }; 
} 

Dies alles in den oberen Link erklärt wird, so hier muss ich gewohnt erklären.

Im Beispiel seine d.radius aber Sie haben d.r.Also die maxRadius, die ich so gearbeitet:

var maxRadius = data.reduce(function(sum, d){ 
    return Math.max(sum,d.r) 
}, 0); //get maximum radius 

Die oben die Datenanordnung reduziert und erhält den größten Wert von r (Radius). Das sind die einzigen Änderungen, die ich gemacht habe.

Und ich habe Ihre tick-Funktion aktualisiert:

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

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

    node 
    .each(collide(.5)) //call collide function here 
    .attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }) 
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

} 

Diese kümmert sich um die Mehr Brennpunkte Sie hatten und die Kollisionserkennung.

Aktualisiert Geige: https://jsfiddle.net/thatOneGuy/392kwuru/

+0

ich die Zeit Geige alle verwenden und wie das Layout codepen nicht, nur wenn youre fragen, warum ich das ging an :) Hoffe, dass – thatOneGuy

+0

Danke soviel hilft, kann ich nicht sagen, Ich habe es bisher verstanden, aber ich bekomme was ich will, wenn ich einen negativen Wert auf Padding umstelle. Ich habe dieses andere Beispiel studiert: https://bl.ocks.org/mbstock/2990a882e007f8384b04827617752738, ist es nicht einfacher, es mit v4 zu machen? – sam

Verwandte Themen