功能

节点树

当节点(可连接实体 ConnectableEntity)和连线组织起来形成一个庞大的网络时,有一些快捷操作

通过纯键盘快速创建树结构

(Xmind 式的操作方式)

  1. 广度生长(创建同级节点):选中节点树上的一个节点,按 \ 反斜杠键,会在该节点下创建新的节点,并自动连接当前父节点

    这里没有使用Xmind习惯的Enter键,是因为 project-graph 最早Enter键是用来进入和退出编辑状态的,为了延续这种习惯避免冲突, 广度生长采用了Enter键上方的反斜杠键

    当选中一个孤立的节点时,只能进行深度生长,不能进行广度生长,因为没有父节点

  2. 深度生长(创建子级节点):选中节点树上的一个节点,按 Tab 键,会在该节点右侧创建新的节点,并自动连接当前父节点

    2.2 版本特性:在节点的编辑状态下,按Tab键时,不会输入制表符,而是将输入光标后的所有字符推出,形成新的子级节点的内容。

这两个按键可在设置中自定义修改

在2.2版本之前,连续创建多个子节点,需要不停的交替按 \(广度生长), Enter(退出编辑状态)。不断的退出编辑状态。

在 2.2 版本以后,节点在输入状态也可以进行 \Tab 键的生长,但输入状态下的快捷键是暂时无法自定义更改的。

这导致一个一个问题:如何在编辑时输入制表符和顿号、英文反斜杠?

如果要刻意输入此符号,有三种方法:

  1. 可以先把节点从树形结构中摘出来,再输入,输入好了之后再接入到树中。
  2. 可以把制表符、顿号、英文反斜杠先复制到粘贴板中,然后在输入状态下直接粘贴字符。
  3. 可以创建一个节点连向当前要输入这些符号的节点,使得当前节点有两个父节点,破坏了树形结构,进而广度生长和深度生长的树形操作特性失效, 等输入好之后再右键滑动砍掉刚才创建的连向它的节点即可。

但在后续的版本中增加了开关,这一“在编辑状态下也能广度生长”的特性是默认关闭的。

为什么按了tab键之后,树形结构内所有的节点重新布局了?

因为按下tab后会触发自动格式化布局。如何让按下tab后不重新布局?相见下面的“格式化树形结构”

移动树

左键拖拽一个节点,但按住 Ctrl 键可以带动所有子节点拖动整个树(注意只选中根节点)

可以拖动多个子树同时移动:

  1. 先选中多个树的根节点
  2. 按住 Ctrl 键不松手
  3. 左键拖拽任意一个选中的根节点进行移动

特性:如果同时移动多个节点,若选中的节点中存在一个节点时另一个节点的子级节点,那么此节点的移动速度会增加一倍。

利用此特性,我们可以整个选中一个链条结构,然后按 Ctrl 键不松手拖拽根节点,就可以整体伸缩整个链条的长度。

此特性本质是移动速度叠加的 bug。不确定以后是否有机会修复。

实际上直接框选,直接拖拽移动整个树形结构就能完成树的移动。这种移动树主要用于两个场景:

  1. 整个树是自定义布局,使用此方法可以移动树的一部分子树。
  2. 我想移动整个树在舞台上的位置,但树的周围有各种各样的障碍物、遮挡、影响框选效率。

格式化树形结构

如果您还在使用低于2.3的版本,请及时更新到最新版本,否则功能可能会和文档有出入。

在 2.0 之后,出现了连线的端点位置代表生长方向的含义。

如何判断一个节点的生长方向?就看这个节点的父节点连向它的连线的端点位置。

  1. 如果这个连线是 右侧发出 并且 左侧接收,简称“右连线”,那么此节点的生长方向向右
  2. 如果这个连线是 左侧发出 并且 右侧接收,简称“左连线”,那么此节点的生长方向向左
  3. 如果这个连线是 上侧发出 并且 下侧接收,简称“上连线”,那么此节点的生长方向向上
  4. 如果这个连线是 下侧发出 并且 上侧接收,简称“下连线”,那么此节点的生长方向向下
  5. 如果连线的端点位置不符合上述四种情况,简称“非标准连线”,那么此节点的生长方向默认向右。
  6. 如果此节点就是根节点,没有指向它的父级连线,那么此节点的生长方向默认向右。

