graphp/graphviz

为数学图/网络库 GraPHP 提供的 GraphViz 图绘制。

v0.2.2 2019-10-04 13:30 UTC

This package is auto-updated.

Last update: 2024-09-16 09:22:53 UTC


README

CI status

为数学图/网络库 GraPHP 提供的 GraphViz 图绘制。

开发版本:此分支包含即将推出的 1.0 版本的代码。对于当前稳定版 0.2 的代码,请检查 0.2.x 分支

即将推出的 1.0 版本将是此包的发展方向。但是,我们仍将积极支持 0.2.x,以支持尚未升级到最新版本的用户。有关更多详细信息,请参阅 安装说明

该库支持可视化图形图像,包括将它们包含在网页中,在 CLI 应用程序中打开图像,并将它们导出为 PNG、JPEG 或 SVG 格式(以及其他许多格式)。由于 图绘制 是一个复杂的领域,实际的布局由优秀的 GraphViz "Graph Visualization Software" 承担,我们仅提供一些方便的 API 来与 GraphViz 接口。

目录

快速入门示例

安装后,让我们构建并显示一个示例图

$graph = new Graphp\Graph\Graph();

$blue = $graph->createVertex();
$blue->setAttribute('id', 'blue');
$blue->setAttribute('graphviz.color', 'blue');

$red = $graph->createVertex();
$red->setAttribute('id', 'red');
$red->setAttribute('graphviz.color', 'red');

$edge = $graph->createEdgeDirected($blue, $red);
$edge->setAttribute('graphviz.color', 'grey');

$graphviz = new Graphp\GraphViz\GraphViz();
$graphviz->display($graph);

上述代码将以以下图像打开您的默认图像查看器

red-blue

请参阅 示例

属性

GraphViz 支持图实例本身的一些属性,以及每个顶点实例(GraphViz 称之为“节点”)和边实例。此库支持 GraphViz 的任何这些属性,并必须使用以下文档中所述的 GraPHP 属性进行分配。

有关所有 GraphViz 属性的完整列表,请参阅 GraphViz 文档

请注意,所有属性都使用 UTF-8 编码(Unicode),并且默认情况下将引用和转义,因此 ö> 将按原样出现,不会被视为 HTML。有关更多详细信息,请参阅下文中的 HTML 样式标签

图属性

GraphViz 支持图实例本身的一些属性。此库支持 GraphViz 的任何这些属性,并必须在图实例上使用 graphviz.graph. 前缀进行分配,如下所示

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.graph.bgcolor', 'transparent');

注意如何使用 graphviz.graph. 前缀,而不是仅使用 graphviz.。这是出于以下原因:与以下文档中所述的默认顶点和边属性保持一致。

例如,可以使用 rankdir 属性将方向更改为水平模式(从左到右),如下所示

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.graph.rankdir', 'LR');

$hello = $graph->createVertex();
$hello->setAttribute('id', 'hello');
$world = $graph->createVertex();
$world->setAttribute('id', 'wörld');
$graph->createEdgeDirected($hello, $world);

html graph example

请参阅 示例

此外,此库接受一个可选的 graphviz.name 属性,如果提供,它将用作 DOT 输出中的根图对象的名称(或 ID)。除非明确分配,否则默认情况下将省略。通常在这里分配一个 G,但通常不需要分配此属性。在其他方面,这可以用作 SVG 输出的标题或工具提示。

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.name', 'G');

$graph->createVertex();

顶点属性

GraphViz 支持每个顶点实例上的多个属性(GraphViz 称这些为“节点”属性)。该库支持这些 GraphViz 属性,并必须使用 graphviz. 前缀在相应的顶点实例上分配,如下所示

$graph = new Graphp\Graph\Graph();

$blue = $graph->createVertex();
$blue->setAttribute('graphviz.color', 'blue');

此外,GraphViz 还支持所有顶点的默认属性。该库支持这些 GraphViz 属性,并必须使用 graphviz.node. 前缀在图实例上分配,如下所示

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.node.color', 'grey');

$grey = $graph->createVertex();

