2016-04-05 10 views
1

以下のD3 Force Layoutの例では、単純なデータ構造を使用しています。D3 Geom Hullによる強制的なレイアウト

var data = { 
    "nodes":[ 
    {"name":"Register", group: 1, "frequency": 1103}, 
    {"name":"Analyze Defect", group: 1, "frequency": 2206}, 
    {"name":"Repair (Complex)", group: 2, "frequency": 1447}, 
    {"name":"Test Repair", group: 2, "frequency": 3012}, 
    {"name":"Inform User", group: 2, "frequency": 1101}, 
    {"name":"Archive Repair", group: 2, "frequency": 999}, 
    {"name":"Repair (Simple)", group: 3, "frequency": 1568}, 
    {"name":"Restart Repair", group: 3, "frequency": 405} 
    ], 
    "arcs":[ 
     { 
      "source": "Register", 
      "target": "Analyze Defect", 
      "frequency": 2206, 
      "dependency": 0 
     }, 
     { 
      "source": "Register", 
      "target": "Repair (Complex)", 
      "frequency": 1447, 
      "dependency": 0 
     }, 
     { 
      "source": "Register", 
      "target": "Test Repair", 
      "frequency": 3012, 
      "dependency": 0 
     }, 
     { 
      "source": "Archive Repair", 
      "target": "Inform User", 
      "frequency": 1101, 
      "dependency": 0 
     }, 
     { 
      "source": "Register", 
      "target": "Archive Repair", 
      "frequency": 999, 
      "dependency": 0 
     }, 
     { 
      "source": "Register", 
      "target": "Repair (Simple)", 
      "frequency": 1568, 
      "dependency": 0 
     }, 
     { 
      "source": "Register", 
      "target": "Restart Repair", 
      "frequency": 405, 
      "dependency": 0 
     } 
    ] 
}; 

var width = 800, 
    height = 400; 
var color = d3.scale.category20(); 

var force = d3.layout.force() 
    .size([width, height]) 
    .linkDistance(100) 
    .charge(-300) 
    .start(); 

var svg = d3.select("#main-content").append("svg") 
    .attr("width", width) 
    .attr("height", height); 


    var nodes = data.nodes; 
    var links = data.arcs; 
    var pathtype = []; 

    // Compute the distinct nodes from the links. 
    links.forEach(function(link) { 
    link.source = nodes[link.source] || (nodes[link.source] = { 
     name: link.source 
    }); 
    link.target = nodes[link.target] || (nodes[link.target] = { 
     name: link.target 
    }); 

    pathtype.push(link.dependency); 

    }); 
    console.log(pathtype); 
    force 
    .nodes(d3.values(nodes)) 
    .links(links) 
    .on("tick", tick) 
    .start(); 

    svg.append("defs").selectAll("marker") 
    .data(pathtype) 
    .enter().append("marker") 
    .attr("id", function(d) { 
     return d; 
    }) 
    .attr("viewBox", "0 -5 10 10") 
    .attr("refX", 25) 
    .attr("refY", -1.5) 
    .attr("markerWidth", 6) 
    .attr("markerHeight", 6) 
    .attr("orient", "auto") 
    .append("path") 
    .attr("d", "M0,-5L10,0L0,5"); 

    var path = svg.append("g").selectAll("path") 
    .data(force.links()) 
    .enter().append("path") 
    .attr("class", function(d) { 
     return "link " + d.dependency; 
    }) 
    .attr("marker-end", function(d) { 
     return "url(#" + d.dependency + ")"; 
    }); 

    var circle = svg.append("g").selectAll("circle") 
    .data(force.nodes()) 
    .enter().append("circle") 
    .attr("r", 15) 
    .call(force.drag); 

    var text = svg.append("g").selectAll("text") 
    .data(force.nodes()) 
    .enter().append("text") 
    .attr("x", 15) 
    .attr("y", ".31em") 
    .text(function(d) { 
     return d.name; 
    }); 

    // Use elliptical arc path segments to doubly-encode directionality. 
    function tick() { 
    path.attr("d", linkArc); 
    circle.attr("transform", transform); 
    text.attr("transform", transform); 
    } 

    function linkArc(d) { 
    var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = Math.sqrt(dx * dx + dy * dy); 
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
    } 

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