可以选中树形结构的任意一个节点,按 Alt+Shift+F 来进行格式化。(因为VSCode的默认格式化代码的快捷键就是Alt+Shift+F,所以这里沿用了这个快捷键)

假设有这样一个结构

A --> B --> C
      |
      V
      D

选中ABCD中的任意一个节点,按下格式化之后,可能就变成了这样,这说明树形格式化成功了。

整个格式化的过程中实际进行了以下操作:

  1. 判断选中的节点所在的节点结构是否为树形结构,若存在聚合或者环路,则无法格式化
  2. 找到选中的节点所在树形结构的根节点,是A
  3. A是根节点,所以位置不变
  4. A的子节点B,之间所在的连线 A --> B 是一个右连线。所以B放在A的右侧一定距离。
  5. B有两个子节点 C、D。检测他们的连线,并根据连线决定他们应该放在自己的哪个方位上。
    (假设 B --> CB --> D)都是右连线。(B --> D不是下连线!它看上去总体是向下,但实际上是从B的右边缘到D的左边缘,看上去是略微往左倾斜了,可以通过选中这条连线观察到绿色虚线的端点圆圈)
  6. 由于两条连线都是右连线,所以 CD 都会摆放在 B 的右侧。现在开始给右侧的子节点按位置排序
  7. C之所以在上,D之所以在下,是因为在最开始,C在D靠上的位置。(以他们外接矩形的左上角顶点坐标位置为判断标准)
  8. 最后调整了CD与B之间的距离,到了一个标准值距离
         --> C
        /
A --> B 
        \
         --> D

能够变成这样的结构,说明 A --> BB --> CB --> D 这三条连线的方向都是从右侧发出,从左侧接收的“右连线”。 如果 B --> D 的连线真的是一个下连线,就会变成类似开始的样子了。

所以,决定树形格式化后的整体树形形状的关键,是在于树中所有连线的端点位置。

决定树中每一层中每个节点的排序,取决于格式化前节点之间的相对位置

如果有一条连线是“非标准连线”,那么在树形格式化进行到“非标准连线”指向的节点时,不会对此节点的位置进行调整(相对于它的父节点保持相对距离不变,而非坐标系中的绝对位置不变)。

所以,如果既想要tab键能够树形格式化,又想要树里保留一些自定义的布局结构,可以调整部分连线的端点位置,让一些连线改为非标准连线。

改变节点的生长方向(2.3+版本)

tab键生长的方向是完全取决于连向它的连线的端点位置。

有时候我们在以链条状的思考事情时,通常希望这条链能够拐弯。然而我们的手在键盘上,所以可以通过快捷键来改变生长方向。

默认的快捷键是:

  1. w, w:将选中节点的生长方向改为向上
  2. s, s:将选中节点的生长方向改为向下
  3. a, a:将选中节点的生长方向改为向左
  4. d, d:将选中节点的生长方向改为向右

("w, w"的含义为按两次w键)

可以观察到改变后,选中节点的边缘位置上会闪烁,表示生长方向已经改变。

假设我们选中了A节点,然后按下了“w, w” 快捷键,此时再按Tab,就会在上侧生长出一个子节点 B。

同时,A --> B 之间的连线也会自动变为“上连线”,如果不小心弄乱了结构,格式化后B也会自动调整到A的上方位置上。

因此可以更加自由的通过纯键盘来实现自由的树形结构布局。

         G  H  I
          \ | /
           \|/
A --> B --> C
     /|\
    / | \
   D  E  F

像上面这种,用一个链式结构将好几个上下的树串起来

ABC 之间的连线都是右连线,DEF与B之间的连线都是下连线,而GHI与C之间的连线都是上连线。

或者向下的链条结构中串起来很多向右的小树,甚至向右和向下不断逐层交替的复杂形状……

交换子节点之间的排列顺序

假设存在一个向右的树,可以拖拽一个子树的根节点,拖拽到同级节点的下方空隙位置中,然后按 Alt+Shift+F 来进行格式化。

格式化会自动调换两个子树的位置。

改变树的朝向

两种旋转方式

  1. 对准一个节点按住 Ctrl + 鼠标滚轮,会带动整个“子树”转动
  2. 用鼠标拖拽连线,可以转动整个“子树”

