在下面的力导向图中,我希望矩形在垂直方向上彼此靠近,同时保持水平相同的距离:
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; });
}

<svg width="600" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
如何更改它,使x轴上的最小距离基于rectWidth
,而y轴上的最小距离基于rectHeight
?此外,它们不应该对角重叠。
答案 0 :(得分: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));
基本上它会增加Yaxis的重力,但不会增加Xaxis的重力。
有关以下内容的更多信息:https://github.com/d3/d3-force/blob/master/README.md#forceY