schematex 0.2.0 → 0.2.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 +1 -1
- package/dist/ai/ai-sdk.cjs +85 -0
- package/dist/ai/ai-sdk.cjs.map +1 -0
- package/dist/ai/ai-sdk.d.cts +30 -0
- package/dist/ai/ai-sdk.d.ts +30 -0
- package/dist/ai/ai-sdk.js +83 -0
- package/dist/ai/ai-sdk.js.map +1 -0
- package/dist/ai/index.cjs +60 -0
- package/dist/ai/index.cjs.map +1 -0
- package/dist/ai/index.d.cts +155 -0
- package/dist/ai/index.d.ts +155 -0
- package/dist/ai/index.js +23 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/browser.cjs +22 -21
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +20 -19
- package/dist/browser.js.map +1 -1
- package/dist/{chunk-HLYA4QBB.js → chunk-2BM3HJSK.js} +545 -101
- package/dist/chunk-2BM3HJSK.js.map +1 -0
- package/dist/{chunk-ZO77FHBF.cjs → chunk-2JDVJRR3.cjs} +14 -6
- package/dist/chunk-2JDVJRR3.cjs.map +1 -0
- package/dist/{chunk-TIGP2OEJ.js → chunk-2VNMKOUO.js} +20 -5
- package/dist/chunk-2VNMKOUO.js.map +1 -0
- package/dist/{chunk-ULERCTGS.cjs → chunk-3YZ6FPQW.cjs} +36 -30
- package/dist/chunk-3YZ6FPQW.cjs.map +1 -0
- package/dist/{chunk-GEPBET4L.js → chunk-45KP67RR.js} +14 -6
- package/dist/chunk-45KP67RR.js.map +1 -0
- package/dist/chunk-4QP37LD3.js +1112 -0
- package/dist/chunk-4QP37LD3.js.map +1 -0
- package/dist/{chunk-HKRYKEOV.cjs → chunk-4S2WILLW.cjs} +4 -4
- package/dist/{chunk-HKRYKEOV.cjs.map → chunk-4S2WILLW.cjs.map} +1 -1
- package/dist/{chunk-IMHR3S5H.cjs → chunk-5AEN2PLB.cjs} +17 -9
- package/dist/chunk-5AEN2PLB.cjs.map +1 -0
- package/dist/{chunk-SPIW4VWP.js → chunk-5YYAYW67.js} +3 -3
- package/dist/{chunk-SPIW4VWP.js.map → chunk-5YYAYW67.js.map} +1 -1
- package/dist/{chunk-CEV3GZA3.cjs → chunk-6LZJTAA3.cjs} +552 -108
- package/dist/chunk-6LZJTAA3.cjs.map +1 -0
- package/dist/{chunk-IY52OWPG.cjs → chunk-A5D2IMOX.cjs} +18 -10
- package/dist/chunk-A5D2IMOX.cjs.map +1 -0
- package/dist/{chunk-AMP2FFES.cjs → chunk-B37IKTI7.cjs} +229 -52
- package/dist/chunk-B37IKTI7.cjs.map +1 -0
- package/dist/{chunk-LKHWBDWZ.cjs → chunk-B6INLQBU.cjs} +17 -11
- package/dist/chunk-B6INLQBU.cjs.map +1 -0
- package/dist/{chunk-DTMCQXXC.cjs → chunk-COLTVQWR.cjs} +184 -16
- package/dist/chunk-COLTVQWR.cjs.map +1 -0
- package/dist/{chunk-S6VPECM3.cjs → chunk-D7EHZFK4.cjs} +20 -5
- package/dist/chunk-D7EHZFK4.cjs.map +1 -0
- package/dist/chunk-DNZFOCV7.js +796 -0
- package/dist/chunk-DNZFOCV7.js.map +1 -0
- package/dist/{chunk-ZGKEFVJQ.cjs → chunk-E65ITQXV.cjs} +188 -32
- package/dist/chunk-E65ITQXV.cjs.map +1 -0
- package/dist/{chunk-7WXAAVR3.js → chunk-FCGHV6ZK.js} +17 -9
- package/dist/chunk-FCGHV6ZK.js.map +1 -0
- package/dist/{chunk-A74ZCP5I.js → chunk-FE6GAUNW.js} +36 -30
- package/dist/chunk-FE6GAUNW.js.map +1 -0
- package/dist/{chunk-MXJ6FHSY.js → chunk-JDTB7IKL.js} +3 -3
- package/dist/{chunk-MXJ6FHSY.js.map → chunk-JDTB7IKL.js.map} +1 -1
- package/dist/{chunk-RQX53J6M.js → chunk-LR4X4ZRG.js} +180 -24
- package/dist/chunk-LR4X4ZRG.js.map +1 -0
- package/dist/{chunk-MRGS54WN.js → chunk-M5B2UUNW.js} +3 -3
- package/dist/{chunk-MRGS54WN.js.map → chunk-M5B2UUNW.js.map} +1 -1
- package/dist/{chunk-LXNFVHDT.cjs → chunk-MCFQAUQV.cjs} +21 -13
- package/dist/chunk-MCFQAUQV.cjs.map +1 -0
- package/dist/chunk-MOU5QRZY.cjs +1121 -0
- package/dist/chunk-MOU5QRZY.cjs.map +1 -0
- package/dist/{chunk-TPA36ULU.js → chunk-OC22GGQN.js} +223 -46
- package/dist/chunk-OC22GGQN.js.map +1 -0
- package/dist/{chunk-2OIW3MAE.js → chunk-PGALHQFF.js} +3 -3
- package/dist/{chunk-2OIW3MAE.js.map → chunk-PGALHQFF.js.map} +1 -1
- package/dist/{chunk-3M7QWADF.cjs → chunk-QSQX77S2.cjs} +4 -4
- package/dist/{chunk-3M7QWADF.cjs.map → chunk-QSQX77S2.cjs.map} +1 -1
- package/dist/{chunk-VP54YPOX.cjs → chunk-QXIGHMH2.cjs} +498 -177
- package/dist/chunk-QXIGHMH2.cjs.map +1 -0
- package/dist/{chunk-YO4GU6JX.js → chunk-RP5UATRA.js} +175 -7
- package/dist/chunk-RP5UATRA.js.map +1 -0
- package/dist/{chunk-M6AMNXQ7.js → chunk-S3RBKJM5.js} +478 -157
- package/dist/chunk-S3RBKJM5.js.map +1 -0
- package/dist/{chunk-JZGFSRVT.js → chunk-SN7NTZI6.js} +9 -7
- package/dist/chunk-SN7NTZI6.js.map +1 -0
- package/dist/{chunk-L6IHSTPP.js → chunk-U6L3FAML.js} +16 -10
- package/dist/chunk-U6L3FAML.js.map +1 -0
- package/dist/{chunk-5SH5NUDW.js → chunk-UGCUNADI.js} +21 -13
- package/dist/chunk-UGCUNADI.js.map +1 -0
- package/dist/chunk-ULYRO2KY.cjs +800 -0
- package/dist/chunk-ULYRO2KY.cjs.map +1 -0
- package/dist/{chunk-4HPT4BOI.cjs → chunk-WYFXOXVK.cjs} +4 -4
- package/dist/{chunk-4HPT4BOI.cjs.map → chunk-WYFXOXVK.cjs.map} +1 -1
- package/dist/{chunk-YKO7DY2F.cjs → chunk-X7RPFTTR.cjs} +13 -13
- package/dist/{chunk-YKO7DY2F.cjs.map → chunk-X7RPFTTR.cjs.map} +1 -1
- package/dist/{chunk-4TS5NB7L.js → chunk-YQANC7HQ.js} +3 -3
- package/dist/{chunk-4TS5NB7L.js.map → chunk-YQANC7HQ.js.map} +1 -1
- package/dist/{chunk-HAIBAF6J.cjs → chunk-Z3DE6S64.cjs} +10 -8
- package/dist/chunk-Z3DE6S64.cjs.map +1 -0
- package/dist/{chunk-IQIJ6WW6.js → chunk-ZNDIGQJD.js} +15 -7
- package/dist/chunk-ZNDIGQJD.js.map +1 -0
- package/dist/{chunk-PIQG2Z5N.cjs → chunk-ZNOD4VZT.cjs} +4 -4
- package/dist/{chunk-PIQG2Z5N.cjs.map → chunk-ZNOD4VZT.cjs.map} +1 -1
- package/dist/diagrams/blockdiagram/index.cjs +5 -5
- package/dist/diagrams/blockdiagram/index.d.cts +1 -1
- package/dist/diagrams/blockdiagram/index.d.ts +1 -1
- package/dist/diagrams/blockdiagram/index.js +1 -1
- package/dist/diagrams/circuit/index.cjs +8 -8
- package/dist/diagrams/circuit/index.d.cts +1 -1
- package/dist/diagrams/circuit/index.d.ts +1 -1
- package/dist/diagrams/circuit/index.js +2 -2
- package/dist/diagrams/ecomap/index.cjs +8 -7
- package/dist/diagrams/ecomap/index.d.cts +2 -2
- package/dist/diagrams/ecomap/index.d.ts +2 -2
- package/dist/diagrams/ecomap/index.js +3 -2
- package/dist/diagrams/entity/index.cjs +6 -6
- package/dist/diagrams/entity/index.d.cts +1 -1
- package/dist/diagrams/entity/index.d.ts +1 -1
- package/dist/diagrams/entity/index.js +2 -2
- package/dist/diagrams/fishbone/index.cjs +8 -8
- package/dist/diagrams/fishbone/index.d.cts +1 -1
- package/dist/diagrams/fishbone/index.d.ts +1 -1
- package/dist/diagrams/fishbone/index.js +2 -2
- package/dist/diagrams/flowchart/index.cjs +8 -8
- package/dist/diagrams/flowchart/index.d.cts +2 -2
- package/dist/diagrams/flowchart/index.d.ts +2 -2
- package/dist/diagrams/flowchart/index.js +2 -2
- package/dist/diagrams/genogram/index.cjs +10 -9
- package/dist/diagrams/genogram/index.d.cts +1 -1
- package/dist/diagrams/genogram/index.d.ts +1 -1
- package/dist/diagrams/genogram/index.js +3 -2
- package/dist/diagrams/ladder/index.cjs +6 -6
- package/dist/diagrams/ladder/index.d.cts +1 -1
- package/dist/diagrams/ladder/index.d.ts +1 -1
- package/dist/diagrams/ladder/index.js +2 -2
- package/dist/diagrams/logic/index.cjs +6 -6
- package/dist/diagrams/logic/index.d.cts +1 -1
- package/dist/diagrams/logic/index.d.ts +1 -1
- package/dist/diagrams/logic/index.js +2 -2
- package/dist/diagrams/orgchart/index.cjs +7 -7
- package/dist/diagrams/orgchart/index.d.cts +5 -2
- package/dist/diagrams/orgchart/index.d.ts +5 -2
- package/dist/diagrams/orgchart/index.js +2 -2
- package/dist/diagrams/pedigree/index.cjs +8 -7
- package/dist/diagrams/pedigree/index.d.cts +1 -1
- package/dist/diagrams/pedigree/index.d.ts +1 -1
- package/dist/diagrams/pedigree/index.js +3 -2
- package/dist/diagrams/phylo/index.cjs +7 -7
- package/dist/diagrams/phylo/index.d.cts +1 -1
- package/dist/diagrams/phylo/index.d.ts +1 -1
- package/dist/diagrams/phylo/index.js +2 -2
- package/dist/diagrams/sld/index.cjs +6 -6
- package/dist/diagrams/sld/index.d.cts +1 -1
- package/dist/diagrams/sld/index.d.ts +1 -1
- package/dist/diagrams/sld/index.js +2 -2
- package/dist/diagrams/sociogram/index.cjs +7 -6
- package/dist/diagrams/sociogram/index.d.cts +2 -1
- package/dist/diagrams/sociogram/index.d.ts +2 -1
- package/dist/diagrams/sociogram/index.js +3 -2
- package/dist/diagrams/timing/index.cjs +4 -4
- package/dist/diagrams/timing/index.d.cts +1 -1
- package/dist/diagrams/timing/index.d.ts +1 -1
- package/dist/diagrams/timing/index.js +1 -1
- package/dist/diagrams/venn/index.cjs +9 -9
- package/dist/diagrams/venn/index.d.cts +1 -1
- package/dist/diagrams/venn/index.d.ts +1 -1
- package/dist/diagrams/venn/index.js +2 -2
- package/dist/{index-ga04CTBI.d.ts → index-C97K-kuw.d.ts} +1 -1
- package/dist/{index-SSGpCggE.d.cts → index-lsSaw3E0.d.cts} +1 -1
- package/dist/index.cjs +50 -49
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +19 -18
- package/dist/react.cjs +20 -19
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +19 -18
- package/dist/react.js.map +1 -1
- package/dist/{types-BcPhMdHd.d.cts → types-C4LnMEcB.d.cts} +58 -4
- package/dist/{types-BcPhMdHd.d.ts → types-C4LnMEcB.d.ts} +58 -4
- package/package.json +30 -7
- package/dist/chunk-5SH5NUDW.js.map +0 -1
- package/dist/chunk-7WXAAVR3.js.map +0 -1
- package/dist/chunk-A74ZCP5I.js.map +0 -1
- package/dist/chunk-AMP2FFES.cjs.map +0 -1
- package/dist/chunk-CEV3GZA3.cjs.map +0 -1
- package/dist/chunk-DTMCQXXC.cjs.map +0 -1
- package/dist/chunk-GEPBET4L.js.map +0 -1
- package/dist/chunk-HAIBAF6J.cjs.map +0 -1
- package/dist/chunk-HLYA4QBB.js.map +0 -1
- package/dist/chunk-IMHR3S5H.cjs.map +0 -1
- package/dist/chunk-IQIJ6WW6.js.map +0 -1
- package/dist/chunk-IY52OWPG.cjs.map +0 -1
- package/dist/chunk-JZGFSRVT.js.map +0 -1
- package/dist/chunk-L6IHSTPP.js.map +0 -1
- package/dist/chunk-LKHWBDWZ.cjs.map +0 -1
- package/dist/chunk-LXNFVHDT.cjs.map +0 -1
- package/dist/chunk-M6AMNXQ7.js.map +0 -1
- package/dist/chunk-RQX53J6M.js.map +0 -1
- package/dist/chunk-S6VPECM3.cjs.map +0 -1
- package/dist/chunk-TIGP2OEJ.js.map +0 -1
- package/dist/chunk-TPA36ULU.js.map +0 -1
- package/dist/chunk-ULERCTGS.cjs.map +0 -1
- package/dist/chunk-VP54YPOX.cjs.map +0 -1
- package/dist/chunk-YO4GU6JX.js.map +0 -1
- package/dist/chunk-ZGKEFVJQ.cjs.map +0 -1
- package/dist/chunk-ZO77FHBF.cjs.map +0 -1
|
@@ -0,0 +1,796 @@
|
|
|
1
|
+
import { text, group, rect, circle, polygon, line, path, el } from './chunk-KLJEK547.js';
|
|
2
|
+
|
|
3
|
+
// src/core/legend-parser.ts
|
|
4
|
+
var VALID_POSITIONS = /* @__PURE__ */ new Set([
|
|
5
|
+
"top-left",
|
|
6
|
+
"top-right",
|
|
7
|
+
"bottom-left",
|
|
8
|
+
"bottom-right",
|
|
9
|
+
"outside-right",
|
|
10
|
+
"outside-bottom",
|
|
11
|
+
"right",
|
|
12
|
+
"bottom-center",
|
|
13
|
+
"none"
|
|
14
|
+
]);
|
|
15
|
+
var VALID_KINDS = /* @__PURE__ */ new Set([
|
|
16
|
+
"shape",
|
|
17
|
+
"fill",
|
|
18
|
+
"fill-pattern",
|
|
19
|
+
"line",
|
|
20
|
+
"marker",
|
|
21
|
+
"edge"
|
|
22
|
+
]);
|
|
23
|
+
var VALID_PATTERNS = /* @__PURE__ */ new Set([
|
|
24
|
+
"solid",
|
|
25
|
+
"dashed",
|
|
26
|
+
"dotted",
|
|
27
|
+
"double",
|
|
28
|
+
"wavy",
|
|
29
|
+
"zigzag",
|
|
30
|
+
"broken"
|
|
31
|
+
]);
|
|
32
|
+
function parseLegendDirective(rawLine, overrides) {
|
|
33
|
+
const line2 = rawLine.trim();
|
|
34
|
+
if (!line2.toLowerCase().startsWith("legend")) return false;
|
|
35
|
+
const masterMatch = line2.match(/^legend\s*:\s*(.+)$/i);
|
|
36
|
+
if (masterMatch && !line2.toLowerCase().startsWith("legend.")) {
|
|
37
|
+
return applyMaster(masterMatch[1].trim(), overrides);
|
|
38
|
+
}
|
|
39
|
+
const titleMatch = line2.match(/^legend\.title\s*:\s*(.+)$/i);
|
|
40
|
+
if (titleMatch) {
|
|
41
|
+
overrides.title = unquote(titleMatch[1].trim());
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const posMatch = line2.match(/^legend\.position\s*:\s*(.+)$/i);
|
|
45
|
+
if (posMatch) {
|
|
46
|
+
const pos = posMatch[1].trim().toLowerCase();
|
|
47
|
+
if (VALID_POSITIONS.has(pos)) {
|
|
48
|
+
overrides.position = pos;
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const colsMatch = line2.match(/^legend\.columns\s*:\s*(\d+)\s*$/i);
|
|
54
|
+
if (colsMatch) {
|
|
55
|
+
overrides.columns = Number.parseInt(colsMatch[1], 10);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const labelMatch = line2.match(/^legend\.label\s+([^\s:]+)\s*:\s*(.+)$/i);
|
|
59
|
+
if (labelMatch) {
|
|
60
|
+
overrides.labels ??= {};
|
|
61
|
+
overrides.labels[labelMatch[1]] = unquote(labelMatch[2].trim());
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
const hideMatch = line2.match(/^legend\.hide\s*:\s*(.+)$/i);
|
|
65
|
+
if (hideMatch) {
|
|
66
|
+
const keys = hideMatch[1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
67
|
+
overrides.hide = (overrides.hide ?? []).concat(keys);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
const sectionHideMatch = line2.match(
|
|
71
|
+
/^legend\.section\s+([^\s.]+)\.hide\s*:\s*(true|false)\s*$/i
|
|
72
|
+
);
|
|
73
|
+
if (sectionHideMatch) {
|
|
74
|
+
const id = sectionHideMatch[1];
|
|
75
|
+
const flag = sectionHideMatch[2].toLowerCase() === "true";
|
|
76
|
+
overrides.sections ??= {};
|
|
77
|
+
overrides.sections[id] = { ...overrides.sections[id] ?? {}, hidden: flag };
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
const sectionMatch = line2.match(/^legend\.section\s+([^\s:]+)\s*:\s*(.+)$/i);
|
|
81
|
+
if (sectionMatch) {
|
|
82
|
+
const id = sectionMatch[1];
|
|
83
|
+
overrides.sections ??= {};
|
|
84
|
+
overrides.sections[id] = {
|
|
85
|
+
...overrides.sections[id] ?? {},
|
|
86
|
+
title: unquote(sectionMatch[2].trim())
|
|
87
|
+
};
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
const itemMatch = line2.match(
|
|
91
|
+
/^legend\.item\s+([^\s:]+)\s*:\s*"([^"]*)"\s*(?:\(([^)]*)\))?\s*$/i
|
|
92
|
+
);
|
|
93
|
+
if (itemMatch) {
|
|
94
|
+
const item = buildItem(itemMatch[1], itemMatch[2], itemMatch[3]);
|
|
95
|
+
if (item) {
|
|
96
|
+
overrides.added ??= [];
|
|
97
|
+
overrides.added.push(item);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
function applyMaster(value, overrides) {
|
|
104
|
+
const parts = value.split(/\s+/).filter(Boolean);
|
|
105
|
+
let consumed = false;
|
|
106
|
+
for (const tok of parts) {
|
|
107
|
+
const t = tok.toLowerCase();
|
|
108
|
+
if (t === "on" || t === "off" || t === "auto") {
|
|
109
|
+
overrides.mode = t;
|
|
110
|
+
consumed = true;
|
|
111
|
+
} else if (VALID_POSITIONS.has(t)) {
|
|
112
|
+
overrides.position = t;
|
|
113
|
+
if (overrides.mode !== "off") overrides.mode = "on";
|
|
114
|
+
consumed = true;
|
|
115
|
+
} else {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return consumed;
|
|
120
|
+
}
|
|
121
|
+
function buildItem(id, label, attrsRaw) {
|
|
122
|
+
const item = { key: id, label, kind: "fill" };
|
|
123
|
+
if (!attrsRaw) return item;
|
|
124
|
+
for (const part of attrsRaw.split(",")) {
|
|
125
|
+
const eq = part.indexOf(":");
|
|
126
|
+
if (eq < 0) continue;
|
|
127
|
+
const k = part.slice(0, eq).trim().toLowerCase();
|
|
128
|
+
const v = part.slice(eq + 1).trim();
|
|
129
|
+
switch (k) {
|
|
130
|
+
case "kind":
|
|
131
|
+
if (VALID_KINDS.has(v)) item.kind = v;
|
|
132
|
+
else return null;
|
|
133
|
+
break;
|
|
134
|
+
case "color":
|
|
135
|
+
item.color = v;
|
|
136
|
+
break;
|
|
137
|
+
case "color2":
|
|
138
|
+
item.color2 = v;
|
|
139
|
+
break;
|
|
140
|
+
case "pattern":
|
|
141
|
+
if (VALID_PATTERNS.has(v))
|
|
142
|
+
item.pattern = v;
|
|
143
|
+
break;
|
|
144
|
+
case "shape":
|
|
145
|
+
item.shape = v;
|
|
146
|
+
break;
|
|
147
|
+
case "marker":
|
|
148
|
+
item.marker = v;
|
|
149
|
+
break;
|
|
150
|
+
case "section":
|
|
151
|
+
item.section = v;
|
|
152
|
+
break;
|
|
153
|
+
case "stroke-width":
|
|
154
|
+
case "strokewidth": {
|
|
155
|
+
const n = Number.parseFloat(v);
|
|
156
|
+
if (Number.isFinite(n)) item.strokeWidth = n;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return item;
|
|
162
|
+
}
|
|
163
|
+
function unquote(s) {
|
|
164
|
+
const m = s.match(/^"(.*)"$/);
|
|
165
|
+
return m ? m[1] : s;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/core/legend.ts
|
|
169
|
+
function applyLegendOverrides(auto, overrides) {
|
|
170
|
+
if (!overrides) return resolveAuto(auto);
|
|
171
|
+
const sections = auto.sections.map((s) => {
|
|
172
|
+
const o = overrides.sections?.[s.id];
|
|
173
|
+
if (!o) return s;
|
|
174
|
+
return { ...s, title: o.title ?? s.title, hidden: o.hidden ?? s.hidden };
|
|
175
|
+
});
|
|
176
|
+
const hideSet = new Set(overrides.hide ?? []);
|
|
177
|
+
const hiddenSectionIds = new Set(
|
|
178
|
+
sections.filter((s) => s.hidden).map((s) => s.id)
|
|
179
|
+
);
|
|
180
|
+
const baseItems = auto.items.filter((it) => {
|
|
181
|
+
if (hideSet.has(it.key)) return false;
|
|
182
|
+
if (it.section && hiddenSectionIds.has(it.section)) return false;
|
|
183
|
+
return true;
|
|
184
|
+
});
|
|
185
|
+
const renamedBase = baseItems.map((it) => {
|
|
186
|
+
const newLabel = overrides.labels?.[it.key];
|
|
187
|
+
return newLabel === void 0 ? it : { ...it, label: newLabel };
|
|
188
|
+
});
|
|
189
|
+
const added = (overrides.added ?? []).map((it) => ({
|
|
190
|
+
...it,
|
|
191
|
+
section: it.section ?? "custom"
|
|
192
|
+
}));
|
|
193
|
+
let finalSections = sections;
|
|
194
|
+
if (added.some((it) => it.section === "custom") && !finalSections.some((s) => s.id === "custom")) {
|
|
195
|
+
finalSections = [...finalSections, { id: "custom", title: "Custom" }];
|
|
196
|
+
}
|
|
197
|
+
const items = [...renamedBase, ...added];
|
|
198
|
+
let mode = overrides.mode ?? auto.mode;
|
|
199
|
+
if (mode === "auto") mode = items.length > 0 ? "on" : "off";
|
|
200
|
+
return {
|
|
201
|
+
mode,
|
|
202
|
+
title: overrides.title ?? auto.title,
|
|
203
|
+
position: overrides.position ?? auto.position,
|
|
204
|
+
columns: overrides.columns ?? auto.columns,
|
|
205
|
+
sections: finalSections,
|
|
206
|
+
items
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function resolveAuto(spec) {
|
|
210
|
+
if (spec.mode !== "auto") return spec;
|
|
211
|
+
return { ...spec, mode: spec.items.length > 0 ? "on" : "off" };
|
|
212
|
+
}
|
|
213
|
+
var ZERO_BBOX = { x: 0, y: 0, w: 0, h: 0 };
|
|
214
|
+
function normalizePosition(p) {
|
|
215
|
+
switch (p) {
|
|
216
|
+
case "bottom-inline":
|
|
217
|
+
case "outside-bottom":
|
|
218
|
+
case "bottom-left":
|
|
219
|
+
case "bottom-center":
|
|
220
|
+
return "bottom-inline";
|
|
221
|
+
case "bottom-right":
|
|
222
|
+
case "outside-right":
|
|
223
|
+
case "right":
|
|
224
|
+
case "top-right":
|
|
225
|
+
case "top-left":
|
|
226
|
+
return "bottom-right";
|
|
227
|
+
case "none":
|
|
228
|
+
default:
|
|
229
|
+
return p === "none" ? "none" : "bottom-inline";
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
var FONT_SIZE = 11;
|
|
233
|
+
var SECTION_FONT_SIZE = 9;
|
|
234
|
+
var TITLE_FONT_SIZE = 12;
|
|
235
|
+
var SWATCH_W = 22;
|
|
236
|
+
var SWATCH_H = 12;
|
|
237
|
+
var SWATCH_LABEL_GAP = 8;
|
|
238
|
+
var ITEM_GAP = 18;
|
|
239
|
+
var SECTION_LABEL_GAP = 14;
|
|
240
|
+
var ROW_H = 18;
|
|
241
|
+
var INLINE_TOP_GAP = 14;
|
|
242
|
+
var INLINE_BOTTOM_PAD = 8;
|
|
243
|
+
var CARD_PAD = 4;
|
|
244
|
+
var CHAR_W = FONT_SIZE * 0.6;
|
|
245
|
+
var SECTION_CHAR_W = SECTION_FONT_SIZE * 0.85;
|
|
246
|
+
var TITLE_CHAR_W = TITLE_FONT_SIZE * 0.65;
|
|
247
|
+
var MIN_INLINE_WIDTH = 480;
|
|
248
|
+
function renderLegend(spec, anchor, theme, config) {
|
|
249
|
+
if (spec.mode === "off" || spec.position === "none" || spec.items.length === 0) {
|
|
250
|
+
return { svg: "", bbox: { ...ZERO_BBOX } };
|
|
251
|
+
}
|
|
252
|
+
const padding = anchor.padding ?? 16;
|
|
253
|
+
const layout = normalizePosition(spec.position);
|
|
254
|
+
const itemsBySection = /* @__PURE__ */ new Map();
|
|
255
|
+
for (const it of spec.items) {
|
|
256
|
+
const sid = it.section ?? "_default";
|
|
257
|
+
const arr = itemsBySection.get(sid) ?? [];
|
|
258
|
+
arr.push(it);
|
|
259
|
+
itemsBySection.set(sid, arr);
|
|
260
|
+
}
|
|
261
|
+
const declared = spec.sections.length ? spec.sections.filter(
|
|
262
|
+
(s) => !s.hidden && (itemsBySection.get(s.id)?.length ?? 0) > 0
|
|
263
|
+
) : [{ id: "_default", title: "" }];
|
|
264
|
+
const declaredIds = new Set(declared.map((s) => s.id));
|
|
265
|
+
const orderedSections = [...declared];
|
|
266
|
+
for (const [sid] of itemsBySection) {
|
|
267
|
+
if (!declaredIds.has(sid) && (itemsBySection.get(sid)?.length ?? 0) > 0) {
|
|
268
|
+
orderedSections.push({ id: sid, title: capitalize(sid) });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const showTitle = !!spec.title && spec.title !== "Legend";
|
|
272
|
+
if (layout === "bottom-inline") {
|
|
273
|
+
return renderBottomInline(
|
|
274
|
+
spec,
|
|
275
|
+
orderedSections,
|
|
276
|
+
itemsBySection,
|
|
277
|
+
anchor,
|
|
278
|
+
theme,
|
|
279
|
+
config,
|
|
280
|
+
padding,
|
|
281
|
+
showTitle
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
return renderBottomRight(
|
|
285
|
+
spec,
|
|
286
|
+
orderedSections,
|
|
287
|
+
itemsBySection,
|
|
288
|
+
anchor,
|
|
289
|
+
theme,
|
|
290
|
+
config,
|
|
291
|
+
padding,
|
|
292
|
+
showTitle
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
function renderBottomInline(spec, sections, bySection, anchor, theme, config, padding, showTitle) {
|
|
296
|
+
const effectiveCanvasW = Math.max(anchor.canvasWidth, MIN_INLINE_WIDTH);
|
|
297
|
+
const startX = padding;
|
|
298
|
+
const endX = effectiveCanvasW - padding;
|
|
299
|
+
const availW = Math.max(120, endX - startX);
|
|
300
|
+
const startY = anchor.canvasHeight + INLINE_TOP_GAP;
|
|
301
|
+
let labelColW = 0;
|
|
302
|
+
for (const s of sections) {
|
|
303
|
+
if (!s.title || s.id === "_default") continue;
|
|
304
|
+
const items = bySection.get(s.id) ?? [];
|
|
305
|
+
if (items.length === 0) continue;
|
|
306
|
+
const lw = SECTION_CHAR_W * s.title.length;
|
|
307
|
+
if (lw > labelColW) labelColW = lw;
|
|
308
|
+
}
|
|
309
|
+
if (showTitle) {
|
|
310
|
+
const tw = TITLE_CHAR_W * spec.title.length;
|
|
311
|
+
if (tw > labelColW) labelColW = tw;
|
|
312
|
+
}
|
|
313
|
+
const itemColX = labelColW > 0 ? labelColW + SECTION_LABEL_GAP : 0;
|
|
314
|
+
const itemAvailW = Math.max(80, availW - itemColX);
|
|
315
|
+
function itemWidth(it) {
|
|
316
|
+
return SWATCH_W + SWATCH_LABEL_GAP + Math.ceil(it.label.length * CHAR_W);
|
|
317
|
+
}
|
|
318
|
+
const sectionRows = [];
|
|
319
|
+
if (showTitle) {
|
|
320
|
+
sectionRows.push({ label: spec.title, rows: [[]] });
|
|
321
|
+
}
|
|
322
|
+
for (const s of sections) {
|
|
323
|
+
const items = bySection.get(s.id) ?? [];
|
|
324
|
+
if (items.length === 0) continue;
|
|
325
|
+
const rows = [];
|
|
326
|
+
let row = [];
|
|
327
|
+
let cursor = 0;
|
|
328
|
+
for (const it of items) {
|
|
329
|
+
const w = itemWidth(it);
|
|
330
|
+
const gap = row.length > 0 ? ITEM_GAP : 0;
|
|
331
|
+
if (cursor > 0 && cursor + gap + w > itemAvailW) {
|
|
332
|
+
rows.push(row);
|
|
333
|
+
row = [];
|
|
334
|
+
cursor = 0;
|
|
335
|
+
}
|
|
336
|
+
const x = cursor + (cursor > 0 ? gap : 0);
|
|
337
|
+
row.push({ item: it, x });
|
|
338
|
+
cursor = x + w;
|
|
339
|
+
}
|
|
340
|
+
if (row.length > 0) rows.push(row);
|
|
341
|
+
const label = s.title && s.id !== "_default" ? s.title.toUpperCase() : null;
|
|
342
|
+
sectionRows.push({ label, rows });
|
|
343
|
+
}
|
|
344
|
+
const out = [];
|
|
345
|
+
out.push(buildStyleBlock(theme, config.fontFamily));
|
|
346
|
+
let cursorY = startY;
|
|
347
|
+
let usedRight = 0;
|
|
348
|
+
for (let si = 0; si < sectionRows.length; si++) {
|
|
349
|
+
const sec = sectionRows[si];
|
|
350
|
+
const isTitleRow = showTitle && si === 0;
|
|
351
|
+
for (let ri = 0; ri < sec.rows.length; ri++) {
|
|
352
|
+
const yMid = cursorY + ROW_H / 2;
|
|
353
|
+
const labelBaseline = yMid + FONT_SIZE / 2 - 2;
|
|
354
|
+
const sectionBaseline = yMid + SECTION_FONT_SIZE / 2 - 1;
|
|
355
|
+
const titleBaseline = yMid + TITLE_FONT_SIZE / 2 - 2;
|
|
356
|
+
if (ri === 0) {
|
|
357
|
+
if (isTitleRow && sec.label) {
|
|
358
|
+
out.push(
|
|
359
|
+
text(
|
|
360
|
+
{ x: startX, y: titleBaseline, class: "schematex-legend-title" },
|
|
361
|
+
sec.label
|
|
362
|
+
)
|
|
363
|
+
);
|
|
364
|
+
const w = TITLE_CHAR_W * sec.label.length;
|
|
365
|
+
if (startX + w > usedRight) usedRight = startX + w;
|
|
366
|
+
} else if (sec.label) {
|
|
367
|
+
out.push(
|
|
368
|
+
text(
|
|
369
|
+
{ x: startX, y: sectionBaseline, class: "schematex-legend-section" },
|
|
370
|
+
sec.label
|
|
371
|
+
)
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
for (const cell of sec.rows[ri]) {
|
|
376
|
+
const cx = startX + itemColX + cell.x;
|
|
377
|
+
const swatchY = yMid - SWATCH_H / 2;
|
|
378
|
+
const swatch = renderSwatch(cell.item, cx, swatchY, SWATCH_W, SWATCH_H, theme);
|
|
379
|
+
const label = text(
|
|
380
|
+
{
|
|
381
|
+
x: cx + SWATCH_W + SWATCH_LABEL_GAP,
|
|
382
|
+
y: labelBaseline,
|
|
383
|
+
class: "schematex-legend-label"
|
|
384
|
+
},
|
|
385
|
+
cell.item.label
|
|
386
|
+
);
|
|
387
|
+
out.push(
|
|
388
|
+
group(
|
|
389
|
+
{
|
|
390
|
+
class: "schematex-legend-row",
|
|
391
|
+
"data-legend-key": cell.item.key,
|
|
392
|
+
"data-legend-section": cell.item.section ?? ""
|
|
393
|
+
},
|
|
394
|
+
[swatch, label]
|
|
395
|
+
)
|
|
396
|
+
);
|
|
397
|
+
const right = cx + itemWidth(cell.item);
|
|
398
|
+
if (right > usedRight) usedRight = right;
|
|
399
|
+
}
|
|
400
|
+
cursorY += ROW_H;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
const totalRows = sectionRows.reduce(
|
|
404
|
+
(sum, sec) => sum + Math.max(1, sec.rows.length),
|
|
405
|
+
0
|
|
406
|
+
);
|
|
407
|
+
const minRight = effectiveCanvasW - padding;
|
|
408
|
+
if (minRight > usedRight) usedRight = minRight;
|
|
409
|
+
const svg = group({ class: "schematex-legend" }, out);
|
|
410
|
+
const bbox = {
|
|
411
|
+
x: startX,
|
|
412
|
+
y: startY,
|
|
413
|
+
w: usedRight - startX,
|
|
414
|
+
h: totalRows * ROW_H + INLINE_BOTTOM_PAD
|
|
415
|
+
};
|
|
416
|
+
return { svg, bbox };
|
|
417
|
+
}
|
|
418
|
+
function renderBottomRight(spec, sections, bySection, anchor, theme, config, padding, showTitle) {
|
|
419
|
+
let maxRowW = 0;
|
|
420
|
+
if (showTitle) {
|
|
421
|
+
maxRowW = Math.max(maxRowW, TITLE_CHAR_W * spec.title.length);
|
|
422
|
+
}
|
|
423
|
+
for (const s of sections) {
|
|
424
|
+
const items = bySection.get(s.id) ?? [];
|
|
425
|
+
if (items.length === 0) continue;
|
|
426
|
+
if (s.title && s.id !== "_default") {
|
|
427
|
+
maxRowW = Math.max(maxRowW, SECTION_CHAR_W * s.title.length);
|
|
428
|
+
}
|
|
429
|
+
for (const it of items) {
|
|
430
|
+
const w = SWATCH_W + SWATCH_LABEL_GAP + Math.ceil(it.label.length * CHAR_W);
|
|
431
|
+
if (w > maxRowW) maxRowW = w;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
const boxW = maxRowW + CARD_PAD * 2;
|
|
435
|
+
let rowCount = 0;
|
|
436
|
+
if (showTitle) rowCount++;
|
|
437
|
+
for (const s of sections) {
|
|
438
|
+
const items = bySection.get(s.id) ?? [];
|
|
439
|
+
if (items.length === 0) continue;
|
|
440
|
+
if (s.title && s.id !== "_default") rowCount++;
|
|
441
|
+
rowCount += items.length;
|
|
442
|
+
}
|
|
443
|
+
const boxH = rowCount * ROW_H + CARD_PAD * 2;
|
|
444
|
+
const x = anchor.canvasWidth - boxW - padding;
|
|
445
|
+
const y = anchor.canvasHeight - boxH - padding;
|
|
446
|
+
const out = [];
|
|
447
|
+
out.push(buildStyleBlock(theme, config.fontFamily));
|
|
448
|
+
let cursorY = y + CARD_PAD;
|
|
449
|
+
if (showTitle) {
|
|
450
|
+
cursorY += ROW_H / 2;
|
|
451
|
+
out.push(
|
|
452
|
+
text(
|
|
453
|
+
{
|
|
454
|
+
x: x + CARD_PAD,
|
|
455
|
+
y: cursorY + TITLE_FONT_SIZE / 2 - 2,
|
|
456
|
+
class: "schematex-legend-title"
|
|
457
|
+
},
|
|
458
|
+
spec.title
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
cursorY += ROW_H / 2;
|
|
462
|
+
}
|
|
463
|
+
for (const s of sections) {
|
|
464
|
+
const items = bySection.get(s.id) ?? [];
|
|
465
|
+
if (items.length === 0) continue;
|
|
466
|
+
if (s.title && s.id !== "_default") {
|
|
467
|
+
cursorY += ROW_H / 2;
|
|
468
|
+
out.push(
|
|
469
|
+
text(
|
|
470
|
+
{
|
|
471
|
+
x: x + CARD_PAD,
|
|
472
|
+
y: cursorY + SECTION_FONT_SIZE / 2 - 1,
|
|
473
|
+
class: "schematex-legend-section"
|
|
474
|
+
},
|
|
475
|
+
s.title.toUpperCase()
|
|
476
|
+
)
|
|
477
|
+
);
|
|
478
|
+
cursorY += ROW_H / 2;
|
|
479
|
+
}
|
|
480
|
+
for (const it of items) {
|
|
481
|
+
const yMid = cursorY + ROW_H / 2;
|
|
482
|
+
const swatchY = yMid - SWATCH_H / 2;
|
|
483
|
+
const swatch = renderSwatch(it, x + CARD_PAD, swatchY, SWATCH_W, SWATCH_H, theme);
|
|
484
|
+
const label = text(
|
|
485
|
+
{
|
|
486
|
+
x: x + CARD_PAD + SWATCH_W + SWATCH_LABEL_GAP,
|
|
487
|
+
y: yMid + FONT_SIZE / 2 - 2,
|
|
488
|
+
class: "schematex-legend-label"
|
|
489
|
+
},
|
|
490
|
+
it.label
|
|
491
|
+
);
|
|
492
|
+
out.push(
|
|
493
|
+
group(
|
|
494
|
+
{
|
|
495
|
+
class: "schematex-legend-row",
|
|
496
|
+
"data-legend-key": it.key,
|
|
497
|
+
"data-legend-section": it.section ?? ""
|
|
498
|
+
},
|
|
499
|
+
[swatch, label]
|
|
500
|
+
)
|
|
501
|
+
);
|
|
502
|
+
cursorY += ROW_H;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
const svg = group({ class: "schematex-legend" }, out);
|
|
506
|
+
return { svg, bbox: { x, y, w: boxW, h: boxH } };
|
|
507
|
+
}
|
|
508
|
+
function renderSwatch(item, x, y, w, h, theme) {
|
|
509
|
+
switch (item.kind) {
|
|
510
|
+
case "shape":
|
|
511
|
+
return renderShapeSwatch(item, x, y, w, h, theme);
|
|
512
|
+
case "fill":
|
|
513
|
+
return renderFillSwatch(item, x, y, w, h, theme);
|
|
514
|
+
case "fill-pattern":
|
|
515
|
+
return renderFillPatternSwatch(item, x, y, w, h, theme);
|
|
516
|
+
case "line":
|
|
517
|
+
return renderLineSwatch(item, x, y, w, h, theme);
|
|
518
|
+
case "marker":
|
|
519
|
+
return renderMarkerSwatch(item, x, y, w, h, theme);
|
|
520
|
+
case "edge":
|
|
521
|
+
return renderEdgeSwatch(item, x, y, w, h, theme);
|
|
522
|
+
default:
|
|
523
|
+
return renderFillSwatch(item, x, y, w, h, theme);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
function renderShapeSwatch(item, x, y, w, h, theme) {
|
|
527
|
+
const shape = item.shape ?? "square";
|
|
528
|
+
const cx = x + w / 2;
|
|
529
|
+
const cy = y + h / 2;
|
|
530
|
+
const usedFill = item.fill ?? item.color ?? theme.fill;
|
|
531
|
+
const usedStroke = item.fill !== void 0 ? item.color ?? theme.stroke : theme.stroke;
|
|
532
|
+
const innerR = Math.min(w, h) / 2 - 1;
|
|
533
|
+
switch (shape) {
|
|
534
|
+
case "circle":
|
|
535
|
+
return circle({ cx, cy, r: innerR, fill: usedFill, stroke: usedStroke });
|
|
536
|
+
case "diamond": {
|
|
537
|
+
return polygon({
|
|
538
|
+
points: `${cx},${cy - innerR} ${cx + innerR},${cy} ${cx},${cy + innerR} ${cx - innerR},${cy}`,
|
|
539
|
+
fill: usedFill,
|
|
540
|
+
stroke: usedStroke
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
case "triangle": {
|
|
544
|
+
return polygon({
|
|
545
|
+
points: `${cx},${cy - innerR} ${cx + innerR},${cy + innerR * 0.8} ${cx - innerR},${cy + innerR * 0.8}`,
|
|
546
|
+
fill: usedFill,
|
|
547
|
+
stroke: usedStroke
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
case "concentric-square": {
|
|
551
|
+
const inner = rect({
|
|
552
|
+
x: x + 3,
|
|
553
|
+
y: y + 3,
|
|
554
|
+
width: w - 6,
|
|
555
|
+
height: h - 6,
|
|
556
|
+
fill: usedFill,
|
|
557
|
+
stroke: usedStroke
|
|
558
|
+
});
|
|
559
|
+
const outer = rect({
|
|
560
|
+
x: x + 1,
|
|
561
|
+
y: y + 1,
|
|
562
|
+
width: w - 2,
|
|
563
|
+
height: h - 2,
|
|
564
|
+
fill: "none",
|
|
565
|
+
stroke: usedStroke,
|
|
566
|
+
"stroke-width": 1.2
|
|
567
|
+
});
|
|
568
|
+
return inner + outer;
|
|
569
|
+
}
|
|
570
|
+
case "concentric-circle": {
|
|
571
|
+
const innerC = circle({
|
|
572
|
+
cx,
|
|
573
|
+
cy,
|
|
574
|
+
r: innerR - 2,
|
|
575
|
+
fill: usedFill,
|
|
576
|
+
stroke: usedStroke
|
|
577
|
+
});
|
|
578
|
+
const outerC = circle({
|
|
579
|
+
cx,
|
|
580
|
+
cy,
|
|
581
|
+
r: innerR,
|
|
582
|
+
fill: "none",
|
|
583
|
+
stroke: usedStroke,
|
|
584
|
+
"stroke-width": 1.2
|
|
585
|
+
});
|
|
586
|
+
return innerC + outerC;
|
|
587
|
+
}
|
|
588
|
+
case "square":
|
|
589
|
+
default:
|
|
590
|
+
return rect({
|
|
591
|
+
x: x + 1,
|
|
592
|
+
y: y + 1,
|
|
593
|
+
width: w - 2,
|
|
594
|
+
height: h - 2,
|
|
595
|
+
fill: usedFill,
|
|
596
|
+
stroke: usedStroke
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function renderFillSwatch(item, x, y, w, h, theme) {
|
|
601
|
+
return rect({
|
|
602
|
+
x: x + 1,
|
|
603
|
+
y: y + 1,
|
|
604
|
+
width: w - 2,
|
|
605
|
+
height: h - 2,
|
|
606
|
+
fill: item.color ?? theme.fill,
|
|
607
|
+
stroke: theme.stroke
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
function renderFillPatternSwatch(item, x, y, w, h, theme) {
|
|
611
|
+
const pattern = item.shape ?? "full";
|
|
612
|
+
const innerX = x + 1;
|
|
613
|
+
const innerY = y + 1;
|
|
614
|
+
const innerW = w - 2;
|
|
615
|
+
const innerH = h - 2;
|
|
616
|
+
const color = item.color ?? theme.fill;
|
|
617
|
+
const color2 = item.color2 ?? "transparent";
|
|
618
|
+
const stroke = theme.stroke;
|
|
619
|
+
const baseRect = rect({
|
|
620
|
+
x: innerX,
|
|
621
|
+
y: innerY,
|
|
622
|
+
width: innerW,
|
|
623
|
+
height: innerH,
|
|
624
|
+
fill: color2,
|
|
625
|
+
stroke
|
|
626
|
+
});
|
|
627
|
+
switch (pattern) {
|
|
628
|
+
case "half-left":
|
|
629
|
+
return baseRect + rect({ x: innerX, y: innerY, width: innerW / 2, height: innerH, fill: color });
|
|
630
|
+
case "half-right":
|
|
631
|
+
return baseRect + rect({ x: innerX + innerW / 2, y: innerY, width: innerW / 2, height: innerH, fill: color });
|
|
632
|
+
case "half-top":
|
|
633
|
+
return baseRect + rect({ x: innerX, y: innerY, width: innerW, height: innerH / 2, fill: color });
|
|
634
|
+
case "half-bottom":
|
|
635
|
+
return baseRect + rect({ x: innerX, y: innerY + innerH / 2, width: innerW, height: innerH / 2, fill: color });
|
|
636
|
+
case "quad-tl":
|
|
637
|
+
return baseRect + rect({ x: innerX, y: innerY, width: innerW / 2, height: innerH / 2, fill: color });
|
|
638
|
+
case "quad-tr":
|
|
639
|
+
return baseRect + rect({ x: innerX + innerW / 2, y: innerY, width: innerW / 2, height: innerH / 2, fill: color });
|
|
640
|
+
case "quad-bl":
|
|
641
|
+
return baseRect + rect({ x: innerX, y: innerY + innerH / 2, width: innerW / 2, height: innerH / 2, fill: color });
|
|
642
|
+
case "quad-br":
|
|
643
|
+
return baseRect + rect({ x: innerX + innerW / 2, y: innerY + innerH / 2, width: innerW / 2, height: innerH / 2, fill: color });
|
|
644
|
+
case "striped":
|
|
645
|
+
case "carrier": {
|
|
646
|
+
const stripes = [baseRect];
|
|
647
|
+
const stripeW = 2;
|
|
648
|
+
for (let sx = innerX; sx < innerX + innerW; sx += stripeW * 2) {
|
|
649
|
+
stripes.push(rect({
|
|
650
|
+
x: sx,
|
|
651
|
+
y: innerY,
|
|
652
|
+
width: Math.min(stripeW, innerX + innerW - sx),
|
|
653
|
+
height: innerH,
|
|
654
|
+
fill: color
|
|
655
|
+
}));
|
|
656
|
+
}
|
|
657
|
+
return stripes.join("");
|
|
658
|
+
}
|
|
659
|
+
case "dotted": {
|
|
660
|
+
const dots = [baseRect];
|
|
661
|
+
const cy = innerY + innerH / 2;
|
|
662
|
+
for (let dx = innerX + 3; dx < innerX + innerW - 1; dx += 4) {
|
|
663
|
+
dots.push(circle({ cx: dx, cy, r: 1, fill: color }));
|
|
664
|
+
}
|
|
665
|
+
return dots.join("");
|
|
666
|
+
}
|
|
667
|
+
case "full":
|
|
668
|
+
default:
|
|
669
|
+
return rect({
|
|
670
|
+
x: innerX,
|
|
671
|
+
y: innerY,
|
|
672
|
+
width: innerW,
|
|
673
|
+
height: innerH,
|
|
674
|
+
fill: color,
|
|
675
|
+
stroke
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function renderLineSwatch(item, x, y, w, h, theme) {
|
|
680
|
+
const cy = y + h / 2;
|
|
681
|
+
const x1 = x + 1;
|
|
682
|
+
const x2 = x + w - 1;
|
|
683
|
+
const stroke = item.color ?? theme.stroke;
|
|
684
|
+
const sw = item.strokeWidth ?? 2;
|
|
685
|
+
const dash = patternDasharray(item.pattern);
|
|
686
|
+
if (item.pattern === "double") {
|
|
687
|
+
const off = Math.max(2, sw);
|
|
688
|
+
return line({ x1, y1: cy - off, x2, y2: cy - off, stroke, "stroke-width": sw }) + line({ x1, y1: cy + off, x2, y2: cy + off, stroke, "stroke-width": sw });
|
|
689
|
+
}
|
|
690
|
+
if (item.pattern === "wavy") {
|
|
691
|
+
const amp = Math.min(h / 3, 3);
|
|
692
|
+
const period = 6;
|
|
693
|
+
const segs = [`M ${x1} ${cy}`];
|
|
694
|
+
let sx = x1;
|
|
695
|
+
let up = true;
|
|
696
|
+
while (sx < x2) {
|
|
697
|
+
const nx = Math.min(sx + period, x2);
|
|
698
|
+
segs.push(`Q ${sx + period / 2} ${cy + (up ? -amp : amp)} ${nx} ${cy}`);
|
|
699
|
+
sx = nx;
|
|
700
|
+
up = !up;
|
|
701
|
+
}
|
|
702
|
+
return path({ d: segs.join(" "), fill: "none", stroke, "stroke-width": sw });
|
|
703
|
+
}
|
|
704
|
+
const attrs = {
|
|
705
|
+
x1,
|
|
706
|
+
y1: cy,
|
|
707
|
+
x2,
|
|
708
|
+
y2: cy,
|
|
709
|
+
stroke,
|
|
710
|
+
"stroke-width": sw,
|
|
711
|
+
"stroke-linecap": "round"
|
|
712
|
+
};
|
|
713
|
+
if (dash) attrs["stroke-dasharray"] = dash;
|
|
714
|
+
return line(attrs);
|
|
715
|
+
}
|
|
716
|
+
function renderMarkerSwatch(item, x, y, w, h, theme) {
|
|
717
|
+
const cx = x + w / 2;
|
|
718
|
+
const cy = y + h / 2;
|
|
719
|
+
const color = item.color ?? theme.text;
|
|
720
|
+
const marker = item.marker ?? "dot";
|
|
721
|
+
switch (marker) {
|
|
722
|
+
case "X":
|
|
723
|
+
case "x": {
|
|
724
|
+
const r = Math.min(w, h) / 3;
|
|
725
|
+
return line({ x1: cx - r, y1: cy - r, x2: cx + r, y2: cy + r, stroke: color, "stroke-width": 1.6, "stroke-linecap": "round" }) + line({ x1: cx + r, y1: cy - r, x2: cx - r, y2: cy + r, stroke: color, "stroke-width": 1.6, "stroke-linecap": "round" });
|
|
726
|
+
}
|
|
727
|
+
case "arrow": {
|
|
728
|
+
const x1 = x + 2;
|
|
729
|
+
const x2 = x + w - 4;
|
|
730
|
+
return line({ x1, y1: cy, x2, y2: cy, stroke: color, "stroke-width": 1.6, "stroke-linecap": "round" }) + polygon({ points: `${x2},${cy - 3} ${x + w - 1},${cy} ${x2},${cy + 3}`, fill: color });
|
|
731
|
+
}
|
|
732
|
+
case "star":
|
|
733
|
+
return text(
|
|
734
|
+
{ x: cx, y: cy + 4, "text-anchor": "middle", "font-size": 14, fill: color },
|
|
735
|
+
"\u2605"
|
|
736
|
+
);
|
|
737
|
+
case "slash":
|
|
738
|
+
return line({
|
|
739
|
+
x1: cx - 4,
|
|
740
|
+
y1: cy + 5,
|
|
741
|
+
x2: cx + 4,
|
|
742
|
+
y2: cy - 5,
|
|
743
|
+
stroke: color,
|
|
744
|
+
"stroke-width": 1.6
|
|
745
|
+
});
|
|
746
|
+
case "P":
|
|
747
|
+
case "C":
|
|
748
|
+
case "E":
|
|
749
|
+
return text(
|
|
750
|
+
{ x: cx, y: cy + 4, "text-anchor": "middle", "font-size": 11, "font-weight": "bold", fill: color },
|
|
751
|
+
marker
|
|
752
|
+
);
|
|
753
|
+
case "dot":
|
|
754
|
+
default:
|
|
755
|
+
return circle({ cx, cy, r: 3, fill: color });
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
function renderEdgeSwatch(item, x, y, w, h, theme) {
|
|
759
|
+
const linePart = renderLineSwatch(item, x, y, w, h, theme);
|
|
760
|
+
if (!item.marker) return linePart;
|
|
761
|
+
return linePart + renderMarkerSwatch(item, x + w - 8, y, 12, h, theme);
|
|
762
|
+
}
|
|
763
|
+
function patternDasharray(p) {
|
|
764
|
+
switch (p) {
|
|
765
|
+
case "dashed":
|
|
766
|
+
return "5,3";
|
|
767
|
+
case "dotted":
|
|
768
|
+
return "1.5,3";
|
|
769
|
+
case "broken":
|
|
770
|
+
return "2,8";
|
|
771
|
+
case "zigzag":
|
|
772
|
+
return "8,3,2,3";
|
|
773
|
+
case "solid":
|
|
774
|
+
case void 0:
|
|
775
|
+
return null;
|
|
776
|
+
default:
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function buildStyleBlock(theme, fontFamily) {
|
|
781
|
+
const css = `
|
|
782
|
+
.schematex-legend { font-family: ${fontFamily}; }
|
|
783
|
+
.schematex-legend-title { font-size: ${TITLE_FONT_SIZE}px; font-weight: 700; fill: ${theme.text}; }
|
|
784
|
+
.schematex-legend-section { font-size: ${SECTION_FONT_SIZE}px; font-weight: 600; fill: ${theme.textMuted}; letter-spacing: 0.6px; }
|
|
785
|
+
.schematex-legend-label { font-size: ${FONT_SIZE}px; fill: ${theme.text}; dominant-baseline: alphabetic; }
|
|
786
|
+
`;
|
|
787
|
+
return el("style", {}, css);
|
|
788
|
+
}
|
|
789
|
+
function capitalize(s) {
|
|
790
|
+
if (!s) return s;
|
|
791
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
export { applyLegendOverrides, parseLegendDirective, renderLegend };
|
|
795
|
+
//# sourceMappingURL=chunk-DNZFOCV7.js.map
|
|
796
|
+
//# sourceMappingURL=chunk-DNZFOCV7.js.map
|