{"expireTime":9007200828528711000,"key":"transformer-remark-markdown-html-7388a1e45496f11d0958f69146dfaec1-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":"<p>G6 提供了一般图和树图的一些常用布局，使用方式参见：中级教程 <a href=\"https://www.yuque.com/antv/g6/qopkkg\" target=\"_self\" rel=\"nofollow\">使用布局 Layout</a>，<a href=\"https://www.yuque.com/antv/g6/agbmu2\" target=\"_self\" rel=\"nofollow\">Layout API</a>。当这些内置布局无法满足需求时，G6 还提供了一般图的自定义布局的机制，方便用户进行更定制化的扩展。</p>\n<p><span style=\"background-color: rgb(251, 233, 231); color: rgb(139, 53, 56)\">   注意：</span>\n树图暂时不支持自定义布局。</p>\n<p>本文将会通过自定义 Bigraph 布局的例子讲解自定义布局。</p>\n<h2 id=\"自定义布局-api\"><a href=\"#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B8%83%E5%B1%80-api\" aria-label=\"自定义布局 api permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>自定义布局 API</h2>\n<p>G6 中自定义布局的 API 如下：</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">/**\n * 注册布局的方法\n * @param {string} type 布局类型，外部引用指定必须，不要与已有布局类型重名\n * @param {object} layout 布局方法\n */</span>\nLayout<span class=\"token punctuation\">.</span><span class=\"token function-variable function\">registerLayout</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span>type<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/**\n   * 定义自定义行为的默认参数，会与用户传入的参数进行合并\n   */</span>\n  <span class=\"token function\">getDefaultCfg</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">/**\n   * 初始化\n   * @param {object} data 数据\n   */</span>\n  <span class=\"token function\">init</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">data</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">/**\n   * 执行布局\n   */</span>\n  <span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">/**\n   * 根据传入的数据进行布局\n   * @param {object} data 数据\n   */</span>\n  <span class=\"token function\">layout</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">data</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">/**\n   * 更新布局配置，但不执行布局\n   * @param {object} cfg 需要更新的配置项\n   */</span>\n  <span class=\"token function\">updateCfg</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">cfg</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">/**\n   * 销毁\n   */</span>\n  <span class=\"token function\">destroy</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2 id=\"自定义布局\"><a href=\"#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B8%83%E5%B1%80\" aria-label=\"自定义布局 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>自定义布局</h2>\n<p>下面，我们将讲解如何自定义布局如下图的二分图 Bigraph。二分图只存在两部分节点之间的边，同属于一个部分的节点之间没有边。我们希望布局能够对两部分节点分别进行排序，减少边的交叉。<br /></p>\n<img src='https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*FksvTrdkqXgAAAAAAAAAAABkARQnAQ' alt='img' width='350'/>\n<p>该二分图数据如下，节点根据 <code class=\"language-text\">cluster</code> 字段分为 了 <code class=\"language-text\">&#39;part1&#39;</code> 和 <code class=\"language-text\">&#39;part2&#39;</code>，代表二分图的两部分。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> data <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  nodes<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'0'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'A'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part1'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'1'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'B'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part1'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'2'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'C'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part1'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'3'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'D'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part1'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'4'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'E'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part1'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'5'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'F'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part1'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'6'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'a'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part2'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'7'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'b'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part2'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'8'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'c'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part2'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> id<span class=\"token punctuation\">:</span> <span class=\"token string\">'9'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">:</span> <span class=\"token string\">'d'</span><span class=\"token punctuation\">,</span> cluster<span class=\"token punctuation\">:</span> <span class=\"token string\">'part2'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  edges<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'0'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'6'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'0'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'7'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'0'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'9'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'1'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'6'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'1'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'9'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'1'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'7'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'2'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'8'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'2'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'9'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'2'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'6'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'3'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'8'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'4'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'6'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'4'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'7'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">{</span> source<span class=\"token punctuation\">:</span> <span class=\"token string\">'5'</span><span class=\"token punctuation\">,</span> target<span class=\"token punctuation\">:</span> <span class=\"token string\">'9'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n</code></pre></div>\n<h3 id=\"需求分析\"><a href=\"#%E9%9C%80%E6%B1%82%E5%88%86%E6%9E%90\" aria-label=\"需求分析 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>需求分析</h3>\n<p>为了减少边的交叉，可以通过排序，将 <code class=\"language-text\">&#39;part1&#39;</code> 的节点 A 对齐到所有与 A 相连的 <code class=\"language-text\">&#39;part2&#39;</code> 中的节点的平均中心；同样将 <code class=\"language-text\">&#39;part2&#39;</code> 中的节点 a 对齐到所有与 a 相连的 <code class=\"language-text\">&#39;part1&#39;</code> 中的节点的平均中心。可以描述成如下过程：</p>\n<ul>\n<li>Step 1：为 <code class=\"language-text\">&#39;part1&#39;</code> 和 <code class=\"language-text\">&#39;part2&#39;</code> 的节点初始化随机序号 index，都分别从 0 开始；</li>\n<li>\n<p>Step 2：遍历 <code class=\"language-text\">&#39;part1&#39;</code> 的节点，对每一个节点 A：</p>\n<ul>\n<li>找到与 A 相连的属于 <code class=\"language-text\">&#39;part2&#39;</code> 的节点的集合 <img src=\"https://cdn.nlark.com/yuque/__latex/f6dc1bad88be668c4ac817b367ec9bbf.svg#card=math&#x26;code=set_A%0A&#x26;height=16&#x26;width=32\">，加和 <img src=\"https://cdn.nlark.com/yuque/__latex/f6dc1bad88be668c4ac817b367ec9bbf.svg#card=math&#x26;code=set_A%0A&#x26;height=16&#x26;width=32\"> 中所有节点的 index，并除以 <img src=\"https://cdn.nlark.com/yuque/__latex/f6dc1bad88be668c4ac817b367ec9bbf.svg#card=math&#x26;code=set_A%0A&#x26;height=16&#x26;width=32\"> 的元素个数，得数覆盖 A 的 index 值：<img src=\"https://cdn.nlark.com/yuque/__latex/b2acdd6a9423b18105b6909ef4124618.svg#card=math&#x26;code=A.index%20%3D%20%5Cfrac%7B1%7D%7B%7Cset_A%7C%7D%5Csum_%7Ba%20%5Cin%20set_A%7D%7Ba.index%7D&#x26;height=48&#x26;width=234\"></li>\n</ul>\n</li>\n<li>\n<p>Step 3：遍历 <code class=\"language-text\">&#39;part1&#39;</code> 的节点，对每一个节点 B（与 Step 2 相似）：</p>\n<ul>\n<li>找到与 B 相连的属于 <code class=\"language-text\">&#39;part2&#39;</code> 的节点的集合 <img src=\"https://cdn.nlark.com/yuque/__latex/dc5ec10db72d3f1928fb51c6da59707a.svg#card=math&#x26;code=set_B%0A&#x26;height=16&#x26;width=32\">，加和 <img src=\"https://cdn.nlark.com/yuque/__latex/dc5ec10db72d3f1928fb51c6da59707a.svg#card=math&#x26;code=set_B%0A&#x26;height=16&#x26;width=32\"> 中所有节点的 index，并除以 <img src=\"https://cdn.nlark.com/yuque/__latex/dc5ec10db72d3f1928fb51c6da59707a.svg#card=math&#x26;code=set_B%0A&#x26;height=16&#x26;width=32\"> 的元素个数，得数覆盖 B 的 index 值：<img src=\"https://cdn.nlark.com/yuque/__latex/2eb533abba4f4502e1bd524e1fb792e6.svg#card=math&#x26;code=B.index%20%3D%20%5Cfrac%7B1%7D%7B%7Cset_B%7C%7D%5Csum_%7Bb%20%5Cin%20set_B%7D%7Bb.index%7D&#x26;height=48&#x26;width=232\"></li>\n</ul>\n</li>\n<li>Step 4：两部分节点分别按照节点的序号 index 进行排序，最终按照节点顺序安排节点位置。</li>\n</ul>\n<h2 id=\"实现\"><a href=\"#%E5%AE%9E%E7%8E%B0\" aria-label=\"实现 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>实现</h2>\n<p>下面代码展示了自定义名为 <code class=\"language-text\">&#39;bigraph-layout&#39;</code> 的二分图布局，完整代码参见：<a href=\"https://antv.alipay.com/zh-cn/g6/3.x/demo/net/layout-custom-bigraph.html\" target=\"_self\" rel=\"nofollow\">自定义布局-二分图</a>。使用该布局的方式与使用内置布局方式相同，都是在实例化图时将其配置到 <code class=\"language-text\">layout</code> 配置项中，详见：<a href=\"https://www.yuque.com/antv/g6/qopkkg\" target=\"_self\" rel=\"nofollow\">使用布局 Layout</a>。</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token constant\">G6</span><span class=\"token punctuation\">.</span><span class=\"token function\">registerLayout</span><span class=\"token punctuation\">(</span><span class=\"token string\">'bigraph-layout'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// 默认参数</span>\n  <span class=\"token function-variable function\">getDefaultCfg</span><span class=\"token punctuation\">:</span> <span class=\"token keyword\">function</span> <span class=\"token function\">getDefaultCfg</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n      center<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 布局的中心</span>\n      biSep<span class=\"token punctuation\">:</span> <span class=\"token number\">100</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 两部分的间距</span>\n      nodeSep<span class=\"token punctuation\">:</span> <span class=\"token number\">20</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 同一部分的节点艰巨</span>\n      direction<span class=\"token punctuation\">:</span> <span class=\"token string\">'horizontal'</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 两部分的分布方向</span>\n      nodeSize<span class=\"token punctuation\">:</span> <span class=\"token number\">20</span><span class=\"token punctuation\">,</span> <span class=\"token comment\">// 节点大小</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">// 执行布局</span>\n  <span class=\"token function-variable function\">execute</span><span class=\"token punctuation\">:</span> <span class=\"token keyword\">function</span> <span class=\"token function\">execute</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> self <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> center <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>center<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> biSep <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>biSep<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> nodeSep <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>nodeSep<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> nodeSize <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>nodeSize<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> part1Pos <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span>\n      part2Pos <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// 若指定为横向分布</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">.</span>direction <span class=\"token operator\">===</span> <span class=\"token string\">'horizontal'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      part1Pos <span class=\"token operator\">=</span> center<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">-</span> biSep <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n      part2Pos <span class=\"token operator\">=</span> center<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> biSep <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">var</span> nodes <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>nodes<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> edges <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>edges<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> part1Nodes <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> part2Nodes <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> part1NodeMap <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> part2NodeMap <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// separate the nodes and init the positions</span>\n    nodes<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">node<span class=\"token punctuation\">,</span> i</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">.</span>cluster <span class=\"token operator\">===</span> <span class=\"token string\">'part1'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        part1Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        part1NodeMap<span class=\"token punctuation\">.</span><span class=\"token function\">set</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        part2Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        part2NodeMap<span class=\"token punctuation\">.</span><span class=\"token function\">set</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">// 对 part1 的节点进行排序</span>\n    part1Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">p1n</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">var</span> index <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">var</span> adjCount <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n      edges<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">edge</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">var</span> sourceId <span class=\"token operator\">=</span> edge<span class=\"token punctuation\">.</span>source<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">var</span> targetId <span class=\"token operator\">=</span> edge<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>sourceId <span class=\"token operator\">===</span> p1n<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n          index <span class=\"token operator\">+=</span> part2NodeMap<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>targetId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n          adjCount<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>targetId <span class=\"token operator\">===</span> p1n<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n          index <span class=\"token operator\">+=</span> part2NodeMap<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>sourceId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n          adjCount<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      index <span class=\"token operator\">/=</span> adjCount<span class=\"token punctuation\">;</span>\n      p1n<span class=\"token punctuation\">.</span>index <span class=\"token operator\">=</span> index<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    part1Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">sort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">a<span class=\"token punctuation\">,</span> b</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> a<span class=\"token punctuation\">.</span>index <span class=\"token operator\">-</span> b<span class=\"token punctuation\">.</span>index<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">// 对 part2 的节点进行排序</span>\n    part2Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">p2n</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">var</span> index <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">var</span> adjCount <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n      edges<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">edge</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">var</span> sourceId <span class=\"token operator\">=</span> edge<span class=\"token punctuation\">.</span>source<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">var</span> targetId <span class=\"token operator\">=</span> edge<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>sourceId <span class=\"token operator\">===</span> p2n<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n          index <span class=\"token operator\">+=</span> part1NodeMap<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>targetId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n          adjCount<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>targetId <span class=\"token operator\">===</span> p2n<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n          index <span class=\"token operator\">+=</span> part1NodeMap<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>sourceId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n          adjCount<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      index <span class=\"token operator\">/=</span> adjCount<span class=\"token punctuation\">;</span>\n      p2n<span class=\"token punctuation\">.</span>index <span class=\"token operator\">=</span> index<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    part2Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">sort</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">a<span class=\"token punctuation\">,</span> b</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> a<span class=\"token punctuation\">.</span>index <span class=\"token operator\">-</span> b<span class=\"token punctuation\">.</span>index<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">// 放置节点</span>\n    <span class=\"token keyword\">var</span> hLength <span class=\"token operator\">=</span>\n      part1Nodes<span class=\"token punctuation\">.</span>length <span class=\"token operator\">></span> part2Nodes<span class=\"token punctuation\">.</span>length\n        <span class=\"token operator\">?</span> part1Nodes<span class=\"token punctuation\">.</span>length\n        <span class=\"token punctuation\">:</span> part2Nodes<span class=\"token punctuation\">.</span>length<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> height <span class=\"token operator\">=</span> hLength <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>nodeSep <span class=\"token operator\">+</span> nodeSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">var</span> begin <span class=\"token operator\">=</span> center<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">-</span> height <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">.</span>direction <span class=\"token operator\">===</span> <span class=\"token string\">'vertical'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      begin <span class=\"token operator\">=</span> center<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">-</span> height <span class=\"token operator\">/</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    part1Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">p1n<span class=\"token punctuation\">,</span> i</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">.</span>direction <span class=\"token operator\">===</span> <span class=\"token string\">'horizontal'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        p1n<span class=\"token punctuation\">.</span>x <span class=\"token operator\">=</span> part1Pos<span class=\"token punctuation\">;</span>\n        p1n<span class=\"token punctuation\">.</span>y <span class=\"token operator\">=</span> begin <span class=\"token operator\">+</span> i <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>nodeSep <span class=\"token operator\">+</span> nodeSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        p1n<span class=\"token punctuation\">.</span>x <span class=\"token operator\">=</span> begin <span class=\"token operator\">+</span> i <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>nodeSep <span class=\"token operator\">+</span> nodeSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        p1n<span class=\"token punctuation\">.</span>y <span class=\"token operator\">=</span> part1Pos<span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    part2Nodes<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">p2n<span class=\"token punctuation\">,</span> i</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">.</span>direction <span class=\"token operator\">===</span> <span class=\"token string\">'horizontal'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        p2n<span class=\"token punctuation\">.</span>x <span class=\"token operator\">=</span> part2Pos<span class=\"token punctuation\">;</span>\n        p2n<span class=\"token punctuation\">.</span>y <span class=\"token operator\">=</span> begin <span class=\"token operator\">+</span> i <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>nodeSep <span class=\"token operator\">+</span> nodeSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        p2n<span class=\"token punctuation\">.</span>x <span class=\"token operator\">=</span> begin <span class=\"token operator\">+</span> i <span class=\"token operator\">*</span> <span class=\"token punctuation\">(</span>nodeSep <span class=\"token operator\">+</span> nodeSize<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        p2n<span class=\"token punctuation\">.</span>y <span class=\"token operator\">=</span> part2Pos<span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n</code></pre></div>"}