如何在JavaScript中绘制图形或树结构? [英] How do I draw a graph or tree structure in JavaScript?

查看:189
本文介绍了如何在JavaScript中绘制图形或树结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够在JavaScript中绘制如下图形:

I need to be able to draw graphs like the following in JavaScript:

我知道 Raphael 库,但它只适用于绘制任意形状。

I know about the Raphael library, but it's only for drawing arbitrary shapes.

我有几个预定义的节点类型(图像上的彩色节点)和每个节点附近/内部的文本。这个库似乎不处理这种情况。我如何在JavaScript中这样做?如果这已经由另一个库完成,我该如何使用该库来解决这个问题?

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?

推荐答案

快速移动的世界,所以这个答案有点过时。考虑到这一点,我刷新了这个答案,使其在2016年适用。

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.

  • 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 在这个新的名单,它的力量和灵活性是这样的,我从来没有需要找到一个替代品。以下是强制引导的示例实现。

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.

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>

有许多库可在浏览器中绘制此类输出您提到Raphael,其他人包括:

There are a number of libraries for drawing this sort of output in a browser, you've mentioned Raphael, others include:

  • 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

我个人会推荐后者,D3取决于您希望显示的项目数量和您需要的浏览器支持,因为它有良好的文档,强大和失败易于使用。请查看此 Github项目以获取强制导向库的示例

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.

完成您所设定的任务需要进行的更改为:

The changes that you would need to make to accomplish the task you've set out would be to:

1)通过修改以下函数更改数据的来源:

1) Change where the data is coming from by modifying the following function:

d3.json("flare.json", function(json) {
   root = json;
   root.fixed = true;
   root.x = w / 2;
   root.y = h / 2 - 80;
   update();
 });

更改 d3.json(flare.json)指向服务器上的其他文件/ URL。

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.

2)如果你希望使用类似的回调方法,你可以使用jQuery做同样的事情。更改以下部分:

2) To colour your nodes based on different categories you'll want to change the following section:

// Update the nodes…
  node = vis.selectAll("circle.node")
      .data(nodes, function(d) { return d.id; })
      .style("fill", color);

更改 .style(fill,color); 到以下行:

.style("fill", function(d) { 
    switch(d.category) {
       case A: return "#FF0000";
       case B: return "#00FF00";
       default: return "#0000FF";
    }
});

其中category是JSON数据对象上要更改的属性。

Where category is a property on the JSON data object that you want to vary by.

这篇关于如何在JavaScript中绘制图形或树结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