五、jsPlumb實現流程圖配置--連線

Bencakes發表於2024-03-19

一、線條建立

第一篇文章講到過線條一共有四種型別BezierStraightFlowchartState Machine,以及每種型別的樣子,接下來就演示如何建立線條。
建立一條連線有兩種方式:透過程式碼建立;使用者使用滑鼠拖拽進行建立。
1. 透過程式碼建立
使用jsPlumb提供的connect API可以建立連線。

      <div
        class="rectangle-node items-center justify-center row"
        ref="node1"
        style="top: 100px; left: 100px"
      >
        節點1
      </div>

      <div
        class="rectangle-node items-center justify-center row"
        ref="node2"
        style="top: 100px; left: 300px"
      >
        節點2
      </div>
import {
  newInstance,
  BrowserJsPlumbInstance,
  StraightConnector,
} from '@jsplumb/browser-ui';

// ...省略部分

onMounted(() => {
  jsPlumb.value = newInstance({
    container: canvas.value,
  });
  jsPlumb.value.connect({
    source: node1.value,
    target: node2.value,
    connector: StraightConnector.type,
  });
});

以上就是最簡單的建立線條的程式碼,引數source、target分別指定了起始節點和目的節點,connector指定了線條的型別。

從圖中可以看到,jsPlumb為節點們建立了預設的Endpoint和Anchor,然後才將他們連線起來。如果並不想用預設的Anchor連線位置,那麼引數source/target也可以設定Endpoint物件,例如:

      <div
        class="rectangle-node items-center justify-center row"
        ref="node3"
        style="top: 100px; left: 500px"
      >
        節點3
      </div>

      <div
        class="rectangle-node items-center justify-center row"
        ref="node4"
        style="top: 100px; left: 700px"
      >
        節點4
      </div>
  const endpoint3 = jsPlumb.value.addEndpoint(node3.value, {
    endpoint: {
      type: 'Rectangle',
      options: {
        width: 10,
        height: 10,
      },
    },
    anchor: AnchorLocations.Right,
  });
  const endpoint4 = jsPlumb.value.addEndpoint(node4.value, {
    endpoint: {
      type: 'Dot',
      options: {
        radius: 5,
      },
    },
    anchor: AnchorLocations.Left,
  });

  jsPlumb.value.connect({
    source: endpoint3,
    target: endpoint4,
    connector: 'Flowchart',
  });


如上面程式碼所示,source/target引數傳入的就是自己建立的Endpoint,connector引數也可以直接傳入字串。以上就是用程式碼建立線條最簡單的方式了。
2. 滑鼠連線
除了直接用程式碼連好連線,也可以把連線的互動交給使用者,使用者只需要拖動滑鼠即可連線。要實現此功能,只需要在Endpoint建立時,新增引數source或target即可。
Endpoint中這兩個引數的含義與Connector中的不同。Endpoint中source表示能否作為連線的起始點target表示能否作為連線的目的點

      <div
        class="rectangle-node items-center justify-center row"
        ref="node5"
        style="top: 300px; left: 100px"
      >
        節點5-source
      </div>
      <div
        class="rectangle-node items-center justify-center row"
        ref="node6"
        style="top: 300px; left: 300px"
      >
        節點6-target
      </div>
  const endpoint5 = jsPlumb.value.addEndpoint(node5.value, {
    endpoint: {
      type: 'Dot',
      options: {
        radius: 5,
      },
    },
    source: true,
    anchor: AnchorLocations.Right,
  });

  const endpoint6 = jsPlumb.value.addEndpoint(node6.value, {
    endpoint: {
      type: 'Dot',
      options: {
        radius: 5,
      },
    },
    target: true,
    anchor: AnchorLocations.Left,
  });

source/target引數為boolean型別,配置如程式碼所示,效果如圖所示,可以從節點5連線到節點6:

但是這個配置,不能從節點6連線到節點5。因為節點5沒有設定target=true,節點6沒有設定source=true,如果想讓一個Endpoint既可以作為起始點,又可以作為目的點,那就同時把source=true,target=true都設定。