可以通过在相应的顶点实例上显式分配相同的属性来覆盖这些默认属性,如下所示

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.node.color', 'grey');

$blue = $graph->createVertex();
$blue->setAttribute('graphviz.color', 'blue');

注意这里使用了 graphviz.node. 前缀而不是 graphviz.vertex.。这是为了与 GraphViz 在其 DOT 输出中分配这些默认属性的方式保持一致性。

边属性

GraphViz 支持每个边实例上的多个属性。该库支持这些 GraphViz 属性,并必须使用 graphviz. 前缀在相应的边实例上分配,如下所示

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$b = $graph->createVertex();

$blue = $graph->createEdgeDirected($a, $b);
$blue->setAttribute('graphviz.color', 'blue');

此外,GraphViz 还支持所有边的默认属性。该库支持这些 GraphViz 属性,并必须使用 graphviz.edge. 前缀在图实例上分配,如下所示

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.edge.color', 'grey');

$a = $graph->createVertex();
$b = $graph->createVertex();

$grey = $graph->createEdgeDirected($a, $b);

可以通过在相应的边实例上显式分配相同的属性来覆盖这些默认属性,如下所示

$graph = new Graphp\Graph\Graph();
$graph->setAttribute('graphviz.edge.color', 'grey');

$a = $graph->createVertex();
$b = $graph->createVertex();

$blue = $graph->createEdgeDirected($a, $b);
$blue->setAttribute('graphviz.color', 'blue');

标签

顶点标签

默认情况下,GraphViz 总是将顶点 ID 作为标签渲染。如果您没有为顶点分配显式的 id 属性,该库将自动从 1 开始在 DOT 输出中分配顶点 ID,并且 GraphViz 将自动将此顶点 ID 作为标签渲染。以下示例将自动将 12 作为标签分配

$graph = new Graphp\Graph\Graph();

$v1 = $graph->createVertex();
$v2 = $graph->createVertex();

如果您为顶点分配 id 属性,该库将自动将其用作 DOT 输出中的顶点 ID,并且 GraphViz 将自动将此顶点 ID 作为标签渲染。以下示例将自动将 blue 作为标签分配

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$a->setAttribute('id', 'blue');

如果您为顶点分配 balance 属性,该库将自动包含一个 label 属性,其中包含括号中的平衡值。以下示例将自动将 blue (+10) 作为标签分配

$graph = new Graphp\Graph\Graph();

$blue = $graph->createVertex();
$blue->setAttribute('id', 'blue');
$blue->setAttribute('balance', 10);

您可以使用 顶点属性 来显式分配自定义 label 属性。请注意,任何平衡值都会像上一个示例那样附加。

$graph = new Graphp\Graph\Graph();

$blue = $graph->createVertex();
$blue->setAttribute('id', 'blue');
$blue->setAttribute('graphviz.label', 'Hello world!');

请注意,默认情况下,所有 属性 都将被引号括起来并转义,所以 > 将原样显示,而不会被解释为 HTML。有关更多详细信息,请参阅下面的 类似 HTML 的标签

请注意,您应该定义 顶点 ID 或 所有 顶点 ID。如果您只定义 一些 顶点 ID,则自动编号可能会产生一个已被显式使用的顶点 ID,并覆盖其一些设置。

边标签

默认情况下,GraphViz 不会在边上渲染任何标签

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$b = $graph->createVertex();

$edge = $graph->createEdgeDirected($a, $b);

如果您为边分配 flowcapacityweight 属性,该库将自动包含一个包含这些值的 label 属性。以下示例将自动将 100 作为加权边的标签分配

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$b = $graph->createVertex();

$edge = $graph->createEdgeDirected($a, $b);
$edge->setAttribute('weight', 100);

以下示例将自动将 4/10 作为同时设置了流量和最大容量的边的标签分配

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$b = $graph->createVertex();

$edge = $graph->createEdgeDirected($a, $b);
$edge->setAttribute('flow', 4);
$edge->setAttribute('capacity', 10);

以下示例将自动将 4/∞/100 作为具有流量和无限容量的加权边的标签分配

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$b = $graph->createVertex();

