我的数据库中存储了一个 RBAC 结构(使用 Yii 构建的项目)。
我很想生成一个图表来可视化项目之间的关系,看看我是否没有犯逻辑错误,并向其他团队成员展示。
我正在考虑创建一个可以生成图形/树的页面。我想我可以处理服务器端部分,但我不知道如何生成 HTML/CSS(或图像)。
图中的节点可以有多个子节点和多个父节点。箭头指向。例子:
我不介意使用最新的 CSS3 和 HTML5 技术,因为它只会被选定的人使用。
我的数据库中存储了一个 RBAC 结构(使用 Yii 构建的项目)。
我很想生成一个图表来可视化项目之间的关系,看看我是否没有犯逻辑错误,并向其他团队成员展示。
我正在考虑创建一个可以生成图形/树的页面。我想我可以处理服务器端部分,但我不知道如何生成 HTML/CSS(或图像)。
图中的节点可以有多个子节点和多个父节点。箭头指向。例子:
我不介意使用最新的 CSS3 和 HTML5 技术,因为它只会被选定的人使用。
不久前我遇到了类似的问题。我最终提出的解决方案是一个完美的小 js 库,即 Dracula。
这是图书馆的链接:https ://github.com/strathausen/dracula
考虑到您的需求,您所要做的就是:
var g = new Graph();
g.addEdge('author', 'create');
g.addEdge('author', 'reader');
g.addEdge('author', 'admin');
// add here the other edges.
var layouter = new Graph.Layout.Spring();
layouter.layout();
var renderer = new Graph.Renderer.Raphael('#canvas', g, 400, 300);
renderer.draw();
有关更多信息,我会让您在文档中挣扎。
希望能帮助到你。
[附录]
我要补充一点,一般来说,显示节点和箭头的问题不是什么大问题,使用 svg 使它几乎是微不足道的。但是,当您想要使用诸如“尽量减少交叉边的数量”、“在父级下方显示子级”等规则来组织节点的显示时,事情会变得复杂,这些都需要复杂的数学运算。
我不认为 Dracula 允许自定义那种规则。不过,考虑到您的评论,我认为可能有一种不太复杂的方法可以使布局看起来像垂直树,因为它是一个无环图(至少看起来是)。但是,您将不得不为此创建自己的库。
使用SVG怎么样?SVG 可以通过 CSS 设置样式,通过 Javascript 访问并嵌入到 HTML 文档中。并且使用矢量格式似乎足以用于图形可视化,因为它具有许多优点。只有一个优势——尤其是在 Web 环境中——是与位图图像相比,大图的文件大小更小。
对于图形可视化本身,我们想到了Graphviz 。它是一个图形渲染软件/库,自 1988 年以来一直在积极开发。它能够渲染各种类型的图形并将生成的图像导出为包括SVG在内的各种图像格式。它使用所谓的“点语言”来描述图形。查看 Graphviz项目页面以查找有关 dot 语言的许多示例和文档。
你有没有dot
在命令行上进行过实验?dot
是来自 Graphviz 包的二进制文件,它读取以点语言编写的文件并将它们呈现为所需的图像格式。这是一个很好的实验起点。
我曾经用它来动态绘制 PHP 类图。我在 php 中生成了一个 .dot 文件,并使用exec dot -Tsvg graph.dot
在 PEAR 存储库中还有一个用于 GraphViz 的 PHP 包装库,名为Image_Graphviz,它用于与您的类似项目中。
当然,如果您使用通用图形绘图库与手动绘制它们相比,您将不得不做出一些布局妥协。但是,当您熟悉点语言时,您将获得最佳结果。
只需尝试以下内容。
图是最常用的数据结构之一,还有链表和树。在最近的一个 PHP 项目中,我需要构建一个 Graph 结构来分析一些相互关联的 url。这个问题很简单,所以我没有编写自己的代码,而是选择了 Pear 存储库中可用的代码。
Pear Structures_Graph 包允许创建和操作图形数据结构。它允许构建有向或无向图,数据和元数据存储在节点中。该库提供了用于图遍历以及从图拓扑中提取特征的函数。
另请参阅以下位置: http: //www.codediesel.com/algorithms/building-a-graph-data-structure-in-php/
一些示例代码:
<?php
require_once 'Structures/Graph.php';
require_once 'Structures/Graph/Node.php';
$nonDirectedGraph = new Structures_Graph(false);
$nodes_names = array('a', 'b', 'c' ,'d', 'e');
$nodes = array();
foreach($nodes_names as $node) {
/* Create a new node / vertex */
$nodes[$node] = new Structures_Graph_Node();
/* Add the node to the Graph structure */
$nonDirectedGraph ->addNode($nodes[$node]);
}
/**
* Specify connections between different nodes.
* For example in the following array, 'a-b'
* specifies that node 'a' is connected to node 'b'.
* Also refer to the figure above.
*/
$vertices = array('a-b', 'b-c', 'b-d', 'd-c', 'c-e', 'e-d');
foreach($vertices as $vertex) {
$data = preg_split("/-/",$vertex);
$nodes[$data[0]]->connectTo($nodes[$data[1]]);
}
?>
如果您可以在服务器端使用 Python,您可以使用Networkx生成高质量的图形并将它们保存为 SVG、PNG 或任何您喜欢的格式。