翻转方向

  1. 选中根节点
  2. 在工具栏中点击对齐,打开对齐面板
  3. 点击“水平翻转”/“垂直翻转”按钮

2.0+没有工具栏了,需要选中跟节点然后右键菜单中找到“横向反转树形结构”、“纵向反转树形结构”

注意:在 2.0 之后,出现了端点位置代表生长方向的含义,因此可能还需要调整连线的端点位置。

所以改变了节点的位置之后,还要再去改变一下连线的端点位置,才能保证在触发格式化时,布局是按照自己想要的方向进行的。

转变成框嵌套结构

框的嵌套形式也可以看成一种树形结构,甚至比树形结构还更加直观,还包含了上下左右等位置信息。

因此当树过于庞大和复杂时,建议使用框的嵌套关系+树形结构结合的方式来整理内容。

  1. 选中根节点
  2. 在工具栏中点击对齐,打开对齐面板
  3. 点击“回”形图标的按钮(2.0+版本需要在右键菜单中点击“品”形图标按钮)

2.1.1特性:当对一个纯文本树结构整体进行 Ctrl+G 打包时,框会自动取标题为当前树形结构的根节点

含有框结构的复杂树形结构

当含有框结构的复杂树形结构在格式化时,需要注意格式化涉及的节点都是连线关联到的节点,格式化不会按照框的引用关系传递。

例如

 ┌─────────┐          
 │S1       │          
 │   ┌──►B │   ┌───►F 
 │   │     │   │      
 │A──┼──►C ├───┼───►G 
 │   │     │   │      
 │   └──►D │   └───►H 
 └─────────┘          

C并没有和FGH相连,而是S1和他们相连。

因此此情况实际上是两个树形结构,一个是 A B C D,另一个是 S1 F G H。S1的大小和位置完全取决于ABCD的位置,S1像一个紧紧的橡皮筋一样套住了ABCD。

所以,选中G进行格式化时,不会影响ABCD的位置,选中C进行格式化时,不会影响FGH的位置。

选中S1进行格式化时,不会影响S1内部的位置,但会影响FGH的位置

但如果是这样:

S1 --> G 之间的连线改为 C --> G,那么此时 ABCDFGH 整体成为了一个树结构。

 ┌─────────┐          
 │S1 ┌──►B │          
 │   │     │  ┌────►F 
 │   │     │  │       
 │A──┼──►C─┼──┼────►G 
 │   │     │  │       
 │   │     │  └────►H 
 │   └──►D │          
 └─────────┘          

选中S1进行格式化时,不会看到任何变化。

但如果Section框和Section框之间有树形结构,例如 S1 --> S2, S1 --> S3 之间的连线都是右连线

            ┌──────┐
            │S2    │
 ┌──────┐ ┌─►      │
 │S1    │ │ │ .... │
 │ .... ┼─┤ └──────┘
 │      │ │         
 └──────┘ │ ┌──────┐
          │ │S3    │
          └─►      │
            │ ...  │
            └──────┘

那么选中任意一个框就能够将三个框按照树形结构格式化为一个向右的树。同时保证三个框内部的节点结构保持不变。

又因为框可以无限嵌套,所以您甚至可以做出分形结构的思维导图。

          ┌────────────┐         
          │S1          │         
          │       ┌───┐│         
          │     ┌─►...││         
          │┌───┐│ └───┘│         
          ││...┼┤      │         
          │└───┘│ ┌───┐│         
          │     └─►...││         
          │       └───┘│         
          └─────┬┬─────┘         
                ││               
       ┌────────┘└────────┐      
       │                  │      
 ┌─────▼──────┐     ┌─────▼─────┐
 │S2          │     │S3         │
 │       ┌───┐│     │   ┌───┐   │
 │     ┌─►...││     │   │...│   │
 │┌───┐│ └───┘│     │   └─┬─┘   │
 ││...┼┤      │     │  ┌──┴──┐  │
 │└───┘│ ┌───┐│     │┌─▼─┐ ┌─▼─┐│
 │     └─►...││     ││...│ │...││
 │       └───┘│     │└───┘ └───┘│
 └────────────┘     └───────────┘

更多关于框的操作可以参考“框”章节。

将树结构导出为 markdown

详见“导出”章节