$edge = $graph->createEdgeDirected($a, $b);
$edge->setAttribute('flow', 4);
$edge->setAttribute('capacity', null);
$edge->setAttribute('weight', 100);

您可以使用边缘属性来明确分配任何自定义的label属性。请注意,任何流、容量或权重值都将像之前的例子一样附加。

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$b = $graph->createVertex();

$edge = $graph->createEdgeDirected($a, $b);
$edge->setAttribute('graphviz.label', 'important');

HTML 样式标签

请注意,默认情况下,所有属性都将被引号括起来并转义,因此>将按原样显示,不会被视为HTML。GraphViz还支持类似于HTML的标签,它支持HTML功能的子集。

GraphViz要求任何类似于HTML的标签必须用<>括起来,并且只支持上述文档中所述的HTML功能的子集。为了防止自动引号和转义,所有类似于HTML的属性值需要在属性名后加上_html,如下所示

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$a->setAttribute('id', 'Entity');
$a->setAttribute('graphviz.shape', 'none');
$a->setAttribute('graphviz.label_html', '
<table cellspacing="0" border="0" cellborder="1">
    <tr><td bgcolor="#eeeeee"><b>\N</b></td></tr>
    <tr><td></td></tr>
    <tr><td>+ touch()</td></tr>
</table>');

$b = $graph->createVertex();
$graph->createEdgeDirected($b, $a);
$b->setAttribute('id', 'Block');
$b->setAttribute('graphviz.shape', 'none');
$b->setAttribute('graphviz.label_html', '
<table cellspacing="0" border="0" cellborder="1">
    <tr><td bgcolor="#eeeeee"><b>\N</b></td></tr>
    <tr><td>- size:int</td></tr>
    <tr><td>+ touch()</td></tr>
</table>');

UML html graph example

请参阅 示例

基于记录的节点

请注意,所有属性默认情况下都会被引号括起来并转义,因此>将按原样显示,不会被视为HTML。类似于上面的类似于HTML的标签,GraphViz还支持使用recordMrecord形状属性和结构化标签属性进行简单基于记录的节点

GraphViz要求任何基于记录的节点标签必须被引号括起来,但使用特殊语法来标记记录字段和可选端口名称。为了防止自动引号和转义,所有基于记录的属性值需要在属性名后加上_record,如下所示

$graph = new Graphp\Graph\Graph();

$a = $graph->createVertex();
$a->setAttribute('graphviz.shape', 'Mrecord');
$a->setAttribute('graphviz.label_record', '<f0> left |<middle> middle |<f2> right'));

$b = $graph->createVertex();
$b->setAttribute('graphviz.shape', 'Mrecord');
$b->setAttribute('graphviz.label_record', '<f0> left |<f1> middle |<right> right'));

// a:middle -> b:right
$edge = $graph->createEdgeDirected($a, $b);
$edge->setAttribute('graphviz.tailport', 'middle');
$edge->setAttribute('graphviz.headport', 'right');

records with ports graph example

请参阅 示例

安装

安装此库的推荐方法是通过Composer。对Composer不熟悉?初学者?

一旦发布,该项目将遵循SemVer。目前,这将安装最新的开发版本

composer require graphp/graphviz:^1@dev graphp/graph:^1@dev

有关版本升级的详细信息,请参阅变更日志

此项目旨在在任何平台上运行,因此不需要任何PHP扩展,并支持在PHP 5.3(通过当前PHP 7+)上运行。强烈建议使用PHP 7+进行此项目。

图表绘制功能由优秀的GraphViz软件提供支持。这意味着您需要安装GraphViz(dot可执行文件)。Graphviz的主页Graphviz下载页面提供了大多数常用平台的完整安装说明,基于Debian/Ubuntu的发行版的用户可以简单地调用

sudo apt install graphviz

测试

要运行测试套件,您首先需要克隆此存储库,然后通过Composer安装所有依赖项

composer install

要运行测试套件,请转到项目根目录并运行

vendor/bin/phpunit

许可证

此项目采用宽松的MIT许可证