我想用 d3.js 这样绘制一个简单的图表
我无法在v5 API文档和Internet上找到图形布局。
所有示例都使用d3-force中的d3.force
布局。虽然它看起来令人印象深刻,但我并不是在寻找带有物理模拟的图形布局。
是否有更简单的布局,或者是关闭物理时使用d3.force
布局的最佳方法?
答案 0 :(得分:1)
没有必要使用d3.forceSimulation
,这最终只是提供的众多D3布局中的一种。如果您查看Mike Bostocks示例Force Directed Graph,那么您需要的修改如下:
nodes
- 基本上是一组代表圆圈的事物svg:circle
.data(nodes)
元素附加到DOM
links
svg:line
.data(links)
元素附加到DOM
醇>
这主要是使用D3
进行纯DOM数据绑定,而不使用预先构建的布局。
你可以真正复制任何力量示例 - 它在下面做的只是在下方设置x
和y
位置。如果你已经有了这些,只需将你的圈子定位在这些点上。
您可以从示例中删除与simulation
和ticked
事件相关的所有部分。
以下是提供静态布局的示例:
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20);
const layout = (graph) => {
return new Promise((resolve) => {
var simulation = d3
.forceSimulation()
.alphaMin(0.3)
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.on("end", resolve(graph));
simulation.nodes(graph.nodes);
simulation.force("link").links(graph.links);
});
};
const render = (graph) => {
var link = d3.select("#target").append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) { return Math.sqrt(d.value); })
.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; });
var node = d3.select("#target").append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("fill", function(d) { return color(d.group); });
}
d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/5916d145c8c048a6e3086915a6be464467391c62/miserables.json", function(error, graph) {
if (error) throw error;
layout(graph)
.then((graph) => render(graph));
});

.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="600">
<g id="target" transform="translate(480, 300)">
</g>
</svg>
&#13;
修改强>
要更改节点之间的距离,您需要更改播放中的某些力。文档真的很好 - 特别是你要改变的是https://github.com/d3/d3-force#many-body
因此,请将charge
力量修改为:
.force("charge", d3.forceManyBody().strength(-charge))
你需要定义电荷,稍微调整一下,直到力量为你提供良好的布局。