二、線條的引數

介紹了簡單建立線條的方式之後,接下來就說說如何設定線條的詳細引數。jsPlumb中,每個型別的線條可用的引數不都相同,也就是說某些引數只對特定型別的線條能夠生效。因此我們分開演示每個型別線條的引數。
Beizier線條

  • curviness:官方文件上解釋的是control pointsanchor points之間的距離(單位: px),就是指的錨點到曲線那個拐點的距離。不好理解,畫圖解釋如下:

    按個人理解,這個引數其實就是控制線條的曲度:值越小,曲線越平;值越大,曲線越彎曲,效果如圖分別表示了curviness=150和curviness=10的效果:

    配置程式碼:
      <div
        class="rectangle-node items-center justify-center column"
        ref="node7"
        style="top: 300px; left: 500px"
      >
        <span class="col">節點7-Bezier</span>
        <span class="col">curviness=150</span>
      </div>
      <div
        class="rectangle-node items-center justify-center column"
        ref="node8"
        style="top: 200px; left: 700px"
      >
        <span class="col">節點8-Bezier</span>
        <span class="col">curviness=150</span>
      </div>

      <div
        class="rectangle-node items-center justify-center column"
        ref="node9"
        style="top: 300px; left: 870px"
      >
        <span class="col">節點9-Bezier</span>
        <span class="col">curviness=10</span>
      </div>
  jsPlumb.value.connect({
    source: endpoint7,
    target: endpoint8,
    connector: {
      type: 'Bezier',
      options: {
        curviness: 150,
      },
    },
  });
  jsPlumb.value.connect({
    source: node8.value,
    target: node9.value,
    endpoint: {
      type: 'Dot',
      options: {
        radius: 4,
      },
    },
    anchors: [
      [1, 0.5, 1, 0],
      [0, 0.5, -1, 0],
    ],
    connector: {
      type: 'Bezier',
      options: {
        curviness: 10,
      },
    },
  });

節點8和節點9的連線程式碼,是不需要提前去建立Endpoint的,直接在建立連線的時候配置好了Endpoint、Anchor以及Connector的引數。Anchor配置使用的是anchors而不是anchoranchors引數只能接收兩個anchor配置,代表的就是起始點位置跟目的點位置。

Straight線條

  • stub:有點類似curviness引數,用於控制錨點到線條拐點的距離,預設是0。
  • gap:控制線條到錨點之間的間隔距離,預設是0。
    用實際的示例演示:

    示例程式碼:
      <div
        class="rectangle-node items-center justify-center column"
        ref="node10"
        style="top: 400px; left: 100px"
      >
        <span class="col">節點10-Straight</span>
        <span class="col">預設</span>
      </div>
      <div
        class="rectangle-node items-center justify-center column"
        ref="node11"
        style="top: 550px; left: 200px"
      >
        <span class="col">節點11-Straight</span>
        <span class="col">預設+stub=30</span>
      </div>
      <div
        class="rectangle-node items-center justify-center column"
        ref="node12"
        style="top: 400px; left: 300px"
      >
        <span class="col">節點12-Straight</span>
        <span class="col">stub=30,gap=20</span>
      </div>
      <div
        class="rectangle-node items-center justify-center column"
        ref="node13"
        style="top: 550px; left: 400px"
      >
        <span class="col">節點13-Straight</span>
        <span class="col">gap=20</span>
      </div>
  jsPlumb.value.connect({
    source: node10.value,
    target: node11.value,
    endpoint: 'Dot',
    anchors: ['Bottom', [0.3, 0, 0, -1]],
    connector: 'Straight',
  });

  jsPlumb.value.connect({
    source: node11.value,
    target: node12.value,
    endpoint: 'Dot',
    anchors: [
      [0.7, 0, 0, -1],
      [0.3, 1, 0, 1],
    ],
    connector: {
      type: 'Straight',
      options: {
        stub: 30,
      },
    },
  });
  jsPlumb.value.connect({
    source: node12.value,
    target: node13.value,
    endpoint: 'Dot',
    anchors: [[0.7, 1, 0, 1], 'Top'],
    connector: {
      type: 'Straight',
      options: {
        gap: 20,
      },
    },
  });

Flowchart線條
Flowchart線條大部份情況下,都會有兩個拐點。與Straight不同,Straight如果不設定stub是不會有拐點出現的。因此Flowchart有些引數與Straight相似:

  • stub:指從錨點到拐點的最小距離。預設值是30
  • alwaysRespectStubs:是否嚴格按照stub設定的引數來繪製,預設是false。一般情況,如果兩個元素靠得很近,那麼jsPlumb會根據實際距離去最佳化線條的繪製。如果此引數設定為true, 那麼不論兩個元素距離如何,線條都會從錨點出發至少stub距離後才進行折線。
  • gap:這個與Straight的配置是一樣的,錨點與線條的間隔距離。
  • cornerRadius:把尖角變為圓角並設定其的弧度。
  • midpoint:不知道幹啥的......

Flowchart引數就不舉例展示了,主要引數stub、gap效果和Straight類似。

State Machine線條
狀態機線條看著就像是不那麼彎曲的Bezier線條,有一些曲度,但整體比較平滑,而且線條只有一個彎曲的地方(Bezier有兩個)。

  • margin:作用跟gap引數一樣的,錨點與線條間隔距離,預設值5。不明白為啥要換個引數,增加了學習成本.....
  • curviness:作用和Bezier線條的curviness引數一樣,調整線條曲度,預設值10。
  • proximityLimit:這是一個閾值,當兩個節點直接的距離小於這個指,線條就會直接變為直線(無彎曲),預設是80px。

三、線條的樣式

連線也是透過SVG繪製的,在調整連線的樣式時,同樣也分為全域性設定跟區域性設定,設定的引數是相同的,全域性設定是在jsPlumb例項化的時候,而區域性設定是在連線的時候。
全域性設定:

  jsPlumb.value = newInstance({
    container: canvas.value,
    paintStyle: {
      stroke: '#40BDEC',
      outlineStroke: '#FFF',
      outlineWidth: 6,
    },
  });

區域性設定:

  jsPlumb.value.connect({
    source: node14.value,
    target: node15.value,
    endpoint: 'Dot',
    anchors: ['Top', 'Top'],
    connector: 'Flowchart',
      paintStyle: {
      stroke: 'red',
      strokeWidth: 5,
      outlineStroke: 'blue',
      outlineWidth: 5,
     },
  });

其中outlineStrokeoutlineWidth屬性設定線條的外邊框寬度與顏色,在實際使用過程中,如果有需要點選線條的需求時,這個屬性會很有用。因為實際使用中,線條寬度可能只有2px~3px,使用滑鼠十分難以點選到,使用outlineWidth對線條加寬,並將顏色設定跟底色一樣,就會讓線條很好點選。
除了設定線條的樣式,還可以設定線條hover時的樣式。例如:

  jsPlumb.value.connect({
    source: node16.value,
    target: node17.value,
    endpoint: 'Dot',
    anchors: ['Top', 'Top'],
    connector: 'Flowchart',
    paintStyle: {
      stroke: '#40BDEC',
      strokeWidth: 2,
      outlineStroke: '#FFF',
      outlineWidth: 8,
    },
    hoverPaintStyle: {
      stroke: '#40BDEC',
      strokeWidth: 4,
      outlineStroke: '#FFF',
      outlineWidth: 8,
    },
  });


這樣就可以實現滑鼠只要移到線條周邊,就可以完成對線條的選中。

四、總結

以上就介紹完了線條的建立、調整與樣式,關於線條的內容比較多,在實際使用中線條的控制是佔大部份的。本章的完整程式碼地址在此,後續還有關於線條的事件、攔截器等內容。

相關文章