w-flowchart 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/w-flowchart.umd.js +2 -2
- package/dist/w-flowchart.umd.js.map +1 -1
- package/docs/WFlowchart.mjs.html +169 -0
- package/docs/global.html +657 -0
- package/docs/index.html +2 -2
- package/package.json +52 -49
- package/src/WFlowchart.mjs +97 -0
- package/src/p1/README.md +2 -2
- package/src/p1/gen.mjs +54 -20
- package/src/p10/README.md +6 -2
- package/src/p10/gen.mjs +235 -15
- package/src/p2/README.md +1 -1
- package/src/p2/gen.mjs +52 -7
- package/src/p3/README.md +1 -1
- package/src/p3/gen.mjs +24 -2
- package/src/p4/README.md +1 -1
- package/src/p4/gen.mjs +36 -10
- package/src/p5/README.md +1 -1
- package/src/p5/gen.mjs +45 -18
- package/src/p6/README.md +1 -1
- package/src/p6/gen.mjs +108 -5
- package/src/p7/README.md +1 -1
- package/src/p7/gen.mjs +42 -3
- package/src/p8/README.md +1 -1
- package/src/p8/gen.mjs +41 -2
- package/src/p9/README.md +1 -1
- package/src/p9/gen.mjs +14 -7
- package/src/p9/page9.html +13 -5
- package/test/cases-diamond.mjs +221 -0
- package/test/cases.mjs +17 -1
- package/test/data//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.json +43 -0
- package/test/data//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.json +132 -0
- package/test/data//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.json +27 -0
- package/test/data//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.json +111 -0
- package/test/data//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.json +117 -0
- package/test/data//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.json +203 -0
- package/test/data//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.json +156 -0
- package/test/data//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.json +46 -0
- package/test/data//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.json +137 -0
- package/test/data//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.json +28 -0
- package/test/data//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.json +134 -0
- package/test/data//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.json +178 -0
- package/test/figures.mjs +3 -2
- package/test/lib.mjs +3 -1
- package/test/p1.test.mjs +5 -0
- package/test/p10.test.mjs +54 -2
- package/test/p2.test.mjs +5 -0
- package/test/p3.test.mjs +5 -0
- package/test/p4.test.mjs +5 -0
- package/test/p5.test.mjs +6 -0
- package/test/p6.test.mjs +5 -0
- package/test/p7.test.mjs +5 -0
- package/test/p8.test.mjs +5 -0
- package/test/p9.test.mjs +5 -0
- package/test/pics/p1/cycle.png +0 -0
- package/test/pics/p1/deep-nest.png +0 -0
- package/test/pics/p1/diamond.png +0 -0
- package/test/pics/p1/edges-mix.png +0 -0
- package/test/pics/p1/english.png +0 -0
- package/test/pics/p1/flat-tb.png +0 -0
- package/test/pics/p1/fold-tall.png +0 -0
- package/test/pics/p1/fold-wide.png +0 -0
- package/test/pics/p1/group-edge.png +0 -0
- package/test/pics/p1/items-node.png +0 -0
- package/test/pics/p1/long-label.png +0 -0
- package/test/pics/p1/lr-flat.png +0 -0
- package/test/pics/p1/nested-group.png +0 -0
- package/test/pics/p1/no-edges.png +0 -0
- package/test/pics/p1/title-overflow.png +0 -0
- package/test/pics/p1/valign.png +0 -0
- package/test/pics/p1//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p1//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p1//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p1//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p1//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p1//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p1//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p1//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p1//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p1//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p1//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p1//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p10/cycle.png +0 -0
- package/test/pics/p10/cycle.svg +1 -0
- package/test/pics/p10/deep-nest.svg +1 -0
- package/test/pics/p10/dia-1in-1out.png +0 -0
- package/test/pics/p10/dia-1in-1out.svg +1 -0
- package/test/pics/p10/dia-1in-2out.png +0 -0
- package/test/pics/p10/dia-1in-2out.svg +1 -0
- package/test/pics/p10/dia-1in.png +0 -0
- package/test/pics/p10/dia-1in.svg +1 -0
- package/test/pics/p10/dia-1out.png +0 -0
- package/test/pics/p10/dia-1out.svg +1 -0
- package/test/pics/p10/dia-2in-1out.png +0 -0
- package/test/pics/p10/dia-2in-1out.svg +1 -0
- package/test/pics/p10/dia-2in-2out-dd.png +0 -0
- package/test/pics/p10/dia-2in-2out-dd.svg +1 -0
- package/test/pics/p10/dia-2in-2out-ss.png +0 -0
- package/test/pics/p10/dia-2in-2out-ss.svg +1 -0
- package/test/pics/p10/dia-2in.png +0 -0
- package/test/pics/p10/dia-2in.svg +1 -0
- package/test/pics/p10/dia-2out.png +0 -0
- package/test/pics/p10/dia-2out.svg +1 -0
- package/test/pics/p10/diamond.png +0 -0
- package/test/pics/p10/diamond.svg +1 -0
- package/test/pics/p10/edges-mix.png +0 -0
- package/test/pics/p10/edges-mix.svg +1 -0
- package/test/pics/p10/english.png +0 -0
- package/test/pics/p10/english.svg +1 -0
- package/test/pics/p10/flat-tb.svg +1 -0
- package/test/pics/p10/fold-tall.svg +1 -0
- package/test/pics/p10/fold-wide.svg +1 -0
- package/test/pics/p10/group-edge.png +0 -0
- package/test/pics/p10/group-edge.svg +1 -0
- package/test/pics/p10/items-node.svg +1 -0
- package/test/pics/p10/long-label.svg +1 -0
- package/test/pics/p10/lr-flat.svg +1 -0
- package/test/pics/p10/nested-group.png +0 -0
- package/test/pics/p10/nested-group.svg +1 -0
- package/test/pics/p10/no-edges.svg +1 -0
- package/test/pics/p10/title-overflow.svg +1 -0
- package/test/pics/p10/valign.svg +1 -0
- package/test/pics/p10//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p10//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.svg +1 -0
- package/test/pics/p10//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p10//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.svg +1 -0
- package/test/pics/p10//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p10//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.svg +1 -0
- package/test/pics/p10//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p10//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.svg +1 -0
- package/test/pics/p10//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p10//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.svg +1 -0
- package/test/pics/p10//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p10//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.svg +1 -0
- package/test/pics/p10//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p10//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.svg +1 -0
- package/test/pics/p10//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p10//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.svg +1 -0
- package/test/pics/p10//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p10//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.svg +1 -0
- package/test/pics/p10//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p10//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.svg +1 -0
- package/test/pics/p10//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p10//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.svg +1 -0
- package/test/pics/p10//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p10//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.svg +1 -0
- package/test/pics/p2/cycle.png +0 -0
- package/test/pics/p2/deep-nest.png +0 -0
- package/test/pics/p2/diamond.png +0 -0
- package/test/pics/p2/edges-mix.png +0 -0
- package/test/pics/p2/english.png +0 -0
- package/test/pics/p2/flat-tb.png +0 -0
- package/test/pics/p2/fold-tall.png +0 -0
- package/test/pics/p2/fold-wide.png +0 -0
- package/test/pics/p2/group-edge.png +0 -0
- package/test/pics/p2/items-node.png +0 -0
- package/test/pics/p2/long-label.png +0 -0
- package/test/pics/p2/lr-flat.png +0 -0
- package/test/pics/p2/nested-group.png +0 -0
- package/test/pics/p2/no-edges.png +0 -0
- package/test/pics/p2/title-overflow.png +0 -0
- package/test/pics/p2/valign.png +0 -0
- package/test/pics/p2//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p2//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p2//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p2//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p2//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p2//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p2//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p2//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p2//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p2//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p2//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p2//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p3/cycle.png +0 -0
- package/test/pics/p3/deep-nest.png +0 -0
- package/test/pics/p3/diamond.png +0 -0
- package/test/pics/p3/edges-mix.png +0 -0
- package/test/pics/p3/english.png +0 -0
- package/test/pics/p3/flat-tb.png +0 -0
- package/test/pics/p3/fold-tall.png +0 -0
- package/test/pics/p3/fold-wide.png +0 -0
- package/test/pics/p3/group-edge.png +0 -0
- package/test/pics/p3/items-node.png +0 -0
- package/test/pics/p3/long-label.png +0 -0
- package/test/pics/p3/lr-flat.png +0 -0
- package/test/pics/p3/nested-group.png +0 -0
- package/test/pics/p3/no-edges.png +0 -0
- package/test/pics/p3/title-overflow.png +0 -0
- package/test/pics/p3/valign.png +0 -0
- package/test/pics/p3//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p3//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p3//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p3//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p3//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p3//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p3//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p3//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p3//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p3//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p3//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p3//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p4/cycle.png +0 -0
- package/test/pics/p4/deep-nest.png +0 -0
- package/test/pics/p4/diamond.png +0 -0
- package/test/pics/p4/edges-mix.png +0 -0
- package/test/pics/p4/english.png +0 -0
- package/test/pics/p4/flat-tb.png +0 -0
- package/test/pics/p4/fold-tall.png +0 -0
- package/test/pics/p4/fold-wide.png +0 -0
- package/test/pics/p4/group-edge.png +0 -0
- package/test/pics/p4/items-node.png +0 -0
- package/test/pics/p4/long-label.png +0 -0
- package/test/pics/p4/lr-flat.png +0 -0
- package/test/pics/p4/nested-group.png +0 -0
- package/test/pics/p4/no-edges.png +0 -0
- package/test/pics/p4/title-overflow.png +0 -0
- package/test/pics/p4/valign.png +0 -0
- package/test/pics/p4//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p4//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p4//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p4//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p4//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p4//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p4//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p4//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p4//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p4//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p4//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p4//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p5/cycle.png +0 -0
- package/test/pics/p5/deep-nest.png +0 -0
- package/test/pics/p5/diamond.png +0 -0
- package/test/pics/p5/edges-mix.png +0 -0
- package/test/pics/p5/english.png +0 -0
- package/test/pics/p5/flat-tb.png +0 -0
- package/test/pics/p5/fold-tall.png +0 -0
- package/test/pics/p5/fold-wide.png +0 -0
- package/test/pics/p5/group-edge.png +0 -0
- package/test/pics/p5/items-node.png +0 -0
- package/test/pics/p5/long-label.png +0 -0
- package/test/pics/p5/lr-flat.png +0 -0
- package/test/pics/p5/nested-group.png +0 -0
- package/test/pics/p5/no-edges.png +0 -0
- package/test/pics/p5/title-overflow.png +0 -0
- package/test/pics/p5/valign.png +0 -0
- package/test/pics/p5//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p5//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p5//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p5//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p5//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p5//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p5//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p5//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p5//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p5//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p5//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p5//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p6/cycle.png +0 -0
- package/test/pics/p6/deep-nest.png +0 -0
- package/test/pics/p6/diamond.png +0 -0
- package/test/pics/p6/edges-mix.png +0 -0
- package/test/pics/p6/english.png +0 -0
- package/test/pics/p6/flat-tb.png +0 -0
- package/test/pics/p6/fold-tall.png +0 -0
- package/test/pics/p6/fold-wide.png +0 -0
- package/test/pics/p6/group-edge.png +0 -0
- package/test/pics/p6/items-node.png +0 -0
- package/test/pics/p6/long-label.png +0 -0
- package/test/pics/p6/lr-flat.png +0 -0
- package/test/pics/p6/nested-group.png +0 -0
- package/test/pics/p6/no-edges.png +0 -0
- package/test/pics/p6/title-overflow.png +0 -0
- package/test/pics/p6/valign.png +0 -0
- package/test/pics/p6//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p6//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p6//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p6//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p6//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p6//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.alt.png +0 -0
- package/test/pics/p6//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.new.png +0 -0
- package/test/pics/p6//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p6//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p6//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p6//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p6//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p6//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p6//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p7/cycle.png +0 -0
- package/test/pics/p7/deep-nest.png +0 -0
- package/test/pics/p7/diamond.png +0 -0
- package/test/pics/p7/edges-mix.png +0 -0
- package/test/pics/p7/english.png +0 -0
- package/test/pics/p7/flat-tb.png +0 -0
- package/test/pics/p7/fold-tall.png +0 -0
- package/test/pics/p7/fold-wide.png +0 -0
- package/test/pics/p7/group-edge.png +0 -0
- package/test/pics/p7/items-node.png +0 -0
- package/test/pics/p7/long-label.png +0 -0
- package/test/pics/p7/lr-flat.png +0 -0
- package/test/pics/p7/nested-group.png +0 -0
- package/test/pics/p7/no-edges.png +0 -0
- package/test/pics/p7/title-overflow.png +0 -0
- package/test/pics/p7/valign.png +0 -0
- package/test/pics/p7//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p7//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p7//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p7//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p7//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p7//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p7//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p7//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p7//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p7//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p7//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p7//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p8/cycle.png +0 -0
- package/test/pics/p8/deep-nest.png +0 -0
- package/test/pics/p8/diamond.png +0 -0
- package/test/pics/p8/edges-mix.png +0 -0
- package/test/pics/p8/english.png +0 -0
- package/test/pics/p8/flat-tb.png +0 -0
- package/test/pics/p8/fold-tall.png +0 -0
- package/test/pics/p8/fold-wide.png +0 -0
- package/test/pics/p8/group-edge.png +0 -0
- package/test/pics/p8/items-node.png +0 -0
- package/test/pics/p8/long-label.png +0 -0
- package/test/pics/p8/lr-flat.png +0 -0
- package/test/pics/p8/nested-group.png +0 -0
- package/test/pics/p8/no-edges.png +0 -0
- package/test/pics/p8/title-overflow.png +0 -0
- package/test/pics/p8/valign.png +0 -0
- package/test/pics/p8//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p8//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p8//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p8//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p8//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p8//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p8//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p8//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p8//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p8//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p8//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p8//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p9/cycle.png +0 -0
- package/test/pics/p9/deep-nest.png +0 -0
- package/test/pics/p9/diamond.png +0 -0
- package/test/pics/p9/edges-mix.png +0 -0
- package/test/pics/p9/english.png +0 -0
- package/test/pics/p9/flat-tb.png +0 -0
- package/test/pics/p9/fold-tall.png +0 -0
- package/test/pics/p9/fold-wide.png +0 -0
- package/test/pics/p9/group-edge.png +0 -0
- package/test/pics/p9/items-node.png +0 -0
- package/test/pics/p9/long-label.png +0 -0
- package/test/pics/p9/lr-flat.png +0 -0
- package/test/pics/p9/nested-group.png +0 -0
- package/test/pics/p9/no-edges.png +0 -0
- package/test/pics/p9/title-overflow.png +0 -0
- package/test/pics/p9/valign.png +0 -0
- package/test/pics/p9//345/267/245/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p9//345/276/256/346/234/215/345/213/231/345/217/242/351/233/206/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p9//346/234/203/345/223/241/350/250/273/345/206/212/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p9//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics/p9//346/254/212/351/231/220/350/247/222/350/211/262/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics/p9//347/211/251/350/201/257/347/266/262/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p9//347/263/273/347/265/261/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p9//350/250/202/345/226/256/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p9//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.png +0 -0
- package/test/pics/p9//350/263/207/346/226/231/346/270/205/346/264/227/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics/p9//351/233/273/345/225/206/345/271/263/345/217/260/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics/p9//351/240/201/351/235/242/345/260/216/350/246/275/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/snapshot.mjs +67 -0
- package/test/wflowchart.test.mjs +57 -11
- package/toolg/gDistRollup.mjs +3 -0
- package/test/data//344/275/234/346/245/255/346/265/201/347/250/213/345/234/226.json +0 -92
- package/test/data//345/211/215/347/253/257/346/236/266/346/247/213/350/210/207/350/263/207/346/226/231/346/265/201/345/234/226.json +0 -112
- package/test/data//345/276/214/347/253/257/346/234/215/345/213/231/347/265/204/346/210/220/345/234/226.json +0 -116
- package/test/data//346/211/271/346/254/241/344/270/212/345/202/263/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.json +0 -251
- package/test/data//347/250/213/345/274/217/345/205/203/344/273/266/347/265/204/346/210/220/345/234/226.json +0 -126
- package/test/data//347/250/213/345/274/217/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.json +0 -133
- package/test/data//347/263/273/347/265/261/346/236/266/346/247/213/345/234/226.json +0 -102
- package/test/data//347/263/273/347/265/261/351/227/234/350/201/257/345/234/226.json +0 -117
- package/test/data//347/267/232/344/270/212/347/225/253/351/235/242/351/227/234/350/201/257/345/234/226.json +0 -162
- package/test/pics/cycle.png +0 -0
- package/test/pics/cycle.svg +0 -1
- package/test/pics/deep-nest.svg +0 -1
- package/test/pics/diamond.png +0 -0
- package/test/pics/diamond.svg +0 -1
- package/test/pics/edges-mix.png +0 -0
- package/test/pics/edges-mix.svg +0 -1
- package/test/pics/english.png +0 -0
- package/test/pics/english.svg +0 -1
- package/test/pics/flat-tb.svg +0 -1
- package/test/pics/fold-tall.svg +0 -1
- package/test/pics/fold-wide.svg +0 -1
- package/test/pics/group-edge.png +0 -0
- package/test/pics/group-edge.svg +0 -1
- package/test/pics/items-node.svg +0 -1
- package/test/pics/long-label.svg +0 -1
- package/test/pics/lr-flat.svg +0 -1
- package/test/pics/nested-group.png +0 -0
- package/test/pics/nested-group.svg +0 -1
- package/test/pics/no-edges.svg +0 -1
- package/test/pics/title-overflow.svg +0 -1
- package/test/pics/valign.svg +0 -1
- package/test/pics//344/275/234/346/245/255/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics//344/275/234/346/245/255/346/265/201/347/250/213/345/234/226.svg +0 -1
- package/test/pics//345/211/215/347/253/257/346/236/266/346/247/213/350/210/207/350/263/207/346/226/231/346/265/201/345/234/226.png +0 -0
- package/test/pics//345/211/215/347/253/257/346/236/266/346/247/213/350/210/207/350/263/207/346/226/231/346/265/201/345/234/226.svg +0 -1
- package/test/pics//345/276/214/347/253/257/346/234/215/345/213/231/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics//345/276/214/347/253/257/346/234/215/345/213/231/347/265/204/346/210/220/345/234/226.svg +0 -1
- package/test/pics//346/211/271/346/254/241/344/270/212/345/202/263/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.png +0 -0
- package/test/pics//346/211/271/346/254/241/344/270/212/345/202/263/350/231/225/347/220/206/346/265/201/347/250/213/345/234/226.svg +0 -1
- package/test/pics//347/250/213/345/274/217/345/205/203/344/273/266/347/265/204/346/210/220/345/234/226.png +0 -0
- package/test/pics//347/250/213/345/274/217/345/205/203/344/273/266/347/265/204/346/210/220/345/234/226.svg +0 -1
- package/test/pics//347/250/213/345/274/217/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics//347/250/213/345/274/217/345/210/206/345/261/244/346/236/266/346/247/213/345/234/226.svg +0 -1
- package/test/pics//347/263/273/347/265/261/346/236/266/346/247/213/345/234/226.png +0 -0
- package/test/pics//347/263/273/347/265/261/346/236/266/346/247/213/345/234/226.svg +0 -1
- package/test/pics//347/263/273/347/265/261/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics//347/263/273/347/265/261/351/227/234/350/201/257/345/234/226.svg +0 -1
- package/test/pics//347/267/232/344/270/212/347/225/253/351/235/242/351/227/234/350/201/257/345/234/226.png +0 -0
- package/test/pics//347/267/232/344/270/212/347/225/253/351/235/242/351/227/234/350/201/257/345/234/226.svg +0 -1
- /package/test/pics/{deep-nest.png → p10/deep-nest.png} +0 -0
- /package/test/pics/{flat-tb.png → p10/flat-tb.png} +0 -0
- /package/test/pics/{fold-tall.png → p10/fold-tall.png} +0 -0
- /package/test/pics/{fold-wide.png → p10/fold-wide.png} +0 -0
- /package/test/pics/{items-node.png → p10/items-node.png} +0 -0
- /package/test/pics/{long-label.png → p10/long-label.png} +0 -0
- /package/test/pics/{lr-flat.png → p10/lr-flat.png} +0 -0
- /package/test/pics/{no-edges.png → p10/no-edges.png} +0 -0
- /package/test/pics/{title-overflow.png → p10/title-overflow.png} +0 -0
- /package/test/pics/{valign.png → p10/valign.png} +0 -0
package/package.json
CHANGED
|
@@ -1,49 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "w-flowchart",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"main": "dist/w-flowchart.umd.js",
|
|
5
|
-
"dependencies": {
|
|
6
|
-
"@antv/
|
|
7
|
-
"@
|
|
8
|
-
"@
|
|
9
|
-
"@
|
|
10
|
-
"@
|
|
11
|
-
"@
|
|
12
|
-
"@
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "w-flowchart",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"main": "dist/w-flowchart.umd.js",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@antv/g-lite": "^2.7.0",
|
|
7
|
+
"@antv/g-svg": "^2.1.1",
|
|
8
|
+
"@antv/g6": "^5.1.1",
|
|
9
|
+
"@dagrejs/dagre": "^1.1.8",
|
|
10
|
+
"@joint/core": "^4.3.0",
|
|
11
|
+
"@logicflow/core": "^2.2.4",
|
|
12
|
+
"@mermaid-js/layout-elk": "^0.2.2",
|
|
13
|
+
"@terrastruct/d2": "0.1.33",
|
|
14
|
+
"@xyflow/react": "^12.11.2",
|
|
15
|
+
"cytoscape": "^3.34.0",
|
|
16
|
+
"cytoscape-dagre": "^4.0.0",
|
|
17
|
+
"cytoscape-svg": "^0.4.0",
|
|
18
|
+
"dagre": "^0.8.5",
|
|
19
|
+
"elkjs": "^0.11.1",
|
|
20
|
+
"graphre": "^0.1.3",
|
|
21
|
+
"lodash-es": "^4.18.1",
|
|
22
|
+
"mermaid10": "npm:mermaid@^10.9.6",
|
|
23
|
+
"mermaid11": "npm:mermaid@^11.16.0",
|
|
24
|
+
"nomnoml": "^1.7.0",
|
|
25
|
+
"playwright": "^1.61.1",
|
|
26
|
+
"react": "^18.3.1",
|
|
27
|
+
"react-dom": "^18.3.1",
|
|
28
|
+
"sharp": "0.35.3",
|
|
29
|
+
"wsemi": "^1.8.64"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"pixelmatch": "^7.2.0",
|
|
33
|
+
"pngjs": "^7.0.0",
|
|
34
|
+
"w-package-tools": "^1.1.10"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"test": "mocha --parallel --timeout 60000",
|
|
38
|
+
"deploy": "gh-pages -d docs"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/yuda-lyu/w-flowchart.git"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"package",
|
|
46
|
+
"tool",
|
|
47
|
+
"flowchart",
|
|
48
|
+
"nodejs"
|
|
49
|
+
],
|
|
50
|
+
"author": "yuda-lyu(semisphere)",
|
|
51
|
+
"license": "MIT"
|
|
52
|
+
}
|
package/src/WFlowchart.mjs
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// WFlowchart — 統一產圖入口: 輸入正規化繪圖數據 inp, 產出 PNG 圖
|
|
2
|
+
// inp: 正規化繪圖數據 { dir, nodes, edges }(與繪圖庫無關, 結構同 test/data/*.json; cls 見 common/palette.mjs)
|
|
3
|
+
// opt.mode: 'p1'~'p10', 各對應一套產線(繪圖引擎與佈局各異, 見各 pN/gen.mjs 檔頭說明), 預設 'p10'
|
|
4
|
+
// p1: mermaid(dagre) p2: mermaid(ELK) p3: nomnoml p4: cytoscape(dagre)
|
|
5
|
+
// p5: D2 p6: G6(antv-dagre) p7: JointJS(dagre) p8: LogicFlow(dagre)
|
|
6
|
+
// p9: dagre 自寫渲染 p10: ELK 自寫渲染
|
|
7
|
+
// 回傳: Promise<Buffer>(PNG)
|
|
8
|
+
import get from 'lodash-es/get.js'
|
|
9
|
+
import cloneDeep from 'lodash-es/cloneDeep.js'
|
|
10
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
11
|
+
import iseobj from 'wsemi/src/iseobj.mjs'
|
|
12
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
13
|
+
import isarr from 'wsemi/src/isarr.mjs'
|
|
14
|
+
import { deriveLabels } from './common/derive.mjs'
|
|
15
|
+
|
|
16
|
+
// 引擎延遲載入: 各產線依 opt.mode 動態 import(), 使用者只為所選產線付出依賴成本
|
|
17
|
+
// (各 pN 模組層即讀取其繪圖庫 bundle 檔; p5 另載入 @terrastruct/d2 與 sharp, 其上游缺陷不影響其他產線)
|
|
18
|
+
const LOADERS = {
|
|
19
|
+
p1: () => import('./p1/gen.mjs'),
|
|
20
|
+
p2: () => import('./p2/gen.mjs'),
|
|
21
|
+
p3: () => import('./p3/gen.mjs'),
|
|
22
|
+
p4: () => import('./p4/gen.mjs'),
|
|
23
|
+
p5: () => import('./p5/gen.mjs'),
|
|
24
|
+
p6: () => import('./p6/gen.mjs'),
|
|
25
|
+
p7: () => import('./p7/gen.mjs'),
|
|
26
|
+
p8: () => import('./p8/gen.mjs'),
|
|
27
|
+
p9: () => import('./p9/gen.mjs'),
|
|
28
|
+
p10: () => import('./p10/gen.mjs'),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// svg 輸出: p1/p2/p3/p5/p10 引擎原生輸出 SVG 字串; p7/p8 為 SVG DOM 序列化(樣式已內嵌);
|
|
32
|
+
// p4 經 cytoscape-svg 外掛、p6 經 @antv/g-svg renderer 重繪為 SVG(皆經像素級忠實度驗證);
|
|
33
|
+
// p9 節點為 React Flow 之 HTML DOM, 無忠實 SVG 可產 → 不支援
|
|
34
|
+
const SVG_MODES = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p10']
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 產製流程圖 PNG
|
|
38
|
+
*
|
|
39
|
+
* @param {Object} inp 輸入正規化繪圖數據物件,格式 { dir, nodes, edges },與繪圖引擎無關
|
|
40
|
+
* @param {String} [inp.dir='TB'] 輸入佈局方向字串,可選 'TB'(上而下)或 'LR'(左而右),預設 'TB'
|
|
41
|
+
* @param {Array} inp.nodes 輸入節點陣列,每項為一般節點 { id, label, cls, group? } 或富節點 { id, title, items, cls, group? };cls 為色票鍵(見 src/common/palette.mjs),結尾 G/G2 者為群組容器,group 為所屬容器 id(容器可巢狀)
|
|
42
|
+
* @param {Array} inp.edges 輸入邊陣列,每項為 { from, to, label?, kind? },kind 給 'dashed' 為虛線
|
|
43
|
+
* @param {Object} [opt={}] 輸入設定物件,原樣傳遞給產線,預設 {}
|
|
44
|
+
* @param {String} [opt.mode='p10'] 輸入產線模式字串,可選 'p1'~'p10',各對應一套繪圖引擎產線(技術概念見各 src/pN/README.md),未指定或非有效字串時預設 'p10'
|
|
45
|
+
* @param {String} [opt.output='png'] 輸入輸出格式字串,可選 'png'(回傳 PNG Buffer)或 'svg'(回傳 standalone SVG 字串),未指定或非有效字串時預設 'png';svg 支援 p1~p8 與 p10,p9(React Flow 之 HTML DOM 渲染)不支援,給 svg 會拋錯
|
|
46
|
+
* @returns {Promise} 回傳 Promise,resolve 依 opt.output 回傳 PNG 圖之 Buffer 或 SVG 字串,reject 回傳錯誤訊息
|
|
47
|
+
* @example
|
|
48
|
+
*
|
|
49
|
+
* import fs from 'fs'
|
|
50
|
+
* import WFlowchart from 'w-flowchart'
|
|
51
|
+
*
|
|
52
|
+
* let inp = {
|
|
53
|
+
* dir: 'TB',
|
|
54
|
+
* nodes: [
|
|
55
|
+
* { id: 'A', label: '開始', cls: 'blue' },
|
|
56
|
+
* { id: 'G', label: '處理群組', cls: 'greenG' },
|
|
57
|
+
* { id: 'B', label: '步驟一', cls: 'green', group: 'G' },
|
|
58
|
+
* { id: 'C', title: '服務', items: ['項目一', '項目二'], cls: 'green', group: 'G' },
|
|
59
|
+
* { id: 'D', label: '判斷?', cls: 'diamond' },
|
|
60
|
+
* { id: 'E', label: '結束', cls: 'orange' },
|
|
61
|
+
* ],
|
|
62
|
+
* edges: [
|
|
63
|
+
* { from: 'A', to: 'B' },
|
|
64
|
+
* { from: 'B', to: 'C', label: '呼叫' },
|
|
65
|
+
* { from: 'C', to: 'D' },
|
|
66
|
+
* { from: 'D', to: 'E', label: '通過' },
|
|
67
|
+
* { from: 'D', to: 'B', kind: 'dashed', label: '退回' },
|
|
68
|
+
* ],
|
|
69
|
+
* }
|
|
70
|
+
*
|
|
71
|
+
* let buf = await WFlowchart(inp) //預設 mode 'p10'; 可用 WFlowchart(inp, { mode: 'p3' }) 指定產線
|
|
72
|
+
* fs.writeFileSync('flowchart.png', buf)
|
|
73
|
+
* // => 產出 flowchart.png
|
|
74
|
+
*
|
|
75
|
+
* let svg = await WFlowchart(inp, { output: 'svg' }) //輸出 standalone SVG 字串(p9 不支援)
|
|
76
|
+
* fs.writeFileSync('flowchart.svg', svg)
|
|
77
|
+
* // => 產出 flowchart.svg
|
|
78
|
+
*/
|
|
79
|
+
async function WFlowchart(inp, opt = {}) {
|
|
80
|
+
let mode = get(opt, 'mode')
|
|
81
|
+
if (!isestr(mode)) mode = 'p10' //未指定或非有效字串時預設 p10
|
|
82
|
+
const m = mode.trim().toLowerCase()
|
|
83
|
+
if (!LOADERS[m]) throw new Error(`invalid opt.mode[${mode}], 須為 ${Object.keys(LOADERS).join(', ')} 之一`)
|
|
84
|
+
let output = get(opt, 'output')
|
|
85
|
+
if (!isestr(output)) output = 'png' //未指定或非有效字串時預設 png
|
|
86
|
+
const o = output.trim().toLowerCase()
|
|
87
|
+
if (o !== 'png' && o !== 'svg') throw new Error(`invalid opt.output[${output}], 須為 png 或 svg`)
|
|
88
|
+
if (o === 'svg' && !SVG_MODES.includes(m)) throw new Error(`mode[${m}] 不支援 svg 輸出, 支援: ${SVG_MODES.join(', ')}`)
|
|
89
|
+
if (!iseobj(inp)) throw new Error('invalid inp, 須為 { dir, nodes, edges } 正規化繪圖數據')
|
|
90
|
+
if (!isearr(inp.nodes)) throw new Error('invalid inp.nodes, 須為非空陣列')
|
|
91
|
+
if (!isarr(inp.edges)) throw new Error('invalid inp.edges, 須為陣列')
|
|
92
|
+
const data = deriveLabels(cloneDeep(inp)) //deriveLabels 會就地改動, 先複製避免污染 caller 之 inp
|
|
93
|
+
const gen = await LOADERS[m]() //檢核全過才載入所選產線引擎(延遲載入)
|
|
94
|
+
return await (o === 'svg' ? gen.genSvg : gen.genPng)(data, opt)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export default WFlowchart
|
package/src/p1/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## 技術核心
|
|
4
4
|
|
|
5
5
|
- **繪圖庫**: mermaid 第 10 版系列(package.json 以 npm alias `mermaid10` 安裝,與 p2 之第 11 版系列並存),透過 `common/pkg.mjs` 的 `pkgScript('mermaid10/dist/mermaid.min.js')` 讀取本機 `node_modules` 內容並內聯注入 `<script>` 標籤,於 Playwright 開啟的 Chromium 頁面內執行;不經 CDN,斷網環境亦可運作。
|
|
6
|
-
- **渲染方式**: `
|
|
6
|
+
- **渲染方式**: 內部 `renderFigPage()` 為每次渲染建立獨立的 Playwright `page`(`browser.newPage()`),避免 mermaid 內部 render id 衝突。將 `mermaidHtml()` 產生的 HTML 字串以 `page.setContent()` 注入,等待 `document.title === 'DONE'` 確認渲染完成(或 `FAIL` 時拋出錯誤),再以 `page.waitForFunction` 超時 30 秒防呆。
|
|
7
7
|
- **截圖目標**: `page.locator('#box svg').screenshot()`,只截 SVG 元素本身,不含外層 `div#box` 的 padding 背景。
|
|
8
8
|
- **解析度**: `deviceScaleFactor: 4`,Chromium 以 4 倍畫素密度渲染 SVG 向量圖,輸出 PNG 清晰度極高,適合印刷品質報告。
|
|
9
9
|
- **字型**: HTML `<body>` 及 mermaid `themeVariables.fontFamily` 均指定 `'微軟正黑體','Microsoft JhengHei',sans-serif`;截圖前以 `page.evaluate(() => document.fonts.ready)` 確保字型載入完成。
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
### 對外介面
|
|
46
46
|
|
|
47
|
-
-
|
|
47
|
+
- 產線對外介面為 `genPng(data, opt)` 與 `genSvg(data, opt)`,`data` 為正規化繪圖數據 `{ dir, nodes, edges }`;`genPng` 回傳 `Promise<Buffer>`(PNG),`genSvg` 回傳 standalone SVG 字串(引擎原生輸出、依 viewBox 寫死寬高、` ` 正規化為 ` `);兩者皆自帶瀏覽器生命週期(`chromium.launch()` → 渲染 → `browser.close()`),呼叫端不需自行管理 Playwright。
|
|
48
48
|
- 統一由 `src/WFlowchart.mjs` 依 `mode === 'p1'` 呼叫,不提供批次流程或落地寫檔行為,是否寫檔、寫至何處由呼叫端決定。
|
|
49
49
|
|
|
50
50
|
## 自動化機制
|
package/src/p1/gen.mjs
CHANGED
|
@@ -8,11 +8,11 @@ import { pkgScript } from '../common/pkg.mjs'
|
|
|
8
8
|
// mermaid@10 由本機 node_modules 內聯注入(取代 CDN, 斷網環境可用)
|
|
9
9
|
const MERMAID_JS = pkgScript('mermaid10/dist/mermaid.min.js')
|
|
10
10
|
|
|
11
|
-
// 把標準節點 label 轉成 mermaid 節點形狀語法
|
|
11
|
+
// 把標準節點 label 轉成 mermaid 節點形狀語法(id 經 qid 消歧)
|
|
12
12
|
// diamond → {label} / 其餘 → ["label"]
|
|
13
|
-
function nodeShape(nd) {
|
|
14
|
-
if (nd.cls === 'diamond') return `${nd.id}{"${nd.label}"}`
|
|
15
|
-
return `${nd.id}["${nd.label}"]`
|
|
13
|
+
function nodeShape(nd, qid) {
|
|
14
|
+
if (nd.cls === 'diamond') return `${qid(nd.id)}{"${nd.label}"}`
|
|
15
|
+
return `${qid(nd.id)}["${nd.label}"]`
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// 正規化數據 → mermaid flowchart DSL 字串
|
|
@@ -27,6 +27,20 @@ function nodeShape(nd) {
|
|
|
27
27
|
function translate(data) {
|
|
28
28
|
const { dir, nodes, edges } = data
|
|
29
29
|
|
|
30
|
+
// mermaid 保留字(end/click/style/class/subgraph/direction 等)不可作節點 id → 一律加前綴消歧
|
|
31
|
+
// 僅影響 DSL 內部識別(顯示文字仍用 label); 不同原 id 淨化後若同名, 以序號區隔避免節點被合併
|
|
32
|
+
const used = new Set()
|
|
33
|
+
const qidMap = {}
|
|
34
|
+
const qid = (id) => {
|
|
35
|
+
if (qidMap[id]) return qidMap[id]
|
|
36
|
+
const base = 'n_' + String(id).replace(/[^A-Za-z0-9_]/g, '_')
|
|
37
|
+
let q = base, k = 2
|
|
38
|
+
while (used.has(q)) q = base + '_' + (k++)
|
|
39
|
+
used.add(q)
|
|
40
|
+
qidMap[id] = q
|
|
41
|
+
return q
|
|
42
|
+
}
|
|
43
|
+
|
|
30
44
|
// 索引: id → node
|
|
31
45
|
const byId = {}
|
|
32
46
|
for (const nd of nodes) byId[nd.id] = nd
|
|
@@ -59,7 +73,7 @@ function translate(data) {
|
|
|
59
73
|
}
|
|
60
74
|
const classLines = []
|
|
61
75
|
for (const [cls, ids] of Object.entries(clsToIds)) {
|
|
62
|
-
classLines.push(` class ${ids.join(',')} ${cls}`)
|
|
76
|
+
classLines.push(` class ${ids.map(qid).join(',')} ${cls}`)
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
// 拓樸: 哪些節點直接屬於哪個容器(含巢狀)
|
|
@@ -73,11 +87,11 @@ function translate(data) {
|
|
|
73
87
|
function renderSubgraph(gid, indent) {
|
|
74
88
|
const g = byId[gid]
|
|
75
89
|
const lines = []
|
|
76
|
-
lines.push(`${indent}subgraph ${gid}["${g.label}"]`)
|
|
90
|
+
lines.push(`${indent}subgraph ${qid(gid)}["${g.label}"]`)
|
|
77
91
|
// 直接子節點(非容器)
|
|
78
92
|
const directChildren = nodes.filter(nd => nd.group === gid && !isGroupCls(nd.cls))
|
|
79
93
|
for (const nd of directChildren) {
|
|
80
|
-
lines.push(`${indent} ${nodeShape(nd)}`)
|
|
94
|
+
lines.push(`${indent} ${nodeShape(nd, qid)}`)
|
|
81
95
|
}
|
|
82
96
|
// 巢狀容器(容器的 group === gid)
|
|
83
97
|
const nestedGroups = nodes.filter(nd => isGroupCls(nd.cls) && nd.group === gid)
|
|
@@ -93,14 +107,14 @@ function translate(data) {
|
|
|
93
107
|
for (const ed of edges) {
|
|
94
108
|
const arrow = ed.kind === 'dashed' ? '-..->' : '-->'
|
|
95
109
|
const lbl = ed.label ? `|"${ed.label}"| ` : ''
|
|
96
|
-
edgeLines.push(` ${ed.from} ${arrow} ${lbl}${ed.to}`)
|
|
110
|
+
edgeLines.push(` ${qid(ed.from)} ${arrow} ${lbl}${qid(ed.to)}`)
|
|
97
111
|
}
|
|
98
112
|
|
|
99
113
|
// 組裝 DSL
|
|
100
114
|
const lines = [`flowchart ${dir}`]
|
|
101
115
|
// 1. 獨立節點
|
|
102
116
|
for (const nd of standaloneNodes) {
|
|
103
|
-
lines.push(` ${nodeShape(nd)}`)
|
|
117
|
+
lines.push(` ${nodeShape(nd, qid)}`)
|
|
104
118
|
}
|
|
105
119
|
// 2. 頂層 subgraph
|
|
106
120
|
for (const gid of topGroupIds) {
|
|
@@ -169,35 +183,55 @@ mermaid.initialize({ startOnLoad:false, theme:'base', themeVariables:{ fontFamil
|
|
|
169
183
|
</script></body></html>`
|
|
170
184
|
}
|
|
171
185
|
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const page = await browser.newPage({ deviceScaleFactor: 4 })
|
|
186
|
+
// 渲染單張至就緒頁面(mermaid DONE + 字型就緒), deviceScaleFactor:4(向量圖放大提高清晰度); caller 負責 close browser
|
|
187
|
+
async function renderFigPage(code) {
|
|
188
|
+
const browser = await chromium.launch()
|
|
176
189
|
try {
|
|
190
|
+
const page = await browser.newPage({ deviceScaleFactor: 4 })
|
|
177
191
|
await page.setContent(mermaidHtml(code), { waitUntil: 'load' })
|
|
178
192
|
await page.waitForFunction(() => document.title === 'DONE' || document.title === 'FAIL', { timeout: 30000 })
|
|
179
193
|
const title = await page.title()
|
|
180
194
|
if (title !== 'DONE') {
|
|
181
195
|
const msg = await page.evaluate(() => { const el = document.getElementById('box'); return el ? el.innerText : '' })
|
|
182
|
-
throw new Error(`mermaid render failed
|
|
196
|
+
throw new Error(`mermaid render failed: ${msg}`)
|
|
183
197
|
}
|
|
184
198
|
await page.evaluate(() => document.fonts.ready)
|
|
185
|
-
return
|
|
199
|
+
return { browser, page }
|
|
186
200
|
}
|
|
187
|
-
|
|
188
|
-
await
|
|
201
|
+
catch (err) {
|
|
202
|
+
await browser.close()
|
|
203
|
+
throw err
|
|
189
204
|
}
|
|
190
205
|
}
|
|
191
206
|
|
|
192
207
|
// 單張渲染 → PNG Buffer(供 WFlowchart 統一入口呼叫; 自帶瀏覽器生命週期)
|
|
193
208
|
async function genPng(data, opt = {}) {
|
|
194
|
-
const browser = await
|
|
209
|
+
const { browser, page } = await renderFigPage(translate(data))
|
|
210
|
+
try {
|
|
211
|
+
return await page.locator('#box svg').screenshot()
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
await browser.close()
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 單張渲染 → SVG 字串(#box 內後處理完成之 SVG; 正規化為   使其為合法 standalone SVG)
|
|
219
|
+
// mermaid 之 svg 為響應式(width:100% + max-width), 脫離頁面尺寸會漂移 → 序列化前依 viewBox 寫死 width/height
|
|
220
|
+
async function genSvg(data, opt = {}) {
|
|
221
|
+
const { browser, page } = await renderFigPage(translate(data))
|
|
195
222
|
try {
|
|
196
|
-
return await
|
|
223
|
+
return (await page.evaluate(() => {
|
|
224
|
+
const el = document.querySelector('#box svg')
|
|
225
|
+
const vb = el.viewBox.baseVal
|
|
226
|
+
el.style.maxWidth = 'none'
|
|
227
|
+
el.setAttribute('width', Math.ceil(vb.width))
|
|
228
|
+
el.setAttribute('height', Math.ceil(vb.height))
|
|
229
|
+
return document.getElementById('box').innerHTML
|
|
230
|
+
})).replace(/ /g, ' ').trim()
|
|
197
231
|
}
|
|
198
232
|
finally {
|
|
199
233
|
await browser.close()
|
|
200
234
|
}
|
|
201
235
|
}
|
|
202
236
|
|
|
203
|
-
export { genPng }
|
|
237
|
+
export { genPng, genSvg }
|
package/src/p10/README.md
CHANGED
|
@@ -6,7 +6,7 @@ p1~p9 為現成繪圖套件;**p10 是唯一「自寫 SVG 渲染器」產線**:
|
|
|
6
6
|
|
|
7
7
|
- **佈局引擎**:`elkjs`(Eclipse Layout Kernel 的 JS 版,`elk.bundled.js` UMD 主執行緒、免 worker),由本機 `node_modules` 讀出後於 `gen.mjs` 模組載入時以 `common/pkg.mjs` 的 `pkgScript` 內聯注入 `PAGE_HTML`(取代 CDN,斷網環境可用),於 Playwright headless 頁內執行。`new ELK().layout(graph)` 回傳各節點/容器之座標尺寸與各邊之 sections(轉折點)。
|
|
8
8
|
- **渲染**:本產線**自行把 ELK 結果組成 SVG 字串**(rect / polygon 菱形 / path 折線 + 箭頭 / foreignObject 文字),插入頁面後對 `#stage svg` 截圖。`deviceScaleFactor:2`。中文以 `foreignObject` 內 div 渲染(瀏覽器原生量字、不爆框)。
|
|
9
|
-
- **呼叫入口**:`export async function genPng(data, opt = {})`
|
|
9
|
+
- **呼叫入口**:`export async function genPng(data, opt = {})` 與 `export async function genSvg(data, opt = {})` 為對外介面,`genPng` 回傳 `Promise<Buffer>`(PNG),`genSvg` 回傳本產線自組之 standalone SVG 字串(`#stage` 內容,` ` 正規化為 ` `);由 `src/WFlowchart.mjs` 之 `GENS.p10` 統一調用(`mode: 'p10'`)。`data` 為正規化繪圖數據 `{ dir, nodes, edges }`;`opt` 保留擴充,目前原樣接收但未使用。`gen.mjs` 另外 `export function translate` 與 `export const PAGE_HTML`,供 `test/`(結構不變量 + 快照回歸測試)重用真實管線(不複製渲染器)。
|
|
10
10
|
|
|
11
11
|
## 產製原理(資料驅動)
|
|
12
12
|
|
|
@@ -23,9 +23,13 @@ p1~p9 為現成繪圖套件;**p10 是唯一「自寫 SVG 渲染器」產線**:
|
|
|
23
23
|
- **字型全覆蓋**:所有 SVG 文字(節點/容器標題/邊標籤)走 `foreignObject` + `font-family:Microsoft JhengHei`,無遺漏、不爆框。
|
|
24
24
|
- **邊標籤白光暈**:邊標籤 div 以多向 `text-shadow` 白光暈(`EDGE.haloColor/haloWidth`),透明底、不遮線。
|
|
25
25
|
- **菱形標籤置中**:菱形以 polygon 畫、標籤 foreignObject 置中於外接框,天然置中(優於 vis 需 vadjust 硬調)。
|
|
26
|
+
- **菱形端點貼齊(共進共出)**:ELK 以外接矩形算邊端點,落在矩形邊上非頂點處會與菱形斜邊「空接」。依「側」(上/下/左/右)獨立處理:**出**→一律由該側「頂點」出發,多條共用首段後於各自高度 90 度轉出(分岔);**進**→該側無出時全部匯入「頂點」(各自橫移至中軸共用末段,箭頭重合),該側有出時依「半側」匯入該半側「斜邊中點」(頂點讓給出,進出不同點)。正交線交叉允許存在(正交路由常態),一致性優先。13 種進出組合由測試之單元驗證逐一把關(其中「同半側」類組合受 ELK 埠序限制,乾淨合成圖排不出,僅能在函式層驗證)。
|
|
27
|
+
- **正交路徑化簡(碰撞偵測把關)**:ELK 階層邊(`INCLUDE_CHILDREN`)偶發「先繞反方向再折返」的 S/U 形繞行(跨容器回邊尤甚)。渲染前對每條路徑反覆嘗試把「平行-垂直-平行」三段窗收斂為兩段,僅在碰撞偵測全過才接受:不撞節點框/容器標題帶/邊標籤、不與他邊平行段貼齊併線;端點段軸向與方向不可翻轉(維持節點進出方向,先於菱形貼齊執行故不干擾其規則);邊標籤若因化簡脫離路徑則整段還原。已極簡之路徑零誤觸。
|
|
26
28
|
- 版面間距為通用常數(`elk.spacing.*`),尺寸由內容自然決定,無逐圖魔術數字。
|
|
27
29
|
|
|
28
30
|
## 已知限制
|
|
29
31
|
|
|
30
|
-
- **循環(回邊)起點**:ELK 的斷環點不一定讓「流程起點」落在最上(
|
|
32
|
+
- **循環(回邊)起點**:ELK 的斷環點不一定讓「流程起點」落在最上(如流程的「退回」迴圈),屬版面取捨、非錯誤(可調 ELK cycle-breaking 選項)。
|
|
31
33
|
- **線性長鏈**:純線性流程(如批次)會被拉得較高(與 dagre 系一致)。
|
|
34
|
+
- **A4 折排容器不可含內部循環**:被自動折排(`elk.aspectRatio` + `SINGLE_EDGE` wrapping)挑中的容器,若其內部邊集含循環,折排結果不穩定,部分節點數組合會令 elkjs 內部拋例外(`IndexOutOfBoundsException` / `NoSuchElementException`)。實測經驗法則:讓會被折排的容器內部保持無環、單一入出口,退回/重試循環放在該容器之外或小型巢狀子群組內。
|
|
35
|
+
- **二層巢狀 + 密集帶標籤邊之組合**:巢狀子群組內有「4+ 節點直鏈且 3+ 連續帶標籤邊」,或「子群組內部帶標籤/分支邊 + 同深度姊妹群組間直連邊」之組合,部分情況會觸發 elkjs 內部例外。繞法:讓功能區群組各自獨立成鏈/分支,跨區以共用之獨立葉節點中繼,或改用群組↔群組邊。
|