如何在 JavaScript 中绘制图形或树结构?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16058073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I draw a graph or tree structure in JavaScript?
提问by Alexey
I need to be able to draw graphs like the following in JavaScript:
我需要能够在 JavaScript 中绘制如下图:
I know about the Raphaellibrary, but it's only for drawing arbitrary shapes.
我知道Raphael库,但它仅用于绘制任意形状。
I have a few predefined node types (the colored nodes on the image) and text nearby/inside every node. This library doesn't seem to handle that case. How do I do this in JavaScript? If this has been accomplished already by another library, how can I use that library to solve this problem?
我有一些预定义的节点类型(图像上的彩色节点)和每个节点附近/内部的文本。这个库似乎不处理这种情况。我如何在 JavaScript 中做到这一点?如果这已经由另一个库完成,我该如何使用该库来解决这个问题?
回答by Ian
The web is a fast moving world, and so this answer was somewhat out of date. With that in mind, I've refreshed this answer to make it applicable in 2016.
网络是一个快速发展的世界,所以这个答案有点过时了。考虑到这一点,我更新了这个答案,使其适用于 2016 年。
- D3.js- This would still be my recommendation. It's under active development and has a vibrant community.
- Vega- An expressive language (less powerful than D3)
- Cytoscape.js
- Spring.js
- cola.js
- D3.js-这仍然是我的推荐。它正在积极开发中,并拥有一个充满活力的社区。
- Vega-一种表达性语言(不如 D3 强大)
- Cytoscape.js
- Spring.js
- 可乐.js
I would add that I've only used D3.js
in this new list, it's power and flexibility are such that I've never needed to find an alternative. Here is an example implementation of a force directed.
我想补充一点,我只D3.js
在这个新列表中使用过,它的强大功能和灵活性让我从来不需要寻找替代品。下面是一个力的实现示例。
var width = 960,
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("https://gist.githubusercontent.com/mbostock/4062045/raw/4176c7d0c0c5ce15630d16072da0af67bb50eb6a/miserables.json", function(error, graph) {
if (error) throw error;
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.group); })
.call(force.drag);
node.append("title")
.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("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
There are a number of libraries for drawing this sort of output in a browser, you've mentioned Raphael, others include:
有许多库可用于在浏览器中绘制此类输出,您提到了 Raphael,其他包括:
- Sigma.js
- Processing.js
- jit.js- Sold to SenchaLabs. The solo developer appeared to stop working on it.
- D3.js
- Raphael.js - Seems to have disappeared, their main site has gone
I personally would recommend the latter, D3 depending on the number of items you wish to display and the browser support you need as it's well documented, powerful and faily easy to use. Check out this Github project for an example of a force-directed library.
我个人会推荐后者,D3,这取决于您希望显示的项目数量和您需要的浏览器支持,因为它有据可查、功能强大且易于使用。查看此Github 项目以获取强制导向库的示例。
The changes that you would need to make to accomplish the task you've set out would be to:
为了完成您设定的任务,您需要进行以下更改:
1) Change where the data is coming from by modifying the following function:
1)通过修改以下函数来改变数据的来源:
d3.json("flare.json", function(json) {
root = json;
root.fixed = true;
root.x = w / 2;
root.y = h / 2 - 80;
update();
});
Change the d3.json("flare.json")
to point to a different file/URL on your server. It is possible to do the same thing with jQuery if you wished and use a similar callback approach.
将 更改d3.json("flare.json")
为指向服务器上的不同文件/URL。如果您愿意并使用类似的回调方法,可以使用 jQuery 做同样的事情。
2) To colour your nodes based on different categories you'll want to change the following section:
2) 要根据不同类别为节点着色,您需要更改以下部分:
// Update the nodes…
node = vis.selectAll("circle.node")
.data(nodes, function(d) { return d.id; })
.style("fill", color);
Change the .style("fill", color);
to something along the lines of:
将其更改.style("fill", color);
为以下内容:
.style("fill", function(d) {
switch(d.category) {
case A: return "#FF0000";
case B: return "#00FF00";
default: return "#0000FF";
}
});
Where category is a property on the JSON data object that you want to vary by.
其中 category 是 JSON 数据对象上您想要改变的属性。