2017-06-22 139 views
1

我有以下代碼(see jsfiddle here):D3 V4力向圖,矩形

<svg width="600" height="600"></svg> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 
var data = { 
    "nodes":[ 
     { 
     "name":"Abc", 
     "id":"1", 
     "value":"1", 
     "cvr":"123" 
     }, 
     { 
     "name":"Aaa", 
     "id":"2", 
     "value":"0.25", 
     "cvr":"7445" 
     }, 
     { 
     "name":"JTY", 
     "id":"3", 
     "value":"0.25", 
     "cvr":"24582" 
     }, 
     { 
     "name":"TTT", 
     "id":"4", 
     "value":"0.1", 
     "cvr":"12351" 
     }, 
     { 
     "name":"MMM", 
     "id":"5", 
     "value":"0.15", 
     "cvr":"783456" 
     }, 
     { 
     "name":"KLI", 
     "id":"6", 
     "value":"0.05" 
     }, 
     { 
     "name":"OTP", 
     "id":"7", 
     "value":"0.250" 
     }, 
     { 
     "name":"Tasqu", 
     "id":"8", 
     "value":"0.250" 
     }, 
     { 
     "name":"Mii", 
     "id":"9", 
     "value":"0.10" 
     }, 
     { 
     "name":"YrA", 
     "id":"11", 
     "value":"0.150", 
     "cvr":"10096669" 
     }, 
     { 
     "name":"Tarb", 
     "id":"10", 
     "value":"0.1500" 
     } 
    ], 
    "links":[ 
     { 
     "source":"2", 
     "target":"1" 
     }, 
     { 
     "source":"3", 
     "target":"1" 
     }, 
     { 
     "source":"4", 
     "target":"1" 
     }, 
     { 
     "source":"5", 
     "target":"1" 
     }, 
     { 
     "source":"6", 
     "target":"1" 
     }, 
     { 
     "source":"7", 
     "target":"2" 
     }, 
     { 
     "source":"8", 
     "target":"3" 
     }, 
     { 
     "source":"9", 
     "target":"4" 
     }, 
     { 
     "source":"11", 
     "target":"5" 
     }, 
     { 
     "source":"10", 
     "target":"11" 
     } 
    ] 
}; 

// Create somewhere to put the force directed graph 
var svg = d3.select("svg"), 
    width = +svg.attr("width"), 
    height = +svg.attr("height"); 

var rectWidth = 240; 
var rectHeight = 60; 
var minDistance = Math.sqrt(rectWidth*rectWidth + rectHeight*rectHeight); 

// Set up the simulation and add forces 
var simulation = d3.forceSimulation() 
    .nodes(data.nodes); 

var link_force = d3.forceLink(data.links) 
    .id(function(d) { return d.id; }).distance(minDistance).strength(1); 

var charge_force = d3.forceManyBody() 
    .strength(-1000); 

var center_force = d3.forceCenter(width/2, height/2); 

simulation 
    .force("charge_force", charge_force) 
    .force("center_force", center_force) 
    .force("links",link_force); 


// Add tick instructions: 
simulation.on("tick", tickActions); 

// Add encompassing group for the zoom 
var g = svg.append("g") 
    .attr("class", "everything"); 

var div = g.select("body").append("div") 
    .attr("class", "tooltip") 
    .style("opacity", 0); 

// Draw lines for the links 
var link = g.append("g") 
    .attr("class", "links") 
     .selectAll("line") 
     .data(data.links) 
     .enter() 
      .append("line") 
       .attr("stroke-width", 2) 
       .style("stroke", linkColour); 

// Draw rects and texts for the nodes 
var nodes = g.append("g") 
    .attr("class", "nodes"); 

var node = nodes.selectAll("node") 
    .data(data.nodes) 
    .enter() 
     .append("g"); 

node 
    .on("mouseover", function(d) { 
     d3.select(this).select("rect").style("fill", "red"); 
     div.transition() 
      .duration(200) 
      .style("opacity", .9); 
     div.html("asdasd") 
      .style("left", (d3.event.pageX) + "px") 
      .style("top", (d3.event.pageY - 28) + "px"); 
    }) 
    .on("mouseout", function(d) { 
     d3.select(this).select("rect").style("fill", rectColour); 
     div.transition() 
      .duration(500) 
      .style("opacity", 0); 
    }); 


var rect = node.append("rect") 
     .attr("x", -rectWidth/2) 
     .attr("y", -rectHeight/2) 
     .attr("width", rectWidth) 
     .attr("height", rectHeight) 
     .attr("fill", rectColour); 

var textName = node.append("text") 
     .text(function (d) { return d.name; }) 
     .attr("y", -15) 
     .style("text-anchor", "middle"); 

var textCvr = node.append("text") 
     .text(function (d) { return d.cvr; }) 
     .attr("y", 0) 
     .style("text-anchor", "middle"); 

var textOwned = node.append("text") 
     .text(function (d) { return (parseFloat(d.value)*100).toFixed(2)+"%"; }) 
     .attr("y", 15) 
     .style("text-anchor", "middle"); 

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

// Add drag capabilities 
var drag_handler = d3.drag() 
    .on("start", drag_start) 
    .on("drag", drag_drag) 
    .on("end", drag_end); 

drag_handler(node); 

// Add zoom capabilities 
var zoom_handler = d3.zoom() 
    .on("zoom", zoom_actions); 

zoom_handler(svg); 

/** Functions **/ 

function rectColour(d){ 
    if(d.person){ 
     return "blue"; 
    } else { 
     return "pink"; 
    } 
} 

// Function to choose the line colour and thickness 
function linkColour(d){ 
    return "black"; 
} 

// Drag functions 
function drag_start(d) { 
if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
    d.fx = d.x; 
    d.fy = d.y; 
} 

// Make sure you can't drag the rect outside the box 
function drag_drag(d) { 
    d.fx = d3.event.x; 
    d.fy = d3.event.y; 
} 

function drag_end(d) { 
    if (!d3.event.active) simulation.alphaTarget(0); 
    d.fx = null; 
    d.fy = null; 
} 

// Zoom functions 
function zoom_actions(){ 
    g.attr("transform", d3.event.transform) 
} 

function tickActions() { 
    // update node positions each tick of the simulation 
    node.attr("transform", function(d) { 
     return "translate(" + d.x + "," + d.y + ")" 
    }); 
    // update link positions 
    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; }); 
    } 
</script> 

我想有矩形彼此更接近垂直,同時水平地保持相同的距離。

如何更改它,使得在x軸的最小距離是根據「rectWidth」,而在y軸的最小距離是根據「rectHeight」?另外,它們不應該能夠對角重疊。

回答

1

你應該改變你的模擬像這樣:

simulation 
    .force("charge_force", charge_force) 
    .force("center_force", center_force) 
    .force("links",link_force) 
    .force('y', d3.forceY(height/2).strength(0.10)); 

基本上,它會增加重力爲Y軸,但不是爲X軸。 https://github.com/d3/d3-force/blob/master/README.md#forceY

更新小提琴:在

更多信息https://jsfiddle.net/oesgnzho/3/

+0

這至少在正確的方向,但現在的矩形排序的橫向傳播。它們不能垂直堆疊。另外,嘗試在中心節點上方放置一個矩形時仍會產生巨大的空白。我想我想做的事情有點複雜。 –

+0

好吧,我的想法,但是我沒有答案。這就是我不喜歡的矩形節點。將盡力檢查我有空時間。我認爲我們必須玩鏈接距離,鏈接強度或其他東西。我會盡力在文檔中找到一條線索。 –