https://jsfiddle.net/n6q0L5fu/8/

私は、この例に示すように、ハルの機能を使用する機能をグループ化する追加する必要があります。 http://jsfiddle.net/y4amnsbn/

データサンプルでグループ変数を使用し、ノードをグループ化するためにHull機能を使用するためにD3の例を取得するには、何が必要ですか?

編集

私は一例に次のコードを追加しましたが、それはまだグループ化をレンダリングしません:

var groups = d3.nest().key(function(d) { return d.group;}).entries(nodes); 

var groupPath = function(d) { 
    var fakePoints = []; 
    if (d.values.length > 2) { 
     //[dx, dy] is the direction vector of the line 
     var dx = d.values[1].x - d.values[0].x; 
     var dy = d.values[1].y - d.values[0].y; 

     //scale it to something very small 
     dx *= 0.00001; 
     dy *= 0.00001; 

     //orthogonal directions to a 2D vector [dx, dy] are [dy, -dx] and [-dy, dx] 
     //take the midpoint [mx, my] of the line and translate it in both directions 
     var mx = (d.values[0].x + d.values[1].x) * 0.5; 
     var my = (d.values[0].y + d.values[1].y) * 0.5; 
     fakePoints = [ 
     [mx + dy, my - dx], 
     [mx - dy, my + dx] 
     ]; 
     //the two additional points will be sufficient for the convex hull algorithm 

     //do not forget to append the fakePoints to the input data 
     var point = "M" + 
     d3.geom.hull(d.values.map(function(i) { 
      return [i.x, i.y]; 
      }) 
      .concat(fakePoints)) 
     .join("L") + "Z"; 
     return point; 
    } 

    function tick() { 
    svg.selectAll("path") 
     .data(groups) 
     .attr("d", groupPath) 
     .enter().insert("path", "circle") 
     .style("fill", "green") 
     .style("stroke", "green") 
     .style("stroke-width", 40) 
     .style("stroke-linejoin", "round") 
     .style("opacity", .2); 
     } 
    } 

答えて

0

私は同じ問題に遭遇した、ここでの例です。 スクリプトを完全には使用しませんが、コード内で再利用できるように、同じデータ構造を提供します。

var width = 960, 
    height = 500 

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

hullg = svg.append("g"); 

var force = d3.layout.force() 
    .gravity(0.05) 
    .distance(100) 
    .charge(-50) 
    .size([width, height]); 

    force 
     .nodes(json.nodes) 
     .links(json.links) 
     .start(); 

    var link = svg.selectAll(".link") 
     .data(json.links) 
     .enter().append("line") 
     .attr("class", "link"); 

    var groups = d3.nest().key(function(d) { return d.group }).entries(json.nodes); 
    var groupPath = function(d) { 
    return "M" + 
     d3.geom.hull(d.values.map(function(i) { return [i.x, i.y]; })) 
     .join("L") 
    + "Z"; 
    }; 
    var groupFill = function(d, i) { return 111 }; 

    var node = svg.selectAll(".node") 
     .data(json.nodes) 
    .enter().append("g") 
     .attr("class", "node") 
     .call(force.drag); 

    node.append("image") 
     .attr("xlink:href", "https://github.com/favicon.ico") 
     .attr("x", -8) 
     .attr("y", -8) 
     .attr("width", 16) 
     .attr("height", 16); 

    node.append("text") 
     .attr("dx", 12) 
     .attr("dy", ".35em") 
     .text(function(d) { return d.name }); 

    force.on("tick", function() { 
    link.attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

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

    hullg.selectAll("path") 
    .data(groups) 
     .attr("d", groupPath) 
    .enter().insert("path", "circle") 
     .style("fill", "#235") 
     .style("stroke", "#235") 
     .style("stroke-width", 40) 
     .style("stroke-linejoin", "round") 
     .style("opacity", .2) 
     .attr("d", groupPath);  
    }); 

この例の完全なソースコードが入手可能であるhere

関連する問題