网络图作为代码

在过去的几年中,我开始更多地处理文档。编写有关该系统或该系统如何工作的解释性文本-通常,这很简单。绘制一个将显示所有关键对象的图,这些对象之间的关系也很容易。

但是最棘手的时刻是保持此文档的最新性。好吧,文字,但是图表...因为所有文档都是在线的,即以html格式显示,然后在文本上附加gif / jpeg / png图片,并在上面实际绘制图表。方案是在各种程序(例如Visio或la.draw的在线服务)中绘制的。然后,将图导出为图形格式,并将其附加到html。一切都很简单。

问题是什么?

方案通常很简单。更确切地说,不是很复杂。是的,对象数为十或两个,连接数大致相同。加上签名,一些名称。简单的方案可以用语言来描述,但是太复杂了,嗯……“他们听不懂,先生。”有很多方案,其中的更改需要定期,定期进行,即不断,因为他们关注我们产品的开发。

您可以嵌入html服务。你试过了吗?

当然是。例如,我喜欢gliffy.com图形。但是要进行更改,您需要转到第三方服务,在那里进行编辑。而且,将修正案下放给同事比较困难。

该怎么办?

最近,在github上,我在建议中遇到了github.com/RaoulMeyer/diagram-as-code存储库。图表作为代码。那些。我们在js上描述了我们需要的电路。我们直接在其他文档文本所在的html中直接编写此js。

顺便说一句,但是我根本没有用html编写文档。通常,文档是带有降价文本的一组文件,然后由某些引擎(例如wintersmith)将其转换为完整的文档站点。或维基系统。

事实证明非常方便:在这里我们编写了文本,然后打开了script标签,并在其中描述了电路的js代码。

又怎么了

我喜欢这个存储库,但这不是使用代码或文本视图绘制图时的唯一示例。 (在文章末尾,将有链接到在主题图中以代码形式搜索到的项目和文章的链接。)

而且我不是唯一更正文档的人。有时,同事也会做出贡献-改正单词,更改描述,插入新图片。 

因此,我希望以可读易懂的文本格式查看该图,因此无需长时间研究。在某些地方,复制粘贴甚至可以很容易地加快新方案的添加速度。 

另一位同事指出,该代码当然很好,但是如果您使用该结构,则所有内容都可能非常严格和富有表现力。

因此,我尝试将该方案呈现为一组由几个小的数组组成的数组,这些数组描述了节点,连接,节点组以及节点的位置。以我的拙见,结果当然很方便,尽管当然还有味道和颜色……

阵列中的图表如何?

  • 每个节点由唯一标识该节点的标识符描述。
  • 您还可以将图标添加到节点,添加题字。
  • 您可以指定两个节点之间的关系。
  • 要进行方案通信,可以设置颜色,题词。
  • 通信的方向定义为从源到目标。源和目标由节点的标识符指示。
  • 可以将一个或多个节点添加到该组。
  • 也可以从组到组指定链接。

使用这些简单的规则,我们得到了这样的方案。只是?相当。



它由以下js代码描述。这里最主要的是elements对象。在哪个节点-节点,边-连接被指示。
 
  const elements = {
    nodes: [       //  
      { id: 'client', type: 'smartphone', label: 'Mobile App'},
      { id: 'server', type: 'server', label: 'Main Server'},
      { id: 'db1', type: 'database', label: 'DB 1'},
      { id: 'db2', type: 'database', label: 'DB 2'},
    ],
    edges: [       //  
      { source: 'client', target: 'server', label: 'request' },
      { source: 'server', target: 'db1', label: 'request' },
      { source: 'server', target: 'db2', label: 'request' },
    ],
  };
  Diagram('scheme1', elements);

当然,我并没有想到自己绘制电路,而是使用了cytoscape.js(一种非常强大的可视化工具)。我决定仅使用Toliku机会。 

显然,这是一个简单的例子。可以更复杂吗?

是的,请。为了指示位置-我们使用位置来指示组-我们指定组中的组列表,并且元素本身具有group属性。



这是代码:

<div id="scheme5" style="height:500px;width:800px;"></div>
<script>
  const elements5 = {
    groups: [
      { id: 'g1', label: '  1'},
      { id: 'g2', label: '  2'},
    ],
    nodes: [
      { id: 'man1', type: 'person', label: ''},
      { id: 'client', type: 'smartphone', label: ''},
      { id: 'agent-backend', type: 'server', group: 'g1', label: 'agent-backend'},
      { id: 'web', type: 'server', group: 'g1', label: ' admin'},
      { id: 'www', type: 'server', group: 'g1', label: ' '},
      { id: 'mongodb1', type: 'database', group: 'g1', label: 'Mongo DB 1'},
      { id: 'mongodb2', type: 'database', group: 'g1', label: 'Mongo DB 2'},
      { id: 'runner-integration1', type: 'worker', group: 'g1', label: ''},
      { id: 'runner-integration2', type: 'worker', group: 'g1', label: ''},
      { id: 'api', type: 'server', group: 'g1', label: 'API'},
      { id: 'server2', type: 'server', group:'g2', label: ''},
      { id: 'otherServer', type: 'server', group:'g2', label: ''},
      { id: 'firebase', type: 'cloud', label: 'Google Firebase'},
    ],
    edges: [
      { source: 'client', target: 'agent-backend', label: 'json', color: 'red' },
      { source: 'agent-backend', target: 'mongodb1', color: 'red' },
      { source: 'agent-backend', target: 'mongodb2',  color: 'red' },
      { source: 'mongodb1', target: 'runner-integration1', label: '' },
      { source: 'mongodb2', target: 'runner-integration2', label: '' },
      { source: 'mongodb1', target: 'web', label: '  ' },
      { source: 'runner-integration1', target: 'server2', label: '' },
      { source: 'runner-integration2', target: 'otherServer', label: '' },
      { source: 'api', target: 'firebase', label: '', color: 'blue', },
      { source: 'firebase', target: 'client', label: 'push', color: 'blue'},
      { source: 'server2', target: 'api', label: '', color: 'blue'},
      { source: 'man1', target: 'client', },
    ],
    positions: [
      { id: 'client', row: 2, col: 1,},
      { id: 'agent-backend', row: 2, col: 3,},
      { id: 'web', row: 6, col: 3,},
      { id: 'www', row: 1, col: 3,},
      { id: 'mongodb1', row: 1, col: 4,},
      { id: 'mongodb2', row: 2, col: 5,},
      { id: 'runner-integration1', row: 3, col: 3,},
      { id: 'runner-integration2', row: 4, col: 3,},
      { id: 'api', row: 5, col: 3,},
      { id: 'server2', row: 6, col: 7,},
      { id: 'otherServer', row: 4, col: 7,},
      { id: 'firebase', row: 5, col: 1,},
      { id: 'logger', row: 2, col: 7,},
      { id: 'crm', row: 5, col: 8,},
    ],
};
  Diagram('scheme5', elements5, {layout: 'grid'});
</script>

这种方案一方面几乎是笔记本电脑上的几个屏幕代码,另一方面,la json结构使您可以类推,快速地填充所有数据,并且可以复制粘贴。

为何将位置与节点分开取出?

这样比较舒服。首先,我们指定节点。然后我们可以指示几个组并在节点中指示它们。然后,我们表示连接。然后,当主要对象及其之间的连接处于连接状态时,我们将占据这些对象在图中的位置。或相反亦然。

没有职位可以吗?

没有职位是可能的。但这会有些折磨,在示例中您可以看到此选项。这是由于以下事实:对于cytoscape,有一种算法可以确定fcose节点的位置,这也考虑了组的存在。指定职位可以使方案更加可控,但是在方案初稿阶段,没有职位是可能的。

另外,可以按照海战的方式指定位置。那些。一个节点位于a1中,另一个位于d5中。尤其有利于细胞景观在帆布上形成可移动的物体,即 我们可以移动它们,查看不同的布局选项,然后在代码中修复您喜欢的元素排列。

总的来说,我知道了。您还可以尝试吗?
 
当然,为了快速创建方案,我给自己做了一个小编辑器,该编辑器会更新方案本身并将最后一个选项存储在浏览器中(在localStorage中)。

你试过了吗?您现在可以添加到页面。

然后再次:

1。 我们连接一个脚本

<script src="https://unpkg.com/@antirek/network-diagram@0.1.4/dist/code-full.min.js"></script>

2.添加到html代码

<div id="scheme1" style="height:300px;width:800px;"></div>
<script>      
  const elements = {    
    nodes: [
      { id: 'client', type: 'smartphone', label: 'Mobile App'},
      { id: 'server', type: 'server', label: 'Main Server'},
      { id: 'db1', type: 'database', label: 'DB 1'},
      { id: 'db2', type: 'database', label: 'DB 2'},
    ],
    edges: [
      { source: 'client', target: 'server', label: 'request' },
      { source: 'server', target: 'db1', label: 'request' },
      { source: 'server', target: 'db2', label: 'request' },
    ],
  };
  Diagram('scheme1', elements);
</script>

3.将代码编辑为所需的方案(我认为这比画猫头鹰要容易:)在github

的项目页面上有更多详细信息

结果是什么?

我实现了我的目标-向文档添加内联模式,格式非常简单明了。它不适用于超级方案,但对于解释连接结构的小型电路,甚至什么也没有。您随时可以快速修复它,并随时间更改某些内容。是的,同事可以自己修改坞中的某些东西,至少可以对对象进行签名,而无需特殊培训))有

什么可以改进的地方?

当然,有很多选择。添加其他图标(所有可用图标均内联添加到脚本中)。选择一组更具表现力的图标。可以指定链接线型。添加背景图片。

你怎么看?
 
我已经有一些实现问题的想法,您也可以在评论中添加您的想法。


我的解决方案绝对适用于狭窄的任务,也许您会发现通过简单地编码对图表进行绘制的更方便的工具-正如他们所说的“以代码形式显示图表”

  1. 不错的选择
  2. 豪华服务  (9种图表在线编辑器)
  3. 当然是mermaid.js
  4. 如果您喜欢超级详细和复杂的方案,那么此项目一定会让您满意:go.drawthe.net

All Articles