w-flowchart 1.0.1 → 1.0.3
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 +2 -0
- package/dist/w-flowchart.umd.js +2 -2
- package/dist/w-flowchart.umd.js.map +1 -1
- package/docs/WFlowchart.mjs.html +22 -39
- package/docs/global.html +4 -4
- package/docs/index.html +1 -1
- package/package.json +1 -1
- package/src/WFlowchart.mjs +20 -37
- package/src/p1/gen.mjs +8 -4
- package/src/p10/gen.mjs +8 -7
- package/src/p3/gen.mjs +14 -8
- package/src/p4/gen.mjs +1 -1
- package/src/p5/gen.mjs +6 -4
- package/src/p7/gen.mjs +14 -9
- package/src/p8/gen.mjs +2 -1
- package/src/p9/gen.mjs +14 -7
- package/test/cases.mjs +82 -1
- package/test/pics/p1/newline-label.png +0 -0
- package/test/pics/p1/newline-lr.png +0 -0
- package/test/pics/p1/newline-multi.png +0 -0
- package/test/pics/p10/cycle.svg +1 -1
- package/test/pics/p10/deep-nest.svg +1 -1
- package/test/pics/p10/dia-1in-1out.svg +1 -1
- package/test/pics/p10/dia-1in-2out.svg +1 -1
- package/test/pics/p10/dia-1in.svg +1 -1
- package/test/pics/p10/dia-1out.svg +1 -1
- package/test/pics/p10/dia-2in-1out.svg +1 -1
- package/test/pics/p10/dia-2in-2out-dd.svg +1 -1
- package/test/pics/p10/dia-2in-2out-ss.svg +1 -1
- package/test/pics/p10/dia-2in.svg +1 -1
- package/test/pics/p10/dia-2out.svg +1 -1
- package/test/pics/p10/diamond.svg +1 -1
- package/test/pics/p10/edges-mix.svg +1 -1
- package/test/pics/p10/english.svg +1 -1
- package/test/pics/p10/flat-tb.svg +1 -1
- package/test/pics/p10/fold-tall.svg +1 -1
- package/test/pics/p10/fold-wide.svg +1 -1
- package/test/pics/p10/group-edge.svg +1 -1
- package/test/pics/p10/items-node.svg +1 -1
- package/test/pics/p10/long-label.svg +1 -1
- package/test/pics/p10/lr-flat.svg +1 -1
- package/test/pics/p10/nested-group.svg +1 -1
- package/test/pics/p10/newline-label.png +0 -0
- package/test/pics/p10/newline-label.svg +5 -0
- package/test/pics/p10/newline-lr.png +0 -0
- package/test/pics/p10/newline-lr.svg +7 -0
- package/test/pics/p10/newline-multi.png +0 -0
- package/test/pics/p10/newline-multi.svg +7 -0
- package/test/pics/p10/no-edges.svg +1 -1
- package/test/pics/p10/title-overflow.svg +1 -1
- package/test/pics/p10/valign.svg +1 -1
- 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 -1
- 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 -1
- 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 -1
- package/test/pics/p10//346/250/241/347/265/204/347/265/204/346/210/220/345/234/226.svg +1 -1
- 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 -1
- 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 -1
- 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 -1
- 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 -1
- package/test/pics/p10//350/263/207/346/226/231/346/265/201/345/220/221/345/234/226.svg +1 -1
- 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 -1
- 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 -1
- 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 -1
- package/test/pics/p2/newline-label.png +0 -0
- package/test/pics/p2/newline-lr.png +0 -0
- package/test/pics/p2/newline-multi.png +0 -0
- package/test/pics/p3/newline-label.png +0 -0
- package/test/pics/p3/newline-lr.png +0 -0
- package/test/pics/p3/newline-multi.png +0 -0
- package/test/pics/p4/newline-label.png +0 -0
- package/test/pics/p4/newline-lr.png +0 -0
- package/test/pics/p4/newline-multi.png +0 -0
- package/test/pics/p5/newline-label.png +0 -0
- package/test/pics/p5/newline-lr.png +0 -0
- package/test/pics/p5/newline-multi.png +0 -0
- package/test/pics/p6/newline-label.png +0 -0
- package/test/pics/p6/newline-lr.png +0 -0
- package/test/pics/p6/newline-multi.png +0 -0
- package/test/pics/p7/newline-label.png +0 -0
- package/test/pics/p7/newline-lr.png +0 -0
- package/test/pics/p7/newline-multi.png +0 -0
- package/test/pics/p8/newline-label.png +0 -0
- package/test/pics/p8/newline-lr.png +0 -0
- package/test/pics/p8/newline-multi.png +0 -0
- package/test/pics/p9/newline-label.png +0 -0
- package/test/pics/p9/newline-lr.png +0 -0
- package/test/pics/p9/newline-multi.png +0 -0
package/src/p1/gen.mjs
CHANGED
|
@@ -8,11 +8,14 @@ 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 內 \n 強制換行 → mermaid htmlLabels 之 <br/>(字面換行在 subgraph 標題會遺失第二行)
|
|
12
|
+
const nl = (s) => String(s).replace(/\n/g, '<br/>')
|
|
13
|
+
|
|
11
14
|
// 把標準節點 label 轉成 mermaid 節點形狀語法(id 經 qid 消歧)
|
|
12
15
|
// diamond → {label} / 其餘 → ["label"]
|
|
13
16
|
function nodeShape(nd, qid) {
|
|
14
|
-
if (nd.cls === 'diamond') return `${qid(nd.id)}{"${nd.label}"}`
|
|
15
|
-
return `${qid(nd.id)}["${nd.label}"]`
|
|
17
|
+
if (nd.cls === 'diamond') return `${qid(nd.id)}{"${nl(nd.label)}"}`
|
|
18
|
+
return `${qid(nd.id)}["${nl(nd.label)}"]`
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
// 正規化數據 → mermaid flowchart DSL 字串
|
|
@@ -87,7 +90,8 @@ function translate(data) {
|
|
|
87
90
|
function renderSubgraph(gid, indent) {
|
|
88
91
|
const g = byId[gid]
|
|
89
92
|
const lines = []
|
|
90
|
-
|
|
93
|
+
// mermaid10 subgraph 標題不支援 <br/>(後段遺失) → \n 降級為空格(不丟資訊)
|
|
94
|
+
lines.push(`${indent}subgraph ${qid(gid)}["${String(g.label).replace(/\n/g, ' ')}"]`)
|
|
91
95
|
// 直接子節點(非容器)
|
|
92
96
|
const directChildren = nodes.filter(nd => nd.group === gid && !isGroupCls(nd.cls))
|
|
93
97
|
for (const nd of directChildren) {
|
|
@@ -106,7 +110,7 @@ function translate(data) {
|
|
|
106
110
|
const edgeLines = []
|
|
107
111
|
for (const ed of edges) {
|
|
108
112
|
const arrow = ed.kind === 'dashed' ? '-..->' : '-->'
|
|
109
|
-
const lbl = ed.label ? `|"${ed.label}"| ` : ''
|
|
113
|
+
const lbl = ed.label ? `|"${nl(ed.label)}"| ` : ''
|
|
110
114
|
edgeLines.push(` ${qid(ed.from)} ${arrow} ${lbl}${qid(ed.to)}`)
|
|
111
115
|
}
|
|
112
116
|
|
package/src/p10/gen.mjs
CHANGED
|
@@ -38,7 +38,8 @@ const VALIGN = { top:'TOP', center:'CENTER', bottom:'BOTTOM' }, DEF_VALIGN = 'to
|
|
|
38
38
|
const meas = document.getElementById('meas')
|
|
39
39
|
function measure(label, fs, maxW){
|
|
40
40
|
const d=document.createElement('div')
|
|
41
|
-
|
|
41
|
+
// white-space:pre-line: label 內 \\n 為強制換行(其餘空白照常摺疊); 與渲染端 foreignObject div 一致
|
|
42
|
+
d.style.cssText='display:inline-block;white-space:pre-line;overflow-wrap:break-word;word-break:normal;text-align:center;line-height:1.4;font-size:'+fs+'px;max-width:'+maxW+'px;padding:0;font-family:'+FONT
|
|
42
43
|
d.textContent=label; meas.appendChild(d); const r=d.getBoundingClientRect(); meas.removeChild(d)
|
|
43
44
|
return { w:Math.ceil(r.width), h:Math.ceil(r.height) }
|
|
44
45
|
}
|
|
@@ -182,7 +183,7 @@ window.renderFig = async function(spec){
|
|
|
182
183
|
const ORDER_OPTS = { 'elk.layered.crossingMinimization.semiInteractive':'true' }
|
|
183
184
|
const hasCycle = (() => { const adj={}; spec.edges.forEach(e=>{ (adj[e.from]=adj[e.from]||[]).push(e.to) }); const st={}; const dfs=(u)=>{ st[u]=1; for(const v of (adj[u]||[])){ if(st[v]===1) return true; if(!st[v] && dfs(v)) return true } st[u]=2; return false }; return Object.keys(adj).some(u=>!st[u]&&dfs(u)) })()
|
|
184
185
|
const gOpts = { 'elk.layered.nodePlacement.bk.fixedAlignment':'BALANCED', 'elk.padding':'[top=10,left=14,bottom=14,right=14]', 'elk.nodeLabels.placement':'[H_CENTER, V_TOP, INSIDE]', 'elk.algorithm':'layered', 'elk.direction':dir, 'elk.edgeRouting':'ORTHOGONAL', 'elk.hierarchyHandling':'INCLUDE_CHILDREN', 'elk.spacing.nodeNode':'28', 'elk.layered.spacing.nodeNodeBetweenLayers':'30', 'elk.spacing.edgeEdge':'22', 'elk.layered.spacing.edgeEdgeBetweenLayers':'24', ...ORDER_OPTS }
|
|
185
|
-
function elkEdge(e){
|
|
186
|
+
function elkEdge(e){ let lab=[]; if(e.label){ const m=measure(e.label,EFS,300); lab=[{ text:e.label, width:m.w, height:m.h }] } return { id:e.id, sources:[e.from], targets:[e.to], labels:lab } }
|
|
186
187
|
function build(parentId, padMap, wrapAR){
|
|
187
188
|
const children=[], edges=[]
|
|
188
189
|
spec.groups.filter(g=>g.parent===parentId).forEach(g=>{ const sub=build(g.id, padMap, wrapAR); const gm=measure(g.label,GFS,400)
|
|
@@ -240,7 +241,7 @@ window.renderFig = async function(spec){
|
|
|
240
241
|
groupsOut.sort((a,b)=>a.depth-b.depth).forEach(o=>{
|
|
241
242
|
svg+='<rect x="'+(o.x)+'" y="'+(o.y)+'" width="'+o.w+'" height="'+o.h+'" rx="8" fill="'+o.g.fill+'" fill-opacity="0.38" stroke="'+o.g.stroke+'" stroke-width="2"/>'
|
|
242
243
|
const tw=o.lbl?o.lbl.width+12:o.w, th=o.lbl?o.lbl.height+6:24, tx=o.x+Math.max(0,(o.w-tw)/2), ty=o.y+(o.lbl?o.lbl.y:5)
|
|
243
|
-
svg+='<foreignObject x="'+tx+'" y="'+ty+'" width="'+tw+'" height="'+th+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:'+GFS+'px;color:'+o.g.stroke+';line-height:1.3;overflow-wrap:break-word;word-break:normal">'+esc(o.g.label)+'</div></foreignObject>'
|
|
244
|
+
svg+='<foreignObject x="'+tx+'" y="'+ty+'" width="'+tw+'" height="'+th+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:'+GFS+'px;color:'+o.g.stroke+';line-height:1.3;white-space:pre-line;overflow-wrap:break-word;word-break:normal">'+esc(o.g.label)+'</div></foreignObject>'
|
|
244
245
|
})
|
|
245
246
|
// 2) 邊(在節點之下、容器之上)
|
|
246
247
|
const nodeBoxById={}; nodesOut.forEach(o=>{ nodeBoxById[o.n.id]={ x:o.x, y:o.y, w:o.w, h:o.h, diamond:!!o.n.diamond } })
|
|
@@ -366,7 +367,7 @@ window.renderFig = async function(spec){
|
|
|
366
367
|
})
|
|
367
368
|
// 邊標籤(白光暈)
|
|
368
369
|
;(e.labels||[]).forEach(l=>{ if(!l.text) return; const lx=o.ox+(l.x||0), ly=o.oy+(l.y||0), lw=l.width||40, lh=l.height||18
|
|
369
|
-
svg+='<foreignObject x="'+lx+'" y="'+ly+'" width="'+(lw+6)+'" height="'+(lh+4)+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:'+EFS+'px;color:'+EDGE_TEXT+';text-shadow:0 0 3px '+HALO+',0 0 3px '+HALO+',0 0 3px '+HALO+',0 0 3px '+HALO+';white-space:
|
|
370
|
+
svg+='<foreignObject x="'+lx+'" y="'+ly+'" width="'+(lw+6)+'" height="'+(lh+4)+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:'+EFS+'px;color:'+EDGE_TEXT+';text-shadow:0 0 3px '+HALO+',0 0 3px '+HALO+',0 0 3px '+HALO+',0 0 3px '+HALO+';white-space:pre-line">'+esc(l.text)+'</div></foreignObject>' })
|
|
370
371
|
})
|
|
371
372
|
// 3) 節點(最上)。各文字 div 之斷行 CSS(overflow-wrap:break-word + word-break:normal)須與 measure()/measureItems() 一致,
|
|
372
373
|
// 否則長英文識別字量測時折行、渲染時不折 → 單行溢出 foreignObject 被裁切
|
|
@@ -379,14 +380,14 @@ window.renderFig = async function(spec){
|
|
|
379
380
|
svg+='<path d="M '+(o.x+r)+' '+o.y+' H '+(o.x+o.w-r)+' A '+r+' '+r+' 0 0 1 '+(o.x+o.w)+' '+(o.y+r)+' V '+sep+' H '+o.x+' V '+(o.y+r)+' A '+r+' '+r+' 0 0 1 '+(o.x+r)+' '+o.y+' Z" fill="'+mix(n.fill,n.stroke,0.16)+'"/>' // 2 標題背景(上圓角下平)
|
|
380
381
|
svg+='<rect x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+o.h+'" rx="'+r+'" fill="none" stroke="'+n.stroke+'" stroke-width="1.6"/>' // 3 框線(頂層)
|
|
381
382
|
svg+='<line x1="'+o.x+'" y1="'+sep+'" x2="'+(o.x+o.w)+'" y2="'+sep+'" stroke="'+n.stroke+'" stroke-width="1"/>' // 4 分隔線
|
|
382
|
-
svg+='<foreignObject x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+headH+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-weight:bold;font-size:'+FS+'px;color:'+n.font+'"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">'+esc(n.title||n.label)+'</div></div></foreignObject>' // 5 標題文字
|
|
383
|
+
svg+='<foreignObject x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+headH+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-weight:bold;font-size:'+FS+'px;color:'+n.font+'"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">'+esc(n.title||n.label)+'</div></div></foreignObject>' // 5 標題文字
|
|
383
384
|
svg+='<foreignObject x="'+o.x+'" y="'+sep+'" width="'+o.w+'" height="'+(o.h-headH)+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:'+(FS-1)+'px;line-height:1.55;padding:6px 9px 4px;text-align:left;color:'+n.font+'">'+lis+'</div></foreignObject>' // 6 items文字
|
|
384
385
|
} else if(n.diamond){ const cx=o.x+o.w/2, cy=o.y+o.h/2
|
|
385
386
|
svg+='<polygon points="'+cx+','+o.y+' '+(o.x+o.w)+','+cy+' '+cx+','+(o.y+o.h)+' '+o.x+','+cy+'" fill="'+n.fill+'" stroke="'+n.stroke+'" stroke-width="1.8"/>'
|
|
386
|
-
svg+='<foreignObject x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+o.h+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:'+FS+'px;color:'+n.font+';line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">'+esc(n.label)+'</div></div></foreignObject>'
|
|
387
|
+
svg+='<foreignObject x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+o.h+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:'+FS+'px;color:'+n.font+';line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">'+esc(n.label)+'</div></div></foreignObject>'
|
|
387
388
|
} else {
|
|
388
389
|
svg+='<rect x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+o.h+'" rx="7" fill="'+n.fill+'" stroke="'+n.stroke+'" stroke-width="1.6"/>'
|
|
389
|
-
svg+='<foreignObject x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+o.h+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:'+FS+'px;color:'+n.font+';line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">'+esc(n.label)+'</div></div></foreignObject>'
|
|
390
|
+
svg+='<foreignObject x="'+o.x+'" y="'+o.y+'" width="'+o.w+'" height="'+o.h+'"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:'+FS+'px;color:'+n.font+';line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">'+esc(n.label)+'</div></div></foreignObject>'
|
|
390
391
|
}
|
|
391
392
|
})
|
|
392
393
|
|
package/src/p3/gen.mjs
CHANGED
|
@@ -66,23 +66,29 @@ function translate(data) {
|
|
|
66
66
|
const byId = {}
|
|
67
67
|
for (const nd of data.nodes) byId[nd.id] = nd
|
|
68
68
|
|
|
69
|
-
//
|
|
70
|
-
|
|
69
|
+
// label 內 \n 強制換行 → nomnoml 節點文字以 ; 斷行(節點宣告與邊參照須同轉換才對得上);
|
|
70
|
+
// 邊標籤不支援多行 → 降級為空格(避免字面換行使版面錯亂)
|
|
71
|
+
const nl = (s) => String(s).replace(/\n/g, ';')
|
|
72
|
+
const nlSp = (s) => String(s).replace(/\n/g, ' ')
|
|
73
|
+
|
|
74
|
+
// 所有節點頂層平鋪宣告; 菱形(choice)之多行內文會超出斜邊被裁 → \n 降級為空格(單行加寬菱形)
|
|
75
|
+
const nodeLabel = (nd) => nd.cls === 'diamond' ? nlSp(nd.label) : nl(nd.label)
|
|
76
|
+
const nodeDsls = data.nodes.map(nd => `[${classifier(nd.cls)}${nodeLabel(nd)}]`).join('\n')
|
|
71
77
|
|
|
72
78
|
// 群組歸屬邊: 容器(group 所指節點) → 成員, 虛線無箭頭語意以外之標籤
|
|
73
79
|
// nomnoml 無容器框, 比照 p10/vis 以關聯邊表達歸屬, 讓排版把成員擺在容器旁
|
|
74
80
|
const assocDsls = data.nodes
|
|
75
81
|
.filter(nd => nd.group && byId[nd.group])
|
|
76
|
-
.map(nd => `[${byId[nd.group]
|
|
82
|
+
.map(nd => `[${nodeLabel(byId[nd.group])}] --> [${nodeLabel(nd)}]`)
|
|
77
83
|
.join('\n')
|
|
78
84
|
|
|
79
|
-
// 數據明列之邊: 端點以既有節點之確切標籤參照(
|
|
85
|
+
// 數據明列之邊: 端點以既有節點之確切標籤參照(不新建節點; 轉換須與節點宣告一致才對得上)
|
|
80
86
|
const edgeDsls = data.edges.map(ed => {
|
|
81
|
-
const
|
|
82
|
-
const
|
|
87
|
+
const fromRef = byId[ed.from] ? nodeLabel(byId[ed.from]) : nl(ed.from)
|
|
88
|
+
const toRef = byId[ed.to] ? nodeLabel(byId[ed.to]) : nl(ed.to)
|
|
83
89
|
const arrow = ed.kind === 'dashed' ? '-->' : '->'
|
|
84
|
-
const edgeLabel = ed.label ? ` ${ed.label} ` : ' '
|
|
85
|
-
return `[${
|
|
90
|
+
const edgeLabel = ed.label ? ` ${nlSp(ed.label)} ` : ' '
|
|
91
|
+
return `[${fromRef}]${edgeLabel}${arrow} [${toRef}]`
|
|
86
92
|
}).join('\n')
|
|
87
93
|
|
|
88
94
|
return `#direction: ${dir}
|
package/src/p4/gen.mjs
CHANGED
|
@@ -34,7 +34,7 @@ const style = `[
|
|
|
34
34
|
{ "selector":"node.greenG2", "style":{ "background-color":"#eaf4ef","border-color":"#348a5c","color":"#348a5c" } },
|
|
35
35
|
{ "selector":"node.orangeG", "style":{ "background-color":"#fdf6ec","border-color":"#c46e1a","color":"#c46e1a" } },
|
|
36
36
|
{ "selector":"node.purpleG", "style":{ "background-color":"#faf7fd","border-color":"#8163ad","color":"#8163ad" } },
|
|
37
|
-
{ "selector":"edge", "style":{ "width":2.2,"line-color":"#44505a","target-arrow-color":"#44505a","target-arrow-shape":"triangle","curve-style":"bezier","label":"data(label)","font-family":"Microsoft JhengHei, sans-serif","font-size":12.5,"color":"#4a5560","text-background-opacity":0,"text-outline-color":"#ffffff","text-outline-width":3,"text-margin-y":-2 } },
|
|
37
|
+
{ "selector":"edge", "style":{ "width":2.2,"line-color":"#44505a","target-arrow-color":"#44505a","target-arrow-shape":"triangle","curve-style":"bezier","label":"data(label)","font-family":"Microsoft JhengHei, sans-serif","font-size":12.5,"color":"#4a5560","text-background-opacity":0,"text-outline-color":"#ffffff","text-outline-width":3,"text-margin-y":-2,"text-wrap":"wrap" } },
|
|
38
38
|
{ "selector":"edge.dashed", "style":{ "line-style":"dashed" } }
|
|
39
39
|
]`
|
|
40
40
|
|
package/src/p5/gen.mjs
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// 注意:本版 D2(0.1.33 / WASM v0.7.0) 傳入自訂 font buffer 會穩定回 "invalid JSON input"。
|
|
6
6
|
// 改為不傳字型編譯,渲染為 SVG 後注入 font-family 覆寫,交由 librsvg(sharp) 以系統「Microsoft JhengHei」實際描繪。
|
|
7
7
|
// D2 v0.7 內建 CJK 全形寬度量測,box 寬即使長中文亦不溢出(已實測)。
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// @terrastruct/d2 與 sharp 為本產線專屬重依賴, 於函式內動態載入(延遲載入):
|
|
9
|
+
// 模組層載入會令「僅用其他產線」的使用者也付出載入成本, 且 d2 上游缺陷會連帶影響其他產線
|
|
10
10
|
import { colorOf, isGroupCls } from '../common/palette.mjs'
|
|
11
11
|
|
|
12
12
|
// ── 字型注入 ────────────────────────────────────────────────────────────────
|
|
@@ -48,8 +48,8 @@ function injectEdgeLabelHalo(svg) {
|
|
|
48
48
|
return svg.slice(0, p + 1) + EDGE_HALO_STYLE + svg.slice(p + 1)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
// ── D2 escape:$ 需轉義以避免 D2
|
|
52
|
-
const esc = (s) => String(s).replace(/\$/g, '\\$')
|
|
51
|
+
// ── D2 escape:$ 需轉義以避免 D2 變數展開; 字面換行轉 \n 逸出序列(D2 雙引號字串不允許字面換行) ──
|
|
52
|
+
const esc = (s) => String(s).replace(/\$/g, '\\$').replace(/\n/g, '\\n')
|
|
53
53
|
|
|
54
54
|
// ── D2 方向映射:標準數據 dir → D2 direction 關鍵字 ─────────────────────────
|
|
55
55
|
const DIR_MAP = { TB: 'down', LR: 'right', BT: 'up', RL: 'left' }
|
|
@@ -176,6 +176,7 @@ const baseOpt = { layout: 'dagre', pad: 40, themeID: 0 }
|
|
|
176
176
|
// D2 建構時即起常駐 worker 且無公開關閉 API(worker 為 node worker_threads 實例),
|
|
177
177
|
// 若掛在模組層, 光 import 本檔就會令 caller 程序無法自然結束;故逐次建立並於 finally terminate。
|
|
178
178
|
async function d2Svg(data) {
|
|
179
|
+
const { D2 } = await import('@terrastruct/d2')
|
|
179
180
|
const d2inst = new D2()
|
|
180
181
|
try {
|
|
181
182
|
const d2src = translate(data)
|
|
@@ -193,6 +194,7 @@ async function d2Svg(data) {
|
|
|
193
194
|
|
|
194
195
|
// ── 單張渲染 → PNG Buffer ────────────────────────────────────────────────────
|
|
195
196
|
export async function genPng(data, opt = {}) {
|
|
197
|
+
const { default: sharp } = await import('sharp')
|
|
196
198
|
const svg = await d2Svg(data)
|
|
197
199
|
// density 通用公式:依 SVG viewBox 寬推算,讓輸出寬約落在 1600–2200px
|
|
198
200
|
const m = svg.match(/viewBox="0 0 (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)"/)
|
package/src/p7/gen.mjs
CHANGED
|
@@ -42,16 +42,21 @@ var __cv = document.createElement('canvas'); var __cx = __cv.getContext('2d')
|
|
|
42
42
|
function measure(text, fs){ __cx.font = fs + 'px ' + FONT; return __cx.measureText(text).width }
|
|
43
43
|
|
|
44
44
|
// 依字寬自動換行(回傳 lines 陣列 + 最大寬)
|
|
45
|
+
// label 內 \\n 為強制換行: 先依 \\n 切段、各段再逐字寬斷行——渲染端以 join('\\n') 交給 JointJS,
|
|
46
|
+
// 若量測不切 \\n 會令實際行數多於估算行數, 框高低估、文字上下溢出框
|
|
45
47
|
function wrapText(text, fs, maxW){
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
var lines = []
|
|
49
|
+
String(text).split('\\n').forEach(function(seg){
|
|
50
|
+
var cur = ''
|
|
51
|
+
for (var i = 0; i < seg.length; i++){
|
|
52
|
+
var ch = seg[i]
|
|
53
|
+
var test = cur + ch
|
|
54
|
+
if (measure(test, fs) > maxW && cur !== ''){ lines.push(cur); cur = ch }
|
|
55
|
+
else cur = test
|
|
56
|
+
}
|
|
57
|
+
lines.push(cur) // 空段亦保留(連續 \\n 表空行)
|
|
58
|
+
})
|
|
59
|
+
if (lines.length === 1 && lines[0] === '') lines = [] // 空字串輸入維持原行為(零行)
|
|
55
60
|
var w = 0; lines.forEach(function(l){ w = Math.max(w, measure(l, fs)) })
|
|
56
61
|
return { lines: lines, w: w }
|
|
57
62
|
}
|
package/src/p8/gen.mjs
CHANGED
|
@@ -173,7 +173,8 @@ function layout(P, nodeSep, rankSep){
|
|
|
173
173
|
Object.keys(groupIds).sort(function(a,b){ return depth(a)-depth(b) }).forEach(function(gid){
|
|
174
174
|
var gn = g.node(gid)
|
|
175
175
|
var pal = PAL[byId[gid].cls] || PAL.blue
|
|
176
|
-
|
|
176
|
+
// 群組標題帶為固定高(GROUP_TITLE), label 內 \\n 降級為空格(兩行標題會壓到成員節點)
|
|
177
|
+
lfGroupNodes.push({ id: gid, label: String(byId[gid].label).replace(/\\n/g, ' '), _pal: pal,
|
|
177
178
|
x: Math.round(gn.x), y: Math.round(gn.y), _w: Math.round(gn.width), _h: Math.round(gn.height) })
|
|
178
179
|
})
|
|
179
180
|
|
package/src/p9/gen.mjs
CHANGED
|
@@ -13,12 +13,19 @@ import { pkgScript, pkgText } from '../common/pkg.mjs'
|
|
|
13
13
|
const __dir = dirname(fileURLToPath(import.meta.url))
|
|
14
14
|
// React / ReactDOM / @xyflow/react(UMD)/ @dagrejs/dagre 由本機 node_modules 內聯注入(取代 esm.sh, 斷網環境可用)
|
|
15
15
|
// replace 用函式形式回傳, 避免庫碼內 $ 序列被當作替換樣板
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
// 首次呼叫才讀檔組頁(延遲載入): 模組層即讀會令「僅用其他產線」的載入方也付出讀檔成本
|
|
17
|
+
let _html = null
|
|
18
|
+
function getHtml() {
|
|
19
|
+
if (_html === null) {
|
|
20
|
+
_html = fs.readFileSync(`${__dir}/page9.html`, 'utf8')
|
|
21
|
+
.replace('/*__XYFLOW_CSS__*/', () => pkgText('@xyflow/react/dist/style.css'))
|
|
22
|
+
.replace('/*__REACT_JS__*/', () => pkgScript('react/umd/react.production.min.js'))
|
|
23
|
+
.replace('/*__REACT_DOM_JS__*/', () => pkgScript('react-dom/umd/react-dom.production.min.js'))
|
|
24
|
+
.replace('/*__XYFLOW_JS__*/', () => pkgScript('@xyflow/react/dist/umd/index.js'))
|
|
25
|
+
.replace('/*__DAGRE_JS__*/', () => pkgScript('@dagrejs/dagre/dist/dagre.min.js'))
|
|
26
|
+
}
|
|
27
|
+
return _html
|
|
28
|
+
}
|
|
22
29
|
|
|
23
30
|
// 正規化數據 → page9.html renderFig spec
|
|
24
31
|
// 標籤「不預折」, 原樣傳入, 由 page9.html 量測 div(max-width + overflow-wrap)自然折行:
|
|
@@ -47,7 +54,7 @@ export async function genPng(data, opt = {}) {
|
|
|
47
54
|
const errs = []
|
|
48
55
|
page.on('pageerror', e => errs.push(e.message))
|
|
49
56
|
page.on('console', m => { if (m.type() === 'error') errs.push('c:' + m.text().slice(0, 200)) })
|
|
50
|
-
await page.setContent(
|
|
57
|
+
await page.setContent(getHtml(), { waitUntil: 'load' })
|
|
51
58
|
await page.waitForFunction(() => document.title === 'READY' || document.title === 'FAIL', { timeout: 60000 }).catch(() => {})
|
|
52
59
|
const boot = await page.evaluate(() => ({ t: document.title, err: window.__err }))
|
|
53
60
|
if (boot.t !== 'READY') throw new Error('BOOT FAIL :: ' + boot.err + ' | ' + errs.slice(0, 6).join(' | '))
|
package/test/cases.mjs
CHANGED
|
@@ -362,4 +362,85 @@ export const CASES = [
|
|
|
362
362
|
},
|
|
363
363
|
},
|
|
364
364
|
|
|
365
|
-
|
|
365
|
+
// 17) label 內 \n 強制換行(節點/群組標題/菱形/邊標籤; white-space:pre-line 量測與渲染一致)
|
|
366
|
+
{
|
|
367
|
+
name: 'newline-label',
|
|
368
|
+
desc: '換行 — label 內 \\n 為強制換行(含 edge/群組/菱形 label)',
|
|
369
|
+
data: {
|
|
370
|
+
dir: 'TB',
|
|
371
|
+
nodes: [
|
|
372
|
+
{ id: 'G', label: '群組\n標題', cls: 'greenG' },
|
|
373
|
+
{ id: 'A', label: '產出各語之\n搜尋與列表索引', cls: 'blue', group: 'G' },
|
|
374
|
+
{ id: 'B', label: '產出各語之搜尋與列表索引', cls: 'blue' },
|
|
375
|
+
{ id: 'D', label: '判斷\n嗎?', cls: 'diamond' },
|
|
376
|
+
],
|
|
377
|
+
edges: [{ from: 'A', to: 'B', label: '第一行\n第二行' }, { from: 'B', to: 'D' }],
|
|
378
|
+
},
|
|
379
|
+
check(spec, geom, h) {
|
|
380
|
+
const A = h.node('A'); const B = h.node('B')
|
|
381
|
+
return [
|
|
382
|
+
// \n 生效 → A 折成兩行: 高於單行之 B、窄於同文案無 \n 之 B
|
|
383
|
+
{ name: 'A 兩行(高於單行 B)', pass: !!A && !!B && A.h >= B.h + 14, detail: A && B && `A.h=${A.h} B.h=${B.h}` },
|
|
384
|
+
{ name: 'A 依換行點收窄(窄於 B)', pass: !!A && !!B && A.w < B.w - 30, detail: A && B && `A.w=${A.w} B.w=${B.w}` },
|
|
385
|
+
]
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
|
|
389
|
+
// 18) \n 行數階梯(1/2/3 行)+ 英文混排 + 多行邊標籤: 行數愈多框愈高(spec: 每個 \n 即一次強制換行)
|
|
390
|
+
{
|
|
391
|
+
name: 'newline-multi',
|
|
392
|
+
desc: '換行 — 1/2/3 行階梯與英文/邊標籤多行',
|
|
393
|
+
data: {
|
|
394
|
+
dir: 'TB',
|
|
395
|
+
nodes: [
|
|
396
|
+
{ id: 'S', label: '單行節點', cls: 'blue' },
|
|
397
|
+
{ id: 'M2', label: '兩行標籤\n第二行', cls: 'green' },
|
|
398
|
+
{ id: 'M3', label: '三行標籤\n第二行\n第三行', cls: 'orange' },
|
|
399
|
+
{ id: 'EN', label: 'Alpha Beta\nGamma Service', cls: 'purple' },
|
|
400
|
+
],
|
|
401
|
+
edges: [
|
|
402
|
+
{ from: 'S', to: 'M2', label: '確認\n送出' },
|
|
403
|
+
{ from: 'M2', to: 'M3' },
|
|
404
|
+
{ from: 'M3', to: 'EN', kind: 'dashed', label: 'retry\nonce' },
|
|
405
|
+
],
|
|
406
|
+
},
|
|
407
|
+
check(spec, geom, h) {
|
|
408
|
+
const S = h.node('S'); const M2 = h.node('M2'); const M3 = h.node('M3'); const EN = h.node('EN')
|
|
409
|
+
return [
|
|
410
|
+
{ name: '兩行高於單行', pass: !!S && !!M2 && M2.h >= S.h + 14, detail: S && M2 && `S.h=${S.h} M2.h=${M2.h}` },
|
|
411
|
+
{ name: '三行高於兩行', pass: !!M2 && !!M3 && M3.h >= M2.h + 14, detail: M2 && M3 && `M2.h=${M2.h} M3.h=${M3.h}` },
|
|
412
|
+
{ name: '英文兩行與中文兩行同高', pass: !!EN && !!M2 && Math.abs(EN.h - M2.h) <= 2, detail: EN && M2 && `EN.h=${EN.h} M2.h=${M2.h}` },
|
|
413
|
+
]
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
|
|
417
|
+
// 19) LR 方向 + 群組標題/菱形/跨群組邊標籤之 \n(換行支援不受方向與容器影響)
|
|
418
|
+
{
|
|
419
|
+
name: 'newline-lr',
|
|
420
|
+
desc: '換行 — LR 方向 + 群組標題/菱形多行',
|
|
421
|
+
data: {
|
|
422
|
+
dir: 'LR',
|
|
423
|
+
nodes: [
|
|
424
|
+
{ id: 'G', label: '前置\n處理群組', cls: 'blueG' },
|
|
425
|
+
{ id: 'A', label: '接收\n輸入資料', cls: 'blue', group: 'G' },
|
|
426
|
+
{ id: 'B', label: '正規化', cls: 'blue', group: 'G' },
|
|
427
|
+
{ id: 'D', label: '格式\n是否\n正確?', cls: 'diamond' },
|
|
428
|
+
{ id: 'E', label: '完成', cls: 'done' },
|
|
429
|
+
],
|
|
430
|
+
edges: [
|
|
431
|
+
{ from: 'A', to: 'B' },
|
|
432
|
+
{ from: 'B', to: 'D', label: '檢查\n格式' },
|
|
433
|
+
{ from: 'D', to: 'E', label: '通過' },
|
|
434
|
+
{ from: 'D', to: 'A', kind: 'dashed', label: '退回\n重新接收' },
|
|
435
|
+
],
|
|
436
|
+
},
|
|
437
|
+
check(spec, geom, h) {
|
|
438
|
+
const A = h.node('A'); const B = h.node('B'); const D = h.node('D')
|
|
439
|
+
return [
|
|
440
|
+
{ name: '群組內兩行節點高於單行', pass: !!A && !!B && A.h >= B.h + 14, detail: A && B && `A.h=${A.h} B.h=${B.h}` },
|
|
441
|
+
{ name: '菱形三行(高度足納三行)', pass: !!D && D.h >= 90, detail: D && `D.h=${D.h}` },
|
|
442
|
+
]
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
|
|
446
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/test/pics/p10/cycle.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="147" height="479" viewBox="-18 -18 147 479" style="background:#fff"><path d="M 55.5 48 L 55.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 82 L 59.5 73 L 51.5 73 Z" fill="#44505a"></path><path d="M 64.16666666666666 118 L 64.16666666666666 144 L 77.25 144 L 77.25 243.75" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 77.25 243.75 L 81.25 234.75 L 73.25 234.75 Z" fill="#44505a"></path><path d="M 55.5 309 L 55.5 395" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 395 L 59.5 386 L 51.5 386 Z" fill="#44505a"></path><foreignObject x="28.5" y="343" width="31" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="147" height="479" viewBox="-18 -18 147 479" style="background:#fff"><path d="M 55.5 48 L 55.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 82 L 59.5 73 L 51.5 73 Z" fill="#44505a"></path><path d="M 64.16666666666666 118 L 64.16666666666666 144 L 77.25 144 L 77.25 243.75" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 77.25 243.75 L 81.25 234.75 L 73.25 234.75 Z" fill="#44505a"></path><path d="M 55.5 309 L 55.5 395" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 395 L 59.5 386 L 51.5 386 Z" fill="#44505a"></path><foreignObject x="28.5" y="343" width="31" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">通過</div></foreignObject><path d="M 55.5 222 L 55.5 144 L 46.83333333333333 144 L 46.83333333333333 118" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 46.83333333333333 118 L 42.83333333333333 127 L 50.83333333333333 127 Z" fill="#44505a"></path><foreignObject x="14" y="170" width="31" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">退回</div></foreignObject><rect x="29.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="29.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><rect x="29.5" y="82" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="29.5" y="82" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">處理</div></div></foreignObject><polygon points="55.5,222 99,265.5 55.5,309 12,265.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="12" y="222" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">審核?</div></div></foreignObject><rect x="29.5" y="395" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#256046" stroke-width="1.6"></rect><foreignObject x="29.5" y="395" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#256046;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">完成</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="224" height="419" viewBox="-18 -18 224 419" style="background:#fff"><rect x="12" y="12" width="164" height="226" rx="8" fill="#f5f9fe" fill-opacity="0.38" stroke="#3f6fb0" stroke-width="2"></rect><foreignObject x="59.5" y="17" width="69" height="33"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:15px;color:#3f6fb0;line-height:1.3;overflow-wrap:break-word;word-break:normal">第一層</div></foreignObject><rect x="26" y="54" width="136" height="159" rx="8" fill="#f0f7f3" fill-opacity="0.38" stroke="#348a5c" stroke-width="2"></rect><foreignObject x="59.5" y="59" width="69" height="33"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:15px;color:#348a5c;line-height:1.3;overflow-wrap:break-word;word-break:normal">第二層</div></foreignObject><rect x="40" y="96" width="108" height="92" rx="8" fill="#fdf6ec" fill-opacity="0.38" stroke="#c46e1a" stroke-width="2"></rect><foreignObject x="59.5" y="101" width="69" height="33"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:15px;color:#c46e1a;line-height:1.3;overflow-wrap:break-word;word-break:normal">第三層</div></foreignObject><path d="M 94 174 L 94 335" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 94 335 L 98 326 L 90 326 Z" fill="#44505a"></path><foreignObject x="54" y="283" width="44" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="224" height="419" viewBox="-18 -18 224 419" style="background:#fff"><rect x="12" y="12" width="164" height="226" rx="8" fill="#f5f9fe" fill-opacity="0.38" stroke="#3f6fb0" stroke-width="2"></rect><foreignObject x="59.5" y="17" width="69" height="33"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:15px;color:#3f6fb0;line-height:1.3;white-space:pre-line;overflow-wrap:break-word;word-break:normal">第一層</div></foreignObject><rect x="26" y="54" width="136" height="159" rx="8" fill="#f0f7f3" fill-opacity="0.38" stroke="#348a5c" stroke-width="2"></rect><foreignObject x="59.5" y="59" width="69" height="33"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:15px;color:#348a5c;line-height:1.3;white-space:pre-line;overflow-wrap:break-word;word-break:normal">第二層</div></foreignObject><rect x="40" y="96" width="108" height="92" rx="8" fill="#fdf6ec" fill-opacity="0.38" stroke="#c46e1a" stroke-width="2"></rect><foreignObject x="59.5" y="101" width="69" height="33"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="text-align:center;font-weight:bold;font-size:15px;color:#c46e1a;line-height:1.3;white-space:pre-line;overflow-wrap:break-word;word-break:normal">第三層</div></foreignObject><path d="M 94 174 L 94 335" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 94 335 L 98 326 L 90 326 Z" fill="#44505a"></path><foreignObject x="54" y="283" width="44" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">跨三層</div></foreignObject><rect x="54" y="138" width="80" height="36" rx="7" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.6"></rect><foreignObject x="54" y="138" width="80" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">最深節點</div></div></foreignObject><rect x="54" y="335" width="80" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="54" y="335" width="80" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">頂層節點</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="166" height="445" viewBox="-18 -18 166 445" style="background:#fff"><path d="M 64.5 48 L 64.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 64.5 82 L 68.5 73 L 60.5 73 Z" fill="#44505a"></path><path d="M 64.5 169 L 64.5 195 L 90 195 L 90 273" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 90 273 L 94 264 L 86 264 Z" fill="#44505a"></path><foreignObject x="93" y="221" width="31" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="166" height="445" viewBox="-18 -18 166 445" style="background:#fff"><path d="M 64.5 48 L 64.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 64.5 82 L 68.5 73 L 60.5 73 Z" fill="#44505a"></path><path d="M 64.5 169 L 64.5 195 L 90 195 L 90 273" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 90 273 L 94 264 L 86 264 Z" fill="#44505a"></path><foreignObject x="93" y="221" width="31" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">通過</div></foreignObject><path d="M 90 309 L 90 335 L 77.83333333333334 335 L 77.83333333333334 361" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 77.83333333333334 361 L 81.83333333333334 352 L 73.83333333333334 352 Z" fill="#44505a"></path><path d="M 51.166666666666664 361 L 51.166666666666664 335 L 39 335 L 39 195 L 42.75 195 L 42.75 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 42.75 147.25 L 38.75 156.25 L 46.75 156.25 Z" fill="#44505a"></path><foreignObject x="12" y="221" width="31" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">退回</div></foreignObject><rect x="38.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="38.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="64.5,82 108,125.5 64.5,169 21,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="21" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="64" y="273" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="64" y="273" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果</div></div></foreignObject><rect x="24.5" y="361" width="80" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="24.5" y="361" width="80" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">回饋來源</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="241" height="445" viewBox="-18 -18 241 445" style="background:#fff"><path d="M 102 48 L 102 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 102 82 L 106 73 L 98 73 Z" fill="#44505a"></path><path d="M 102 169 L 102 195 L 160 195 L 160 273" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 160 273 L 164 264 L 156 264 Z" fill="#44505a"></path><foreignObject x="145" y="221" width="19" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="241" height="445" viewBox="-18 -18 241 445" style="background:#fff"><path d="M 102 48 L 102 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 102 82 L 106 73 L 98 73 Z" fill="#44505a"></path><path d="M 102 169 L 102 195 L 160 195 L 160 273" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 160 273 L 164 264 L 156 264 Z" fill="#44505a"></path><foreignObject x="145" y="221" width="19" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">是</div></foreignObject><path d="M 102 169 L 102 195 L 45 195 L 45 273" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 45 273 L 49 264 L 41 264 Z" fill="#44505a"></path><foreignObject x="30" y="221" width="19" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">否</div></foreignObject><path d="M 160 309 L 160 335 L 144.33333333333334 335 L 144.33333333333334 361" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 144.33333333333334 361 L 148.33333333333334 352 L 140.33333333333334 352 Z" fill="#44505a"></path><path d="M 117.66666666666667 361 L 117.66666666666667 335 L 123.75 335 L 123.75 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 123.75 147.25 L 119.75 156.25 L 127.75 156.25 Z" fill="#44505a"></path><rect x="76" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="76" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="102,82 145.5,125.5 102,169 58.5,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="58.5" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="127" y="273" width="66" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="127" y="273" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果一</div></div></foreignObject><rect x="12" y="273" width="66" height="36" rx="7" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.6"></rect><foreignObject x="12" y="273" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果二</div></div></foreignObject><rect x="91" y="361" width="80" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="91" y="361" width="80" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">回饋來源</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="147" height="217" viewBox="-18 -18 147 217" style="background:#fff"><path d="M 55.5 48 L 55.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 82 L 59.5 73 L 51.5 73 Z" fill="#44505a"></path><rect x="29.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="29.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">來源</div></div></foreignObject><polygon points="55.5,82 99,125.5 55.5,169 12,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="12" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="147" height="217" viewBox="-18 -18 147 217" style="background:#fff"><path d="M 55.5 48 L 55.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 82 L 59.5 73 L 51.5 73 Z" fill="#44505a"></path><rect x="29.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="29.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">來源</div></div></foreignObject><polygon points="55.5,82 99,125.5 55.5,169 12,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="12" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="147" height="287" viewBox="-18 -18 147 287" style="background:#fff"><path d="M 55.5 48 L 55.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 82 L 59.5 73 L 51.5 73 Z" fill="#44505a"></path><path d="M 55.5 169 L 55.5 203" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 203 L 59.5 194 L 51.5 194 Z" fill="#44505a"></path><rect x="29.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="29.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="55.5,82 99,125.5 55.5,169 12,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="12" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="29.5" y="203" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="29.5" y="203" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">結果</div></div></foreignObject></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="147" height="287" viewBox="-18 -18 147 287" style="background:#fff"><path d="M 55.5 48 L 55.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 82 L 59.5 73 L 51.5 73 Z" fill="#44505a"></path><path d="M 55.5 169 L 55.5 203" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 55.5 203 L 59.5 194 L 51.5 194 Z" fill="#44505a"></path><rect x="29.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="29.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="55.5,82 99,125.5 55.5,169 12,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="12" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="29.5" y="203" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="29.5" y="203" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="222" height="393" viewBox="-18 -18 222 393" style="background:#fff"><path d="M 93 48 L 93 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 93 82 L 97 73 L 89 73 Z" fill="#44505a"></path><path d="M 93 169 L 93 221" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 93 221 L 97 212 L 89 212 Z" fill="#44505a"></path><path d="M 84.33333333333334 257 L 84.33333333333334 283 L 56 283 L 56 309" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 56 309 L 60 300 L 52 300 Z" fill="#44505a"></path><path d="M 101.66666666666667 257 L 101.66666666666667 283 L 130 283 L 130 309" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 130 309 L 134 300 L 126 300 Z" fill="#44505a"></path><path d="M 34 309 L 34 283 L 23.833333333333336 283 L 23.833333333333336 195 L 71.25 195 L 71.25 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 71.25 147.25 L 67.25 156.25 L 75.25 156.25 Z" fill="#44505a"></path><path d="M 152 309 L 152 283 L 161.66666666666669 283 L 161.66666666666669 195 L 114.75 195 L 114.75 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 114.75 147.25 L 110.75 156.25 L 118.75 156.25 Z" fill="#44505a"></path><rect x="67" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="67" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="93,82 136.5,125.5 93,169 49.50000000000001,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="49.50000000000001" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="67" y="221" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="67" y="221" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">結果</div></div></foreignObject><rect x="12" y="309" width="66" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="12" y="309" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">來源一</div></div></foreignObject><rect x="108" y="309" width="66" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="108" y="309" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;overflow-wrap:break-word;word-break:normal">來源二</div></div></foreignObject></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="222" height="393" viewBox="-18 -18 222 393" style="background:#fff"><path d="M 93 48 L 93 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 93 82 L 97 73 L 89 73 Z" fill="#44505a"></path><path d="M 93 169 L 93 221" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 93 221 L 97 212 L 89 212 Z" fill="#44505a"></path><path d="M 84.33333333333334 257 L 84.33333333333334 283 L 56 283 L 56 309" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 56 309 L 60 300 L 52 300 Z" fill="#44505a"></path><path d="M 101.66666666666667 257 L 101.66666666666667 283 L 130 283 L 130 309" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 130 309 L 134 300 L 126 300 Z" fill="#44505a"></path><path d="M 34 309 L 34 283 L 23.833333333333336 283 L 23.833333333333336 195 L 71.25 195 L 71.25 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 71.25 147.25 L 67.25 156.25 L 75.25 156.25 Z" fill="#44505a"></path><path d="M 152 309 L 152 283 L 161.66666666666669 283 L 161.66666666666669 195 L 114.75 195 L 114.75 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 114.75 147.25 L 110.75 156.25 L 118.75 156.25 Z" fill="#44505a"></path><rect x="67" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="67" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="93,82 136.5,125.5 93,169 49.50000000000001,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="49.50000000000001" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="67" y="221" width="52" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="67" y="221" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果</div></div></foreignObject><rect x="12" y="309" width="66" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="12" y="309" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">來源一</div></div></foreignObject><rect x="108" y="309" width="66" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="108" y="309" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">來源二</div></div></foreignObject></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="270" height="469" viewBox="-18 -18 270 469" style="background:#fff"><path d="M 102.5 48 L 102.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 102.5 82 L 106.5 73 L 98.5 73 Z" fill="#44505a"></path><path d="M 102.5 169 L 102.5 219 L 74 219 L 74 297" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 74 297 L 78 288 L 70 288 Z" fill="#44505a"></path><foreignObject x="59" y="245" width="19" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="270" height="469" viewBox="-18 -18 270 469" style="background:#fff"><path d="M 102.5 48 L 102.5 82" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 102.5 82 L 106.5 73 L 98.5 73 Z" fill="#44505a"></path><path d="M 102.5 169 L 102.5 219 L 74 219 L 74 297" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 74 297 L 78 288 L 70 288 Z" fill="#44505a"></path><foreignObject x="59" y="245" width="19" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">是</div></foreignObject><path d="M 102.5 169 L 102.5 195 L 189 195 L 189 297" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 189 297 L 193 288 L 185 288 Z" fill="#44505a"></path><foreignObject x="174" y="245" width="19" height="22"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="font-size:12.5px;color:#4a5560;text-shadow:0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff,0 0 3px #ffffff;white-space:pre-line">否</div></foreignObject><path d="M 74 333 L 74 359 L 56 359 L 56 385" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 56 385 L 60 376 L 52 376 Z" fill="#44505a"></path><path d="M 189 333 L 189 359 L 171 359 L 171 385" fill="none" stroke="#44505a" stroke-width="2"></path><path d="M 171 385 L 175 376 L 167 376 Z" fill="#44505a"></path><path d="M 34 385 L 34 359 L 16 359 L 16 195 L 80.75 195 L 80.75 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 80.75 147.25 L 76.75 156.25 L 84.75 156.25 Z" fill="#44505a"></path><path d="M 149 385 L 149 359 L 131 359 L 131 219 L 124.25 219 L 124.25 147.25" fill="none" stroke="#44505a" stroke-width="2" stroke-dasharray="6 4"></path><path d="M 124.25 147.25 L 120.25 156.25 L 128.25 156.25 Z" fill="#44505a"></path><rect x="76.5" y="12" width="52" height="36" rx="7" fill="#eef4fb" stroke="#3f6fb0" stroke-width="1.6"></rect><foreignObject x="76.5" y="12" width="52" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">開始</div></div></foreignObject><polygon points="102.5,82 146,125.5 102.5,169 59.00000000000001,125.5" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.8"></polygon><foreignObject x="59.00000000000001" y="82" width="87" height="87"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">判斷?</div></div></foreignObject><rect x="41" y="297" width="66" height="36" rx="7" fill="#eaf4ef" stroke="#348a5c" stroke-width="1.6"></rect><foreignObject x="41" y="297" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果一</div></div></foreignObject><rect x="156" y="297" width="66" height="36" rx="7" fill="#fcf0e2" stroke="#c46e1a" stroke-width="1.6"></rect><foreignObject x="156" y="297" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#1c2b36;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">結果二</div></div></foreignObject><rect x="12" y="385" width="66" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="12" y="385" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">來源一</div></div></foreignObject><rect x="127" y="385" width="66" height="36" rx="7" fill="#fbecea" stroke="#c0392b" stroke-width="1.6"></rect><foreignObject x="127" y="385" width="66" height="36"><div xmlns="http://www.w3.org/1999/xhtml" class="lbl" style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;text-align:center;font-size:14px;color:#23303a;line-height:1.4;padding:0 4px;box-sizing:border-box"><div style="width:100%;min-width:0;white-space:pre-line;overflow-wrap:break-word;word-break:normal">來源二</div></div></foreignObject></svg>
|