@syhr/dga-charts 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +31 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1187 -1112
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +31 -23
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
|
|
1
|
+
var Xt = Object.defineProperty;
|
|
2
|
+
var kt = (w, t, e) => t in w ? Xt(w, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : w[t] = e;
|
|
3
|
+
var J = (w, t, e) => kt(w, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
const Q = [
|
|
5
|
+
"#5470c6",
|
|
6
|
+
"#91cc75",
|
|
7
|
+
"#fac858",
|
|
8
|
+
"#ee6666",
|
|
9
|
+
"#73c0de",
|
|
10
|
+
"#3ba272",
|
|
11
|
+
"#fc8452",
|
|
12
|
+
"#9a60b4",
|
|
13
|
+
"#ea7ccc"
|
|
14
|
+
];
|
|
15
|
+
class pt {
|
|
5
16
|
constructor() {
|
|
6
17
|
this._h = /* @__PURE__ */ Object.create(null);
|
|
7
18
|
}
|
|
@@ -18,13 +29,13 @@ class At {
|
|
|
18
29
|
this._h = /* @__PURE__ */ Object.create(null);
|
|
19
30
|
}
|
|
20
31
|
}
|
|
21
|
-
class
|
|
32
|
+
class St {
|
|
22
33
|
constructor(t = {}) {
|
|
23
34
|
this.zoom = 1, this.panX = 0, this.panY = 0, this._min = t.min ?? 0.3, this._max = t.max ?? 6, this._step = t.step ?? 0.12, this._dragging = !1, this._dragStart = null, this._panStart = null;
|
|
24
35
|
}
|
|
25
36
|
onWheel(t, e, o) {
|
|
26
|
-
const
|
|
27
|
-
return this.panX = e - n * (e - this.panX), this.panY = o - n * (o - this.panY), this.zoom =
|
|
37
|
+
const i = t < 0 ? 1 : -1, s = Math.min(this._max, Math.max(this._min, this.zoom * (1 + i * this._step))), n = s / this.zoom;
|
|
38
|
+
return this.panX = e - n * (e - this.panX), this.panY = o - n * (o - this.panY), this.zoom = s, this;
|
|
28
39
|
}
|
|
29
40
|
startDrag(t, e) {
|
|
30
41
|
this._dragging = !0, this._dragStart = { x: t, y: e }, this._panStart = { x: this.panX, y: this.panY };
|
|
@@ -49,26 +60,26 @@ class ut {
|
|
|
49
60
|
t.translate(this.panX, this.panY), t.scale(this.zoom, this.zoom);
|
|
50
61
|
}
|
|
51
62
|
}
|
|
52
|
-
function
|
|
53
|
-
const e =
|
|
54
|
-
return `rgba(${o},${
|
|
63
|
+
function wt(w, t) {
|
|
64
|
+
const e = w.replace("#", ""), o = parseInt(e.slice(0, 2), 16), i = parseInt(e.slice(2, 4), 16), s = parseInt(e.slice(4, 6), 16);
|
|
65
|
+
return `rgba(${o},${i},${s},${t})`;
|
|
55
66
|
}
|
|
56
|
-
function
|
|
67
|
+
function X(w, t) {
|
|
57
68
|
for (const e of Object.keys(t)) {
|
|
58
69
|
const o = t[e];
|
|
59
|
-
o !== null && typeof o == "object" && !Array.isArray(o) ? (
|
|
70
|
+
o !== null && typeof o == "object" && !Array.isArray(o) ? (w[e] = w[e] && typeof w[e] == "object" ? w[e] : {}, X(w[e], o)) : w[e] = o;
|
|
60
71
|
}
|
|
61
|
-
return
|
|
72
|
+
return w;
|
|
62
73
|
}
|
|
63
|
-
function
|
|
74
|
+
function ct(w, t, e) {
|
|
64
75
|
let o = !1;
|
|
65
|
-
for (let
|
|
66
|
-
const [n,
|
|
67
|
-
|
|
76
|
+
for (let i = 0, s = e.length - 1; i < e.length; s = i++) {
|
|
77
|
+
const [n, r] = e[i], [h, a] = e[s];
|
|
78
|
+
r > t != a > t && w < (h - n) * (t - r) / (a - r) + n && (o = !o);
|
|
68
79
|
}
|
|
69
80
|
return o;
|
|
70
81
|
}
|
|
71
|
-
class
|
|
82
|
+
class vt {
|
|
72
83
|
constructor(t, e) {
|
|
73
84
|
this.container = t, this.el = document.createElement("div"), this.el.style.position = "absolute", this.el.style.pointerEvents = "none", this.el.style.display = "none", this.el.style.zIndex = "9999", this.el.style.transition = "left 0.1s, top 0.1s", window.getComputedStyle(t).position === "static" && (t.style.position = "relative"), t.appendChild(this.el), this.updateTheme(e);
|
|
74
85
|
}
|
|
@@ -76,18 +87,18 @@ class yt {
|
|
|
76
87
|
if (!t) return;
|
|
77
88
|
const e = t.tooltip || {}, o = e.textStyle || {};
|
|
78
89
|
this.el.style.backgroundColor = e.backgroundColor || t.tooltipBg || "rgba(6,13,31,0.93)", this.el.style.color = o.color || t.tooltipTextColor || "#c8ddf0";
|
|
79
|
-
let
|
|
80
|
-
typeof
|
|
81
|
-
}
|
|
82
|
-
show(t, e, o,
|
|
83
|
-
this.el.innerHTML = t, this.el.style.display = "block", this.el.style.backgroundColor =
|
|
84
|
-
const
|
|
85
|
-
this.el.style.border = `${
|
|
86
|
-
const a =
|
|
87
|
-
this.el.style.color = a.color ||
|
|
88
|
-
const
|
|
89
|
-
let
|
|
90
|
-
|
|
90
|
+
let i = e.padding !== void 0 ? e.padding : t.tooltipPadding || 10;
|
|
91
|
+
typeof i == "number" ? this.el.style.padding = `${i}px` : Array.isArray(i) ? this.el.style.padding = i.map((s) => `${s}px`).join(" ") : this.el.style.padding = i + "px", this.el.style.borderRadius = "5px", this.el.style.border = `1px solid ${t.zoneBorderColor || "rgba(255,255,255,0.25)"}`, this.el.style.boxShadow = "0 0 10px rgba(0,0,0,0.45)", this.el.style.fontFamily = t.fontFamily || "Rajdhani, sans-serif", this.el.style.fontSize = o.fontSize !== void 0 ? typeof o.fontSize == "number" ? `${o.fontSize}px` : o.fontSize : "12px";
|
|
92
|
+
}
|
|
93
|
+
show(t, e, o, i = {}, s = {}, n = null) {
|
|
94
|
+
this.el.innerHTML = t, this.el.style.display = "block", this.el.style.backgroundColor = i.backgroundColor || s.tooltipBg || "rgba(6,13,31,0.93)";
|
|
95
|
+
const r = i.borderWidth !== void 0 ? typeof i.borderWidth == "number" ? `${i.borderWidth}px` : i.borderWidth : "1px", h = i.borderColor || (n ? n.borderColor || s.zoneBorderColor || n.color : "rgba(255,255,255,0.25)");
|
|
96
|
+
this.el.style.border = `${r} solid ${h}`, i.padding !== void 0 ? typeof i.padding == "number" ? this.el.style.padding = `${i.padding}px` : Array.isArray(i.padding) ? this.el.style.padding = i.padding.map((u) => `${u}px`).join(" ") : this.el.style.padding = i.padding : this.el.style.padding = (s.tooltipPadding || 10) + "px";
|
|
97
|
+
const a = i.textStyle || {};
|
|
98
|
+
this.el.style.color = a.color || s.tooltipTextColor || "#c8ddf0", this.el.style.fontStyle = a.fontStyle || "", this.el.style.fontWeight = a.fontWeight || a.fontStyle || "", this.el.style.fontSize = a.fontSize !== void 0 ? typeof a.fontSize == "number" ? `${a.fontSize}px` : a.fontSize : "12px", this.el.style.fontFamily = s.fontFamily || "Rajdhani, sans-serif";
|
|
99
|
+
const l = this.container.getBoundingClientRect(), c = this.el.offsetWidth, d = this.el.offsetHeight;
|
|
100
|
+
let p = e + 15, b = o - d / 2;
|
|
101
|
+
p + c > l.width && (p = e - c - 15), b < 0 && (b = 0), b + d > l.height && (b = l.height - d), this.el.style.left = p + "px", this.el.style.top = b + "px";
|
|
91
102
|
}
|
|
92
103
|
hide() {
|
|
93
104
|
this.el.style.display = "none";
|
|
@@ -96,198 +107,140 @@ class yt {
|
|
|
96
107
|
this.el && this.el.parentNode && this.el.parentNode.removeChild(this.el);
|
|
97
108
|
}
|
|
98
109
|
}
|
|
99
|
-
function
|
|
100
|
-
const
|
|
101
|
-
return { left:
|
|
110
|
+
function gt(w, t, e = {}, o = 45) {
|
|
111
|
+
const i = (p, b, u) => p == null ? u : typeof p == "string" && p.endsWith("%") ? parseFloat(p) / 100 * b : parseFloat(p) || 0, s = i(e.left, w, o), n = i(e.right, w, o), r = i(e.top, t, o), h = i(e.bottom, t, o), a = Math.max(0, w - s - n), l = Math.max(0, t - r - h), c = s + a / 2, d = r + l / 2;
|
|
112
|
+
return { left: s, right: n, top: r, bottom: h, availW: a, availH: l, cx: c, cy: d };
|
|
102
113
|
}
|
|
103
|
-
function
|
|
104
|
-
const
|
|
114
|
+
function lt(w, t, e, o, i, s = 1, n = 0) {
|
|
115
|
+
const r = (i + n) * s;
|
|
105
116
|
if (o === "circle" || o === "ring")
|
|
106
|
-
|
|
117
|
+
w.arc(t, e, r, 0, Math.PI * 2);
|
|
107
118
|
else if (o === "star") {
|
|
108
|
-
const h =
|
|
119
|
+
const h = r * 0.42;
|
|
109
120
|
for (let a = 0; a < 10; a++) {
|
|
110
|
-
const
|
|
111
|
-
a === 0 ?
|
|
121
|
+
const l = a * Math.PI / 5 - Math.PI / 2, c = a % 2 === 0 ? r : h;
|
|
122
|
+
a === 0 ? w.moveTo(t + c * Math.cos(l), e + c * Math.sin(l)) : w.lineTo(t + c * Math.cos(l), e + c * Math.sin(l));
|
|
112
123
|
}
|
|
113
|
-
|
|
124
|
+
w.closePath();
|
|
114
125
|
} else if (o === "triangle") {
|
|
115
126
|
for (let h = 0; h < 3; h++) {
|
|
116
|
-
const a = -Math.PI / 2 + h * 2 * Math.PI / 3,
|
|
117
|
-
h === 0 ?
|
|
127
|
+
const a = -Math.PI / 2 + h * 2 * Math.PI / 3, l = t + r * Math.cos(a), c = e + r * Math.sin(a);
|
|
128
|
+
h === 0 ? w.moveTo(l, c) : w.lineTo(l, c);
|
|
118
129
|
}
|
|
119
|
-
|
|
130
|
+
w.closePath();
|
|
120
131
|
} else if (o === "diamond")
|
|
121
|
-
|
|
132
|
+
w.moveTo(t, e - r), w.lineTo(t + r, e), w.lineTo(t, e + r), w.lineTo(t - r, e), w.closePath();
|
|
122
133
|
else if (o === "square" || o === "rect") {
|
|
123
|
-
const h = (
|
|
124
|
-
|
|
134
|
+
const h = (i + n) * 2 * s, a = t - h / 2, l = e - h / 2;
|
|
135
|
+
w.rect(a, l, h, h);
|
|
125
136
|
} else
|
|
126
|
-
|
|
137
|
+
w.arc(t, e, r, 0, Math.PI * 2);
|
|
127
138
|
}
|
|
128
|
-
const
|
|
139
|
+
const Yt = [
|
|
129
140
|
{
|
|
130
|
-
id: "PD",
|
|
131
141
|
name: "PD",
|
|
132
|
-
desc: "局部放电",
|
|
133
142
|
color: "#A0DC99",
|
|
134
|
-
|
|
135
|
-
points: [[1, 0, 0], [0.95, 0.05, 0], [0.95, 0, 0.05]]
|
|
143
|
+
coordinates: [[1, 0, 0], [0.95, 0.05, 0], [0.95, 0, 0.05]]
|
|
136
144
|
},
|
|
137
145
|
{
|
|
138
|
-
id: "D1",
|
|
139
146
|
name: "D1",
|
|
140
|
-
desc: "低能放电",
|
|
141
147
|
color: "#77A3FC",
|
|
142
|
-
|
|
143
|
-
points: [[0.85, 0.15, 0], [0, 1, 0], [0, 0.75, 0.25], [0.6, 0.15, 0.25]]
|
|
148
|
+
coordinates: [[0.85, 0.15, 0], [0, 1, 0], [0, 0.75, 0.25], [0.6, 0.15, 0.25]]
|
|
144
149
|
},
|
|
145
150
|
{
|
|
146
|
-
id: "D2",
|
|
147
151
|
name: "D2",
|
|
148
|
-
desc: "高能放电",
|
|
149
152
|
color: "#E3F2FF",
|
|
150
|
-
|
|
151
|
-
points: [[0, 0.75, 0.25], [0, 0.28, 0.72], [0.32, 0.28, 0.4], [0.45, 0.15, 0.4], [0.6, 0.15, 0.25]]
|
|
153
|
+
coordinates: [[0, 0.75, 0.25], [0, 0.28, 0.72], [0.32, 0.28, 0.4], [0.45, 0.15, 0.4], [0.6, 0.15, 0.25]]
|
|
152
154
|
},
|
|
153
155
|
{
|
|
154
|
-
id: "T1",
|
|
155
156
|
name: "T1",
|
|
156
|
-
desc: "热故障 < 300°C",
|
|
157
157
|
color: "#CBE4FD",
|
|
158
|
-
|
|
159
|
-
points: [[0.95, 0.05, 0], [0.85, 0.05, 0.1], [0.9, 0, 0.1], [0.95, 0, 0.05]]
|
|
158
|
+
coordinates: [[0.95, 0.05, 0], [0.85, 0.05, 0.1], [0.9, 0, 0.1], [0.95, 0, 0.05]]
|
|
160
159
|
},
|
|
161
160
|
{
|
|
162
|
-
id: "T2",
|
|
163
161
|
name: "T2",
|
|
164
|
-
desc: "热故障 300 ~ 700°C",
|
|
165
162
|
color: "#56AD4A",
|
|
166
|
-
|
|
167
|
-
points: [[0.85, 0.05, 0.1], [0.45, 0.05, 0.5], [0.5, 0, 0.5], [0.9, 0, 0.1]]
|
|
163
|
+
coordinates: [[0.85, 0.05, 0.1], [0.45, 0.05, 0.5], [0.5, 0, 0.5], [0.9, 0, 0.1]]
|
|
168
164
|
},
|
|
169
165
|
{
|
|
170
|
-
id: "T3",
|
|
171
166
|
name: "T3",
|
|
172
|
-
desc: "热故障 > 700°C",
|
|
173
167
|
color: "#5490FF",
|
|
174
|
-
|
|
175
|
-
points: [[0.5, 0, 0.5], [0.35, 0.15, 0.5], [0, 0.15, 0.85], [0, 0, 1]]
|
|
168
|
+
coordinates: [[0.5, 0, 0.5], [0.35, 0.15, 0.5], [0, 0.15, 0.85], [0, 0, 1]]
|
|
176
169
|
},
|
|
177
170
|
{
|
|
178
|
-
id: "DT",
|
|
179
171
|
name: "DT",
|
|
180
|
-
desc: "混合故障(放电+热)",
|
|
181
172
|
color: "#313CFF",
|
|
182
|
-
|
|
183
|
-
points: [[0.95, 0.05, 0], [0.85, 0.15, 0], [0.45, 0.15, 0.4], [0.32, 0.28, 0.4], [0, 0.28, 0.72], [0, 0.15, 0.85], [0.35, 0.15, 0.5], [0.45, 0.05, 0.5]]
|
|
173
|
+
coordinates: [[0.95, 0.05, 0], [0.85, 0.15, 0], [0.45, 0.15, 0.4], [0.32, 0.28, 0.4], [0, 0.28, 0.72], [0, 0.15, 0.85], [0.35, 0.15, 0.5], [0.45, 0.05, 0.5]]
|
|
184
174
|
}
|
|
185
|
-
],
|
|
175
|
+
], Gt = [
|
|
186
176
|
{
|
|
187
|
-
id: "PD",
|
|
188
177
|
name: "PD",
|
|
189
|
-
desc: "电晕型局部放电",
|
|
190
178
|
color: "#A0DC99",
|
|
191
|
-
|
|
192
|
-
points: [[0.975, 0, 0.025], [0.955, 0.02, 0.025], [0.83, 0.02, 0.15], [0.85, 0, 0.15]]
|
|
179
|
+
coordinates: [[0.975, 0, 0.025], [0.955, 0.02, 0.025], [0.83, 0.02, 0.15], [0.85, 0, 0.15]]
|
|
193
180
|
},
|
|
194
181
|
{
|
|
195
|
-
id: "S",
|
|
196
182
|
name: "S",
|
|
197
|
-
desc: "温度<200℃时的杂散气体",
|
|
198
183
|
color: "#313CFF",
|
|
199
|
-
|
|
200
|
-
points: [[1, 0, 0], [0.45, 0.55, 0], [0.08, 0.52, 0.4], [0.08, 0.3, 0.62], [0.15, 0.3, 0.55], [0.15, 0.25, 0.6], [0.4, 0.25, 0.35], [0.65, 0, 0.35], [0.85, 0, 0.15], [0.83, 0.02, 0.15], [0.955, 0.02, 0.025], [0.975, 0, 0.025]]
|
|
184
|
+
coordinates: [[1, 0, 0], [0.45, 0.55, 0], [0.08, 0.52, 0.4], [0.08, 0.3, 0.62], [0.15, 0.3, 0.55], [0.15, 0.25, 0.6], [0.4, 0.25, 0.35], [0.65, 0, 0.35], [0.85, 0, 0.15], [0.83, 0.02, 0.15], [0.955, 0.02, 0.025], [0.975, 0, 0.025]]
|
|
201
185
|
},
|
|
202
186
|
{
|
|
203
|
-
id: "C",
|
|
204
187
|
name: "C",
|
|
205
|
-
desc: "绝缘纸可能碳化",
|
|
206
188
|
color: "#3587FF",
|
|
207
|
-
|
|
208
|
-
points: [[0.65, 0, 0.35], [0.4, 0.25, 0.35], [0.15, 0.25, 0.6], [0.15, 0.3, 0.55], [0, 0.3, 0.7], [0, 0, 1]]
|
|
189
|
+
coordinates: [[0.65, 0, 0.35], [0.4, 0.25, 0.35], [0.15, 0.25, 0.6], [0.15, 0.3, 0.55], [0, 0.3, 0.7], [0, 0, 1]]
|
|
209
190
|
},
|
|
210
191
|
{
|
|
211
|
-
id: "O",
|
|
212
192
|
name: "O",
|
|
213
|
-
desc: "过热温度<250℃,绝缘纸不碳化",
|
|
214
193
|
color: "#6AA4FF",
|
|
215
|
-
|
|
216
|
-
points: [[0.08, 0.92, 0], [0, 1, 0], [0, 0.3, 0.7], [0.08, 0.3, 0.62]]
|
|
194
|
+
coordinates: [[0.08, 0.92, 0], [0, 1, 0], [0, 0.3, 0.7], [0.08, 0.3, 0.62]]
|
|
217
195
|
},
|
|
218
196
|
{
|
|
219
|
-
id: "ND",
|
|
220
197
|
name: "ND",
|
|
221
|
-
desc: "未确定",
|
|
222
198
|
color: "#BEE1FD",
|
|
223
|
-
|
|
224
|
-
points: [[0.45, 0.55, 0], [0.08, 0.92, 0], [0.08, 0.52, 0.4]]
|
|
199
|
+
coordinates: [[0.45, 0.55, 0], [0.08, 0.92, 0], [0.08, 0.52, 0.4]]
|
|
225
200
|
}
|
|
226
|
-
],
|
|
201
|
+
], Vt = [
|
|
227
202
|
{
|
|
228
|
-
id: "PD",
|
|
229
203
|
name: "PD",
|
|
230
|
-
desc: "电晕型局部放电",
|
|
231
204
|
color: "#A0DC99",
|
|
232
|
-
|
|
233
|
-
points: [[0.85, 0.15, 0], [0.83, 0.15, 0.02], [0.96, 0.02, 0.02], [0.98, 0.02, 0]]
|
|
205
|
+
coordinates: [[0.85, 0.15, 0], [0.83, 0.15, 0.02], [0.96, 0.02, 0.02], [0.98, 0.02, 0]]
|
|
234
206
|
},
|
|
235
207
|
{
|
|
236
|
-
id: "T2",
|
|
237
208
|
name: "T2",
|
|
238
|
-
desc: "中温过热 (300~700℃)",
|
|
239
209
|
color: "#56AD4A",
|
|
240
|
-
|
|
241
|
-
points: [[0.9, 0, 0.1], [0.65, 0, 0.35], [0.525, 0.125, 0.35], [0.775, 0.125, 0.1]]
|
|
210
|
+
coordinates: [[0.9, 0, 0.1], [0.65, 0, 0.35], [0.525, 0.125, 0.35], [0.775, 0.125, 0.1]]
|
|
242
211
|
},
|
|
243
212
|
{
|
|
244
|
-
id: "S",
|
|
245
213
|
name: "S",
|
|
246
|
-
desc: "温度<200℃时的杂散气体",
|
|
247
214
|
color: "#313CFF",
|
|
248
|
-
|
|
249
|
-
points: [[0.85, 0.15, 0], [0.35, 0.65, 0], [0.25, 0.65, 0.1], [0.75, 0.15, 0.1]]
|
|
215
|
+
coordinates: [[0.85, 0.15, 0], [0.35, 0.65, 0], [0.25, 0.65, 0.1], [0.75, 0.15, 0.1]]
|
|
250
216
|
},
|
|
251
217
|
{
|
|
252
|
-
id: "C",
|
|
253
218
|
name: "C",
|
|
254
|
-
desc: "绝缘纸可能碳化",
|
|
255
219
|
color: "#3587FF",
|
|
256
|
-
|
|
257
|
-
points: [[0.6, 0.3, 0.1], [0, 0.3, 0.7], [0.15, 0.15, 0.7], [0.35, 0.15, 0.5], [0.375, 0.125, 0.5], [0.775, 0.125, 0.1]]
|
|
220
|
+
coordinates: [[0.6, 0.3, 0.1], [0, 0.3, 0.7], [0.15, 0.15, 0.7], [0.35, 0.15, 0.5], [0.375, 0.125, 0.5], [0.775, 0.125, 0.1]]
|
|
258
221
|
},
|
|
259
222
|
{
|
|
260
|
-
id: "O",
|
|
261
223
|
name: "O",
|
|
262
|
-
desc: "过热",
|
|
263
224
|
color: "#6AA4FF",
|
|
264
|
-
|
|
265
|
-
points: [[1, 0, 0], [0.98, 0.02, 0], [0.96, 0.02, 0.02], [0.83, 0.15, 0.02], [0.85, 0.15, 0], [0, 1, 0], [0, 0.9, 0.1], [0.35, 0.55, 0.1], [0.45, 0.55, 0], [0.85, 0.15, 0], [0.75, 0.15, 0.1], [0.9, 0, 0.1]]
|
|
225
|
+
coordinates: [[1, 0, 0], [0.98, 0.02, 0], [0.96, 0.02, 0.02], [0.83, 0.15, 0.02], [0.85, 0.15, 0], [0, 1, 0], [0, 0.9, 0.1], [0.35, 0.55, 0.1], [0.45, 0.55, 0], [0.85, 0.15, 0], [0.75, 0.15, 0.1], [0.9, 0, 0.1]]
|
|
266
226
|
},
|
|
267
227
|
{
|
|
268
|
-
id: "T3-H",
|
|
269
228
|
name: "T3-H",
|
|
270
|
-
desc: "仅矿物油过热",
|
|
271
229
|
color: "#77A3FC",
|
|
272
|
-
|
|
273
|
-
points: [[0.35, 0.3, 0.35], [0, 0.65, 0.35], [0, 0, 1], [0.65, 0, 0.35], [0.525, 0.125, 0.35], [0.375, 0.125, 0.5], [0.35, 0.15, 0.5], [0.15, 0.15, 0.7], [0, 0.3, 0.7]],
|
|
230
|
+
coordinates: [[0.35, 0.3, 0.35], [0, 0.65, 0.35], [0, 0, 1], [0.65, 0, 0.35], [0.525, 0.125, 0.35], [0.375, 0.125, 0.5], [0.35, 0.15, 0.5], [0.15, 0.15, 0.7], [0, 0.3, 0.7]],
|
|
274
231
|
labelAt: [0.1, 0.42, 0.48]
|
|
275
232
|
},
|
|
276
233
|
{
|
|
277
|
-
id: "ND",
|
|
278
234
|
name: "ND",
|
|
279
|
-
desc: "未确定",
|
|
280
235
|
color: "#E3F2FF",
|
|
281
|
-
|
|
282
|
-
points: [[0.6, 0.3, 0.1], [0, 0.9, 0.1], [0, 0.65, 0.35], [0.35, 0.3, 0.35]]
|
|
236
|
+
coordinates: [[0.6, 0.3, 0.1], [0, 0.9, 0.1], [0, 0.65, 0.35], [0.35, 0.3, 0.35]]
|
|
283
237
|
}
|
|
284
|
-
],
|
|
238
|
+
], nt = [
|
|
285
239
|
{
|
|
286
240
|
name: "PD",
|
|
287
241
|
title: "电晕型局部放电",
|
|
288
242
|
color: "#A0DC99",
|
|
289
|
-
|
|
290
|
-
poly: [
|
|
243
|
+
coordinates: [
|
|
291
244
|
[0, 33],
|
|
292
245
|
[-1, 33],
|
|
293
246
|
[-1, 24.5],
|
|
@@ -298,8 +251,7 @@ const Pt = [
|
|
|
298
251
|
name: "D1",
|
|
299
252
|
title: "低能量放电或火花型局部放电",
|
|
300
253
|
color: "#81ADFF",
|
|
301
|
-
|
|
302
|
-
poly: [
|
|
254
|
+
coordinates: [
|
|
303
255
|
[0, 40],
|
|
304
256
|
[38, 12],
|
|
305
257
|
[32, -6.1],
|
|
@@ -311,8 +263,7 @@ const Pt = [
|
|
|
311
263
|
name: "D2",
|
|
312
264
|
title: "高能量放电",
|
|
313
265
|
color: "#E3F2FF",
|
|
314
|
-
|
|
315
|
-
poly: [
|
|
266
|
+
coordinates: [
|
|
316
267
|
[4, 16],
|
|
317
268
|
[32, -6.1],
|
|
318
269
|
[24.3, -30],
|
|
@@ -324,8 +275,7 @@ const Pt = [
|
|
|
324
275
|
name: "T3",
|
|
325
276
|
title: "过热故障,t>700℃",
|
|
326
277
|
color: "#5490FF",
|
|
327
|
-
|
|
328
|
-
poly: [
|
|
278
|
+
coordinates: [
|
|
329
279
|
[0, -3],
|
|
330
280
|
[24.3, -30],
|
|
331
281
|
[23.5, -32.4],
|
|
@@ -337,8 +287,7 @@ const Pt = [
|
|
|
337
287
|
name: "T2",
|
|
338
288
|
title: "过热故障,300℃<t<700℃",
|
|
339
289
|
color: "#56AD4A",
|
|
340
|
-
|
|
341
|
-
poly: [
|
|
290
|
+
coordinates: [
|
|
342
291
|
[-6, -4],
|
|
343
292
|
[1, -32.4],
|
|
344
293
|
[-22.5, -32.4]
|
|
@@ -348,8 +297,7 @@ const Pt = [
|
|
|
348
297
|
name: "T1",
|
|
349
298
|
title: "过热故障,t<300℃",
|
|
350
299
|
color: "#CBE4FD",
|
|
351
|
-
|
|
352
|
-
poly: [
|
|
300
|
+
coordinates: [
|
|
353
301
|
[-6, -4],
|
|
354
302
|
[-22.5, -32.4],
|
|
355
303
|
[-23.5, -32.4],
|
|
@@ -362,8 +310,7 @@ const Pt = [
|
|
|
362
310
|
name: "S",
|
|
363
311
|
title: "温度<200℃时的杂散气体",
|
|
364
312
|
color: "#2735FF",
|
|
365
|
-
|
|
366
|
-
poly: [
|
|
313
|
+
coordinates: [
|
|
367
314
|
[0, 1.5],
|
|
368
315
|
[-35, 3.1],
|
|
369
316
|
[-38, 12.4],
|
|
@@ -374,13 +321,12 @@ const Pt = [
|
|
|
374
321
|
[0, 24.5]
|
|
375
322
|
]
|
|
376
323
|
}
|
|
377
|
-
],
|
|
324
|
+
], at = [
|
|
378
325
|
{
|
|
379
326
|
name: "PD",
|
|
380
327
|
title: "电晕型局部放电",
|
|
381
328
|
color: "#A0DC99",
|
|
382
|
-
|
|
383
|
-
poly: [
|
|
329
|
+
coordinates: [
|
|
384
330
|
[0, 33],
|
|
385
331
|
[-1, 33],
|
|
386
332
|
[-1, 24.5],
|
|
@@ -391,8 +337,7 @@ const Pt = [
|
|
|
391
337
|
name: "D1",
|
|
392
338
|
title: "低能量放电或火花型局部放电",
|
|
393
339
|
color: "#81ADFF",
|
|
394
|
-
|
|
395
|
-
poly: [
|
|
340
|
+
coordinates: [
|
|
396
341
|
[0, 40],
|
|
397
342
|
[38, 12],
|
|
398
343
|
[32, -6.1],
|
|
@@ -404,8 +349,7 @@ const Pt = [
|
|
|
404
349
|
name: "D2",
|
|
405
350
|
title: "高能量放电",
|
|
406
351
|
color: "#E3F2FF",
|
|
407
|
-
|
|
408
|
-
poly: [
|
|
352
|
+
coordinates: [
|
|
409
353
|
[4, 16],
|
|
410
354
|
[32, -6.1],
|
|
411
355
|
[24.3, -30],
|
|
@@ -417,8 +361,7 @@ const Pt = [
|
|
|
417
361
|
name: "S",
|
|
418
362
|
title: "温度<200℃时的杂散气体",
|
|
419
363
|
color: "#2735FF",
|
|
420
|
-
|
|
421
|
-
poly: [
|
|
364
|
+
coordinates: [
|
|
422
365
|
[0, 1.5],
|
|
423
366
|
[-35, 3.1],
|
|
424
367
|
[-38, 12.4],
|
|
@@ -433,8 +376,7 @@ const Pt = [
|
|
|
433
376
|
name: "T3-H",
|
|
434
377
|
title: "——仅矿物油过热",
|
|
435
378
|
color: "#25A53D",
|
|
436
|
-
|
|
437
|
-
poly: [
|
|
379
|
+
coordinates: [
|
|
438
380
|
[0, -3],
|
|
439
381
|
[24.3, -30],
|
|
440
382
|
[23.5, -32.4],
|
|
@@ -446,8 +388,7 @@ const Pt = [
|
|
|
446
388
|
name: "C",
|
|
447
389
|
title: "绝缘纸可能碳化",
|
|
448
390
|
color: "#3587FF",
|
|
449
|
-
|
|
450
|
-
poly: [
|
|
391
|
+
coordinates: [
|
|
451
392
|
[-3.5, -3],
|
|
452
393
|
[2.5, -32.4],
|
|
453
394
|
[-21.5, -32.4],
|
|
@@ -458,8 +399,7 @@ const Pt = [
|
|
|
458
399
|
name: "O",
|
|
459
400
|
title: "过热温度<250℃,绝缘纸不碳化",
|
|
460
401
|
color: "#6AA4FF",
|
|
461
|
-
|
|
462
|
-
poly: [
|
|
402
|
+
coordinates: [
|
|
463
403
|
[-3.5, -3],
|
|
464
404
|
[-11, -8],
|
|
465
405
|
[-21.5, -32.4],
|
|
@@ -469,217 +409,199 @@ const Pt = [
|
|
|
469
409
|
[0, -3]
|
|
470
410
|
]
|
|
471
411
|
}
|
|
472
|
-
],
|
|
412
|
+
], Ft = [
|
|
473
413
|
{
|
|
474
414
|
name: "D1/PD",
|
|
475
415
|
title: "局部放电",
|
|
476
|
-
color: "
|
|
477
|
-
|
|
478
|
-
poly: [[-2, 3], [3, 3], [3, 0], [-2, 0]]
|
|
416
|
+
color: "#51b4c8",
|
|
417
|
+
coordinates: [[-2, 3], [3, 3], [3, 0], [-2, 0]]
|
|
479
418
|
// Y >= 1 (logY >= 0), full X
|
|
480
419
|
},
|
|
481
420
|
{
|
|
482
421
|
name: "T3/DT",
|
|
483
422
|
title: "高温热故障/放电+热",
|
|
484
|
-
color: "
|
|
485
|
-
|
|
486
|
-
poly: [[-2, 0], [3, 0], [3, -2], [-2, -2]]
|
|
423
|
+
color: "#fe9d37",
|
|
424
|
+
coordinates: [[-2, 0], [3, 0], [3, -2], [-2, -2]]
|
|
487
425
|
// -2 <= logY <= 0, full X
|
|
488
426
|
},
|
|
489
427
|
{
|
|
490
428
|
name: "T1",
|
|
491
429
|
title: "过热故障,t<300℃",
|
|
492
|
-
color: "
|
|
493
|
-
|
|
494
|
-
poly: [[-2, -2], [0, -2], [0, -3], [-2, -3]]
|
|
430
|
+
color: "#df4d41",
|
|
431
|
+
coordinates: [[-2, -2], [0, -2], [0, -3], [-2, -3]]
|
|
495
432
|
},
|
|
496
433
|
{
|
|
497
434
|
name: "T2",
|
|
498
435
|
title: "过热故障,300℃<t<700℃",
|
|
499
|
-
color: "
|
|
500
|
-
|
|
501
|
-
poly: [[0, -2], [0.4, -2], [0.4, -3], [0, -3]]
|
|
436
|
+
color: "#458be6",
|
|
437
|
+
coordinates: [[0, -2], [0.4, -2], [0.4, -3], [0, -3]]
|
|
502
438
|
},
|
|
503
439
|
{
|
|
504
440
|
name: "T3",
|
|
505
441
|
title: "过热故障,t>700℃",
|
|
506
|
-
color: "
|
|
507
|
-
|
|
508
|
-
poly: [[0.4, -2], [3, -2], [3, -3], [0.4, -3]]
|
|
442
|
+
color: "#8c2fae",
|
|
443
|
+
coordinates: [[0.4, -2], [3, -2], [3, -3], [0.4, -3]]
|
|
509
444
|
}
|
|
510
|
-
],
|
|
445
|
+
], Kt = [
|
|
511
446
|
{
|
|
512
447
|
name: "D2",
|
|
513
448
|
title: "高能放电",
|
|
514
|
-
color: "
|
|
515
|
-
labelColor: "rgba(100,180,255,0.95)",
|
|
449
|
+
color: "#63a856",
|
|
516
450
|
// Y >= 10 AND X >= 10 → logY>=1, logX>=1
|
|
517
|
-
|
|
451
|
+
coordinates: [[-2, 3], [3, 3], [3, 0], [1, 0], [1, 1], [-2, 1]]
|
|
518
452
|
},
|
|
519
453
|
{
|
|
520
454
|
name: "D1",
|
|
521
455
|
title: "低能放电",
|
|
522
|
-
color: "
|
|
523
|
-
labelColor: "rgba(130,190,255,0.85)",
|
|
456
|
+
color: "#f16335",
|
|
524
457
|
// L-shape: Y>=1 AND X<10
|
|
525
458
|
// = (logY in [0,3], logX in [-2,1])
|
|
526
|
-
|
|
459
|
+
coordinates: [[-2, 1], [1, 1], [1, 0], [-2, 0]]
|
|
527
460
|
},
|
|
528
461
|
{
|
|
529
462
|
name: "PD",
|
|
530
463
|
title: "局部放电",
|
|
531
|
-
color: "
|
|
532
|
-
|
|
533
|
-
poly: [[-2, 0], [0, 0], [0, -2], [-2, -2]]
|
|
464
|
+
color: "#53b7cc",
|
|
465
|
+
coordinates: [[-2, 0], [0, 0], [0, -2], [-2, -2]]
|
|
534
466
|
},
|
|
535
467
|
{
|
|
536
468
|
name: "T3/DT",
|
|
537
469
|
title: "高温热/放电+热",
|
|
538
|
-
color: "
|
|
539
|
-
|
|
540
|
-
poly: [[0, 0], [3, 0], [3, -2], [0, -2]]
|
|
470
|
+
color: "#fe9d37",
|
|
471
|
+
coordinates: [[0, 0], [3, 0], [3, -2], [0, -2]]
|
|
541
472
|
},
|
|
542
473
|
{
|
|
543
474
|
name: "T1",
|
|
544
475
|
title: "过热故障,t<300℃",
|
|
545
|
-
color: "
|
|
546
|
-
|
|
547
|
-
poly: [[-2, -2], [0, -2], [0, -3], [-2, -3]]
|
|
476
|
+
color: "#df4d41",
|
|
477
|
+
coordinates: [[-2, -2], [0, -2], [0, -3], [-2, -3]]
|
|
548
478
|
},
|
|
549
479
|
{
|
|
550
480
|
name: "T2",
|
|
551
481
|
title: "过热故障,300℃<t<700℃",
|
|
552
|
-
color: "
|
|
553
|
-
|
|
554
|
-
poly: [[0, -2], [0.4, -2], [0.4, -3], [0, -3]]
|
|
482
|
+
color: "#458be6",
|
|
483
|
+
coordinates: [[0, -2], [0.4, -2], [0.4, -3], [0, -3]]
|
|
555
484
|
},
|
|
556
485
|
{
|
|
557
486
|
name: "T3",
|
|
558
487
|
title: "过热故障,t>700℃",
|
|
559
|
-
color: "
|
|
560
|
-
|
|
561
|
-
poly: [[0.4, -2], [3, -2], [3, -3], [0.4, -3]]
|
|
488
|
+
color: "#8c2fae",
|
|
489
|
+
coordinates: [[0.4, -2], [3, -2], [3, -3], [0.4, -3]]
|
|
562
490
|
}
|
|
563
|
-
],
|
|
491
|
+
], Rt = [
|
|
564
492
|
{
|
|
565
493
|
name: "PD",
|
|
566
494
|
title: "电晕型局部放电",
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
p1: [0, 0, 0],
|
|
570
|
-
// 开始坐标点
|
|
571
|
-
p2: [0.2, 0.1, 0.01]
|
|
495
|
+
color: "#09FAFF",
|
|
496
|
+
coordinates: [[0, 0, 0], [0.2, 0.1, 0.01]]
|
|
572
497
|
// 结束坐标点
|
|
573
498
|
},
|
|
574
499
|
{
|
|
575
500
|
name: "T1",
|
|
576
501
|
title: "过热故障,t<300℃",
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
p1: [0, 1, 0],
|
|
580
|
-
p2: [1, 10, 0.01]
|
|
502
|
+
color: "#EC9B9A",
|
|
503
|
+
coordinates: [[0, 1, 0], [1, 10, 0.01]]
|
|
581
504
|
},
|
|
582
505
|
{
|
|
583
506
|
name: "T2",
|
|
584
507
|
title: "过热故障,300℃<t<700℃",
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
p1: [1, 1, 0],
|
|
588
|
-
p2: [4, 10, 0.1]
|
|
508
|
+
color: "#A0C9F5",
|
|
509
|
+
coordinates: [[1, 1, 0], [4, 10, 0.1]]
|
|
589
510
|
},
|
|
590
511
|
{
|
|
591
512
|
name: "T3",
|
|
592
513
|
title: "过热故障,t>700℃",
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
p1: [4, 1, 0],
|
|
596
|
-
p2: [10, 10, 0.2]
|
|
514
|
+
color: "#CA677B",
|
|
515
|
+
coordinates: [[4, 1, 0], [10, 10, 0.2]]
|
|
597
516
|
},
|
|
598
517
|
{
|
|
599
518
|
name: "D1",
|
|
600
519
|
title: "低能量放电火花型局部放电",
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
p1: [1, 0.1, 1],
|
|
604
|
-
p2: [10, 0.5, 10]
|
|
520
|
+
color: "#FF7B16",
|
|
521
|
+
coordinates: [[1, 0.1, 1], [10, 0.5, 10]]
|
|
605
522
|
},
|
|
606
523
|
{
|
|
607
524
|
name: "D2",
|
|
608
525
|
title: "高能量放电",
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
p1: [2, 0.1, 0.6],
|
|
612
|
-
p2: [10, 1, 2.5]
|
|
526
|
+
color: "#48FF16",
|
|
527
|
+
coordinates: [[2, 0.1, 0.6], [10, 1, 2.5]]
|
|
613
528
|
}
|
|
614
529
|
];
|
|
615
|
-
function
|
|
616
|
-
if (!Array.isArray(
|
|
617
|
-
const t =
|
|
530
|
+
function yt(w) {
|
|
531
|
+
if (!Array.isArray(w)) return [];
|
|
532
|
+
const t = w.map((o) => Math.max(Number(o) || 0, 0)), e = t.reduce((o, i) => o + i, 0);
|
|
618
533
|
return e === 0 ? t.map(() => 0) : t.map((o) => {
|
|
619
|
-
const
|
|
620
|
-
return Math.round(
|
|
534
|
+
const i = o / e * 100;
|
|
535
|
+
return Math.round(i * 100) / 100;
|
|
621
536
|
});
|
|
622
537
|
}
|
|
623
|
-
function
|
|
624
|
-
const
|
|
538
|
+
function xt(w, t, e, o, i) {
|
|
539
|
+
const s = [w, t, e, o, i].map((d) => Math.max(0, Number(d) || 0)), n = s.reduce((d, p) => d + p, 0);
|
|
625
540
|
if (n <= 0) return null;
|
|
626
|
-
const
|
|
627
|
-
let
|
|
541
|
+
const r = s.map((d) => d / n), h = 40, a = [90, 18, -54, -126, 162];
|
|
542
|
+
let l = 0, c = 0;
|
|
628
543
|
for (let d = 0; d < 5; d++) {
|
|
629
|
-
const
|
|
630
|
-
|
|
544
|
+
const p = a[d] * Math.PI / 180;
|
|
545
|
+
l += r[d] * h * Math.cos(p), c += r[d] * h * Math.sin(p);
|
|
631
546
|
}
|
|
632
|
-
return { x:
|
|
547
|
+
return { x: l, y: c, ratio: r };
|
|
633
548
|
}
|
|
634
|
-
function
|
|
549
|
+
function _t(w, t, e) {
|
|
635
550
|
let o = !1;
|
|
636
|
-
for (let
|
|
637
|
-
const [n,
|
|
638
|
-
|
|
551
|
+
for (let i = 0, s = e.length - 1; i < e.length; s = i++) {
|
|
552
|
+
const [n, r] = e[i], [h, a] = e[s];
|
|
553
|
+
r > t != a > t && w < (h - n) * (t - r) / (a - r) + n && (o = !o);
|
|
639
554
|
}
|
|
640
555
|
return o;
|
|
641
556
|
}
|
|
642
|
-
const
|
|
643
|
-
duvalTriangle1: (
|
|
644
|
-
if (
|
|
645
|
-
const [
|
|
646
|
-
return
|
|
647
|
-
},
|
|
648
|
-
duvalTriangle4: (
|
|
649
|
-
if (
|
|
650
|
-
const [
|
|
651
|
-
return
|
|
652
|
-
},
|
|
653
|
-
duvalTriangle5: (
|
|
654
|
-
if (
|
|
655
|
-
const [
|
|
656
|
-
return
|
|
657
|
-
},
|
|
658
|
-
duvalPentagon1: (
|
|
659
|
-
const
|
|
660
|
-
if (!
|
|
661
|
-
const { x: n, y:
|
|
662
|
-
for (let a = 0; a <
|
|
663
|
-
const
|
|
664
|
-
if (
|
|
665
|
-
return { code:
|
|
557
|
+
const qt = {
|
|
558
|
+
duvalTriangle1: (w, t, e) => {
|
|
559
|
+
if (w + t + e <= 0) return { code: "INVALID", label: "无效输入" };
|
|
560
|
+
const [i, s, n] = yt([w, t, e]);
|
|
561
|
+
return i >= 98 ? { code: "PD", label: "局部放电" } : s >= 23 && n <= 13 ? { code: "D1", label: "低能放电" } : s >= 23 && s <= 40 && n >= 13 && n <= 29 ? { code: "D2", label: "高能放电" } : n <= 4 && s <= 20 ? { code: "T1", label: "热故障(t < 300℃)" } : n <= 4 && s > 20 && s <= 50 ? { code: "T2", label: "热故障(300℃ < t < 700℃)" } : n <= 15 && s >= 50 ? { code: "T3", label: "热故障(t > 700℃)" } : { code: "ND", label: "区域未定义" };
|
|
562
|
+
},
|
|
563
|
+
duvalTriangle4: (w, t, e) => {
|
|
564
|
+
if (w + t + e <= 0) return { code: "INVALID", label: "无效输入" };
|
|
565
|
+
const [i, s, n] = yt([w, t, e]);
|
|
566
|
+
return s >= 1 && n >= 2 && n <= 15 ? { code: "PD", label: "电晕型局部放电" } : i <= 9 && s >= 24 && s <= 46 && n <= 36 ? { code: "S", label: "温度<200℃时的杂散气体" } : i <= 9 && s <= 30 ? { code: "O", label: "过热温度<250℃,绝缘纸不碳化" } : s >= 24 && s <= 30 && n >= 36 ? { code: "C", label: "绝缘纸可能碳化" } : { code: "ND", label: "区域未定义" };
|
|
567
|
+
},
|
|
568
|
+
duvalTriangle5: (w, t, e) => {
|
|
569
|
+
if (w + t + e <= 0) return { code: "INVALID", label: "无效输入" };
|
|
570
|
+
const [i, s, n] = yt([w, t, e]);
|
|
571
|
+
return i >= 85 && i <= 100 && n >= 0 && n <= 15 ? { code: "PD", label: "电晕型局部放电" } : s >= 35 && s <= 100 && n >= 0 && n <= 14 || s >= 35 && s <= 70 && n >= 30 && n <= 75 ? { code: "T3", label: "高温过热故障(t > 700℃)" } : s >= 10 && s <= 35 && n >= 0 && n <= 12 ? { code: "T2", label: "中温过热故障(t > 300℃)" } : s >= 10 && s <= 70 && n >= 12 && n <= 30 ? { code: "C", label: "绝缘纸碳化故障" } : s <= 10 && n >= 15 && n <= 54 ? { code: "S", label: "矿物油杂散气体(低温过热 90℃~200℃)" } : s <= 10 && (n <= 15 || n >= 54) ? { code: "O", label: "过热故障" } : { code: "ND", label: "区域未定义" };
|
|
572
|
+
},
|
|
573
|
+
duvalPentagon1: (w, t, e, o, i) => {
|
|
574
|
+
const s = xt(w, e, o, t, i);
|
|
575
|
+
if (!s) return { code: "INVALID", label: "无效输入", desc: "", color: "" };
|
|
576
|
+
const { x: n, y: r } = s;
|
|
577
|
+
for (let a = 0; a < nt.length - 1; a++) {
|
|
578
|
+
const l = nt[a];
|
|
579
|
+
if (_t(n, r, l.poly))
|
|
580
|
+
return { code: l.name, label: l.title, desc: l.desc, color: l.color };
|
|
666
581
|
}
|
|
667
|
-
const h =
|
|
582
|
+
const h = nt[nt.length - 1];
|
|
668
583
|
return { code: h.name, label: h.title, desc: h.desc, color: h.color };
|
|
669
584
|
},
|
|
670
|
-
duvalPentagon2: (
|
|
671
|
-
const
|
|
672
|
-
if (!
|
|
673
|
-
const { x: n, y:
|
|
674
|
-
for (let a = 0; a <
|
|
675
|
-
const
|
|
676
|
-
if (
|
|
677
|
-
return { code:
|
|
585
|
+
duvalPentagon2: (w, t, e, o, i) => {
|
|
586
|
+
const s = xt(w, e, o, t, i);
|
|
587
|
+
if (!s) return { code: "INVALID", label: "无效输入", desc: "", color: "" };
|
|
588
|
+
const { x: n, y: r } = s;
|
|
589
|
+
for (let a = 0; a < at.length - 1; a++) {
|
|
590
|
+
const l = at[a];
|
|
591
|
+
if (_t(n, r, l.poly))
|
|
592
|
+
return { code: l.name, label: l.title, desc: l.desc, color: l.color };
|
|
678
593
|
}
|
|
679
|
-
const h =
|
|
594
|
+
const h = at[at.length - 1];
|
|
680
595
|
return { code: h.name, label: h.title, desc: h.desc, color: h.color };
|
|
681
596
|
}
|
|
682
|
-
}
|
|
597
|
+
};
|
|
598
|
+
function Tt(w, t) {
|
|
599
|
+
return w ? w.startsWith("#") ? wt(w, t) : w.startsWith("rgb") ? w.replace(/rgb(a)?\(([^)]+)\)/, (e, o, i) => {
|
|
600
|
+
const s = i.split(","), n = s[0].trim(), r = s[1].trim(), h = s[2].trim();
|
|
601
|
+
return `rgba(${n},${r},${h},${t})`;
|
|
602
|
+
}) : w : `rgba(0,0,0,${t})`;
|
|
603
|
+
}
|
|
604
|
+
const I = class I {
|
|
683
605
|
// 度
|
|
684
606
|
/**
|
|
685
607
|
* 将 doc 坐标(R=40,Y向上)转换为归一化 ratio 向量
|
|
@@ -688,33 +610,33 @@ const Ut = {
|
|
|
688
610
|
* @returns {number[]|null} - 长度为5的 ratio 向量,或 null(如果在五边形外)
|
|
689
611
|
*/
|
|
690
612
|
static docToRatio(t, e) {
|
|
691
|
-
const o =
|
|
692
|
-
const
|
|
693
|
-
return [o * Math.cos(
|
|
613
|
+
const o = I.DOC_R, s = I.DOC_ANGLES.map((n) => {
|
|
614
|
+
const r = n * Math.PI / 180;
|
|
615
|
+
return [o * Math.cos(r), o * Math.sin(r)];
|
|
694
616
|
});
|
|
695
617
|
for (let n = 0; n < 5; n++)
|
|
696
|
-
if (Math.hypot(t -
|
|
697
|
-
const
|
|
698
|
-
return
|
|
618
|
+
if (Math.hypot(t - s[n][0], e - s[n][1]) < 0.5) {
|
|
619
|
+
const r = [0, 0, 0, 0, 0];
|
|
620
|
+
return r[n] = 1, r;
|
|
699
621
|
}
|
|
700
622
|
for (let n = 0; n < 5; n++) {
|
|
701
|
-
const
|
|
702
|
-
if (
|
|
703
|
-
const
|
|
704
|
-
if (
|
|
705
|
-
const
|
|
706
|
-
return
|
|
623
|
+
const r = (n + 1) % 5, [h, a] = s[n], [l, c] = s[r], d = l - h, p = c - a, b = d * d + p * p;
|
|
624
|
+
if (b < 1e-10) continue;
|
|
625
|
+
const u = ((t - h) * d + (e - a) * p) / b;
|
|
626
|
+
if (u >= -1e-6 && u <= 1 + 1e-6 && Math.abs((e - a) * d - (t - h) * p) / Math.sqrt(b) < 0.15) {
|
|
627
|
+
const g = Math.max(0, Math.min(1, u)), f = [0, 0, 0, 0, 0];
|
|
628
|
+
return f[n] = 1 - g, f[r] = g, f;
|
|
707
629
|
}
|
|
708
630
|
}
|
|
709
631
|
for (let n = 0; n < 5; n++) {
|
|
710
|
-
const
|
|
711
|
-
if (Math.abs(
|
|
712
|
-
const c = ((h[1] - a[1]) * (t - a[0]) + (a[0] - h[0]) * (e - a[1])) /
|
|
713
|
-
if (c >= -0.01 && d >= -0.01 &&
|
|
714
|
-
const
|
|
715
|
-
|
|
716
|
-
const
|
|
717
|
-
return
|
|
632
|
+
const r = [0, 0], h = s[n], a = s[(n + 1) % 5], l = (h[1] - a[1]) * (r[0] - a[0]) + (a[0] - h[0]) * (r[1] - a[1]);
|
|
633
|
+
if (Math.abs(l) < 1e-10) continue;
|
|
634
|
+
const c = ((h[1] - a[1]) * (t - a[0]) + (a[0] - h[0]) * (e - a[1])) / l, d = ((a[1] - r[1]) * (t - a[0]) + (r[0] - a[0]) * (e - a[1])) / l, p = 1 - c - d;
|
|
635
|
+
if (c >= -0.01 && d >= -0.01 && p >= -0.01) {
|
|
636
|
+
const b = new Array(5).fill(c / 5);
|
|
637
|
+
b[n] += d, b[(n + 1) % 5] += p;
|
|
638
|
+
const u = b.reduce((S, g) => S + Math.max(0, g), 0);
|
|
639
|
+
return b.map((S) => Math.max(0, S) / u);
|
|
718
640
|
}
|
|
719
641
|
}
|
|
720
642
|
return null;
|
|
@@ -725,13 +647,13 @@ const Ut = {
|
|
|
725
647
|
* @returns {number[]} - [x, y] doc 坐标
|
|
726
648
|
*/
|
|
727
649
|
static ratioToDoc(t) {
|
|
728
|
-
const e =
|
|
729
|
-
let
|
|
650
|
+
const e = I.DOC_R, o = I.DOC_ANGLES;
|
|
651
|
+
let i = 0, s = 0;
|
|
730
652
|
for (let n = 0; n < 5; n++) {
|
|
731
|
-
const
|
|
732
|
-
|
|
653
|
+
const r = o[n] * Math.PI / 180;
|
|
654
|
+
i += t[n] * e * Math.cos(r), s += t[n] * e * Math.sin(r);
|
|
733
655
|
}
|
|
734
|
-
return [
|
|
656
|
+
return [i, s];
|
|
735
657
|
}
|
|
736
658
|
/**
|
|
737
659
|
* 将 canvas 像素坐标转换为归一化 ratio 向量
|
|
@@ -742,45 +664,45 @@ const Ut = {
|
|
|
742
664
|
* @param {number} R - 五边形半径
|
|
743
665
|
* @returns {number[]|null} - ratio 向量或 null
|
|
744
666
|
*/
|
|
745
|
-
static canvasToRatio(t, e, o,
|
|
746
|
-
const n = Array.from({ length: 5 }, (
|
|
747
|
-
if (!
|
|
748
|
-
for (let
|
|
749
|
-
const h = [o,
|
|
667
|
+
static canvasToRatio(t, e, o, i, s) {
|
|
668
|
+
const n = Array.from({ length: 5 }, (r, h) => I.canvasVertex(h, o, i, s));
|
|
669
|
+
if (!ct(t, e, n)) return null;
|
|
670
|
+
for (let r = 0; r < 5; r++) {
|
|
671
|
+
const h = [o, i], a = n[r], l = n[(r + 1) % 5], c = (a[1] - l[1]) * (h[0] - l[0]) + (l[0] - a[0]) * (h[1] - l[1]);
|
|
750
672
|
if (Math.abs(c) < 1e-10) continue;
|
|
751
|
-
const d = ((a[1] -
|
|
752
|
-
if (d >= -1e-9 &&
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
const
|
|
756
|
-
return
|
|
673
|
+
const d = ((a[1] - l[1]) * (t - l[0]) + (l[0] - a[0]) * (e - l[1])) / c, p = ((l[1] - h[1]) * (t - l[0]) + (h[0] - l[0]) * (e - l[1])) / c, b = 1 - d - p;
|
|
674
|
+
if (d >= -1e-9 && p >= -1e-9 && b >= -1e-9) {
|
|
675
|
+
const u = new Array(5).fill(d / 5);
|
|
676
|
+
u[r] += p, u[(r + 1) % 5] += b;
|
|
677
|
+
const S = u.reduce((g, f) => g + Math.max(0, f), 0);
|
|
678
|
+
return u.map((g) => Math.max(0, g) / S);
|
|
757
679
|
}
|
|
758
680
|
}
|
|
759
681
|
return null;
|
|
760
682
|
}
|
|
761
683
|
// canvas 顶点坐标(Y 向下,从顶部 12 点顺时针)
|
|
762
|
-
static canvasVertex(t, e, o,
|
|
763
|
-
const
|
|
764
|
-
return [e +
|
|
684
|
+
static canvasVertex(t, e, o, i) {
|
|
685
|
+
const s = -Math.PI / 2 + t * 2 * Math.PI / 5;
|
|
686
|
+
return [e + i * Math.cos(s), o + i * Math.sin(s)];
|
|
765
687
|
}
|
|
766
688
|
// doc 坐标 → canvas 坐标(直接线性映射)
|
|
767
|
-
static docToCanvas(t, e, o,
|
|
689
|
+
static docToCanvas(t, e, o, i, s) {
|
|
768
690
|
return [
|
|
769
|
-
o + t /
|
|
770
|
-
|
|
691
|
+
o + t / I.DOC_R * s,
|
|
692
|
+
i - e / I.DOC_R * s
|
|
771
693
|
// Y 轴反转
|
|
772
694
|
];
|
|
773
695
|
}
|
|
774
696
|
// poly 统一解析 → canvas 点数组
|
|
775
|
-
static polyToCanvas(t, e, o,
|
|
697
|
+
static polyToCanvas(t, e, o, i) {
|
|
776
698
|
if (t.length === 2)
|
|
777
|
-
return
|
|
778
|
-
let
|
|
779
|
-
for (let
|
|
780
|
-
const [h, a] =
|
|
781
|
-
|
|
699
|
+
return I.docToCanvas(t[0], t[1], e, o, i);
|
|
700
|
+
let s = 0, n = 0;
|
|
701
|
+
for (let r = 0; r < 5; r++) {
|
|
702
|
+
const [h, a] = I.canvasVertex(r, e, o, i);
|
|
703
|
+
s += t[r] * h, n += t[r] * a;
|
|
782
704
|
}
|
|
783
|
-
return [
|
|
705
|
+
return [s, n];
|
|
784
706
|
}
|
|
785
707
|
/**
|
|
786
708
|
* 将任意格式的 series.data 解析为归一化 ratio 向量
|
|
@@ -792,32 +714,32 @@ const Ut = {
|
|
|
792
714
|
if (!t) return null;
|
|
793
715
|
if (Array.isArray(t)) {
|
|
794
716
|
const o = t.length > 0 && t[0] && typeof t[0] == "object";
|
|
795
|
-
let
|
|
796
|
-
o && e ?
|
|
797
|
-
const
|
|
798
|
-
return Math.max(0, (
|
|
799
|
-
}) :
|
|
800
|
-
const
|
|
801
|
-
return
|
|
717
|
+
let i;
|
|
718
|
+
o && e ? i = e.map((n) => {
|
|
719
|
+
const r = t.find((h) => h.name === n);
|
|
720
|
+
return Math.max(0, (r ? r.value : 0) || 0);
|
|
721
|
+
}) : i = t.map((n) => Math.max(0, n || 0));
|
|
722
|
+
const s = i.reduce((n, r) => n + r, 0);
|
|
723
|
+
return s <= 1e-9 ? null : i.map((n) => n / s);
|
|
802
724
|
}
|
|
803
|
-
return "x" in t && "y" in t ?
|
|
725
|
+
return "x" in t && "y" in t ? I.docToRatio(t.x, t.y) : null;
|
|
804
726
|
}
|
|
805
727
|
// ratio → doc 坐标字符串(调试/显示用)
|
|
806
728
|
static ratioToDocStr(t, e = 1) {
|
|
807
|
-
const [o,
|
|
808
|
-
return `(${o.toFixed(e)}, ${
|
|
729
|
+
const [o, i] = I.ratioToDoc(t);
|
|
730
|
+
return `(${o.toFixed(e)}, ${i.toFixed(e)})`;
|
|
809
731
|
}
|
|
810
732
|
};
|
|
811
733
|
// doc 坐标系参数(固定)
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
let
|
|
815
|
-
const
|
|
734
|
+
J(I, "DOC_R", 40), // 顶点角度(数学坐标,顺时针,H2 在顶部=90°)
|
|
735
|
+
J(I, "DOC_ANGLES", [90, 18, -54, -126, 162]);
|
|
736
|
+
let Y = I;
|
|
737
|
+
const et = class et {
|
|
816
738
|
static resolve(t) {
|
|
817
|
-
return !t || t === "dark" ? { ...
|
|
739
|
+
return !t || t === "dark" ? { ...et.DARK } : t === "light" ? { ...et.LIGHT } : X({ ...et.DARK }, t);
|
|
818
740
|
}
|
|
819
741
|
};
|
|
820
|
-
|
|
742
|
+
J(et, "DARK", {
|
|
821
743
|
backgroundColor: "transparent",
|
|
822
744
|
// 画布背景色
|
|
823
745
|
pointStyle: {
|
|
@@ -853,6 +775,7 @@ K(J, "DARK", {
|
|
|
853
775
|
}
|
|
854
776
|
},
|
|
855
777
|
zone: {
|
|
778
|
+
alpha: 0.75,
|
|
856
779
|
labelStyle: {
|
|
857
780
|
show: !0,
|
|
858
781
|
color: "#ffffff",
|
|
@@ -866,15 +789,13 @@ K(J, "DARK", {
|
|
|
866
789
|
},
|
|
867
790
|
borderStyle: {
|
|
868
791
|
show: !0,
|
|
869
|
-
|
|
792
|
+
width: 1,
|
|
870
793
|
type: "solid",
|
|
871
794
|
color: "rgba(255, 255, 255, 0.25)"
|
|
872
795
|
}
|
|
873
796
|
},
|
|
874
797
|
tooltip: {
|
|
875
798
|
show: !0,
|
|
876
|
-
showDiagnostic: !1,
|
|
877
|
-
showPoint: !0,
|
|
878
799
|
backgroundColor: "rgba(6, 13, 31, 0.93)",
|
|
879
800
|
textStyle: {
|
|
880
801
|
color: "#c8ddf0",
|
|
@@ -886,7 +807,7 @@ K(J, "DARK", {
|
|
|
886
807
|
},
|
|
887
808
|
fontFamily: "Rajdhani, sans-serif"
|
|
888
809
|
// 全局字体
|
|
889
|
-
}),
|
|
810
|
+
}), J(et, "LIGHT", {
|
|
890
811
|
backgroundColor: "transparent",
|
|
891
812
|
// 画布背景色
|
|
892
813
|
pointStyle: {
|
|
@@ -935,15 +856,13 @@ K(J, "DARK", {
|
|
|
935
856
|
},
|
|
936
857
|
borderStyle: {
|
|
937
858
|
show: !0,
|
|
938
|
-
|
|
859
|
+
width: 1,
|
|
939
860
|
type: "solid",
|
|
940
861
|
color: "rgba(0, 0, 0, 0.25)"
|
|
941
862
|
}
|
|
942
863
|
},
|
|
943
864
|
tooltip: {
|
|
944
865
|
show: !0,
|
|
945
|
-
showDiagnostic: !1,
|
|
946
|
-
showPoint: !0,
|
|
947
866
|
backgroundColor: "rgba(240, 244, 248, 0.96)",
|
|
948
867
|
textStyle: {
|
|
949
868
|
color: "#334155",
|
|
@@ -956,8 +875,8 @@ K(J, "DARK", {
|
|
|
956
875
|
fontFamily: "Rajdhani, sans-serif"
|
|
957
876
|
// 全局字体
|
|
958
877
|
});
|
|
959
|
-
let
|
|
960
|
-
class
|
|
878
|
+
let dt = et;
|
|
879
|
+
class ht {
|
|
961
880
|
/**
|
|
962
881
|
* 根据 ratio 向量诊断所在故障区域
|
|
963
882
|
* @param {number[]} ratio - 待诊断的 ratio 向量
|
|
@@ -967,13 +886,14 @@ class pt {
|
|
|
967
886
|
* @param {number} R - 半径
|
|
968
887
|
* @returns {object} - 匹配的区域对象
|
|
969
888
|
*/
|
|
970
|
-
static diagnose(t, e, o,
|
|
971
|
-
const n = e && Array.isArray(e.data) ? e.data :
|
|
889
|
+
static diagnose(t, e, o, i, s) {
|
|
890
|
+
const n = e && Array.isArray(e.data) ? e.data : [];
|
|
972
891
|
if (!n.length) return null;
|
|
973
|
-
const [
|
|
892
|
+
const [r, h] = Y.polyToCanvas(t, o, i, s);
|
|
974
893
|
for (let a = 0; a < n.length - 1; a++) {
|
|
975
|
-
|
|
976
|
-
|
|
894
|
+
if (!n[a].coordinates || !n[a].coordinates.length) continue;
|
|
895
|
+
const l = n[a].coordinates.map((c) => Y.polyToCanvas(c, o, i, s));
|
|
896
|
+
if (ct(r, h, l)) return n[a];
|
|
977
897
|
}
|
|
978
898
|
return n[n.length - 1];
|
|
979
899
|
}
|
|
@@ -987,81 +907,83 @@ class pt {
|
|
|
987
907
|
* @param {number} R - 半径
|
|
988
908
|
* @param {number} S - 容器尺寸
|
|
989
909
|
*/
|
|
990
|
-
static draw(t, e, o,
|
|
991
|
-
const h = e && Array.isArray(e.data) ? e.data :
|
|
992
|
-
|
|
993
|
-
if (!
|
|
994
|
-
const
|
|
995
|
-
t.beginPath(),
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
const
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
910
|
+
static draw(t, e, o, i, s, n, r) {
|
|
911
|
+
const h = e && Array.isArray(e.data) ? e.data : [], a = e.labelStyle || {}, l = e.borderStyle || {}, c = e.alpha, d = e.colors || o.colors || Q;
|
|
912
|
+
h.forEach((b, u) => {
|
|
913
|
+
if (!b.coordinates || !b.coordinates.length) return;
|
|
914
|
+
const S = b.coordinates.map((f) => Y.polyToCanvas(f, i, s, n));
|
|
915
|
+
t.beginPath(), S.forEach(([f, y], m) => m === 0 ? t.moveTo(f, y) : t.lineTo(f, y)), t.closePath();
|
|
916
|
+
let g = b.color || d[u % d.length];
|
|
917
|
+
c !== void 0 && g !== "transparent" && (g = Tt(g, c)), t.fillStyle = g, t.fill();
|
|
918
|
+
}), h.forEach((b, u) => {
|
|
919
|
+
const S = l;
|
|
920
|
+
if (S.show === !1 || !b.coordinates || !b.coordinates.length) return;
|
|
921
|
+
const g = b.coordinates.map((y) => Y.polyToCanvas(y, i, s, n));
|
|
922
|
+
t.beginPath(), g.forEach(([y, m], v) => v === 0 ? t.moveTo(y, m) : t.lineTo(y, m)), t.closePath();
|
|
923
|
+
let f = S.color || b.color || d[u % d.length];
|
|
924
|
+
S.alpha !== void 0 && f !== "transparent" && (f = Tt(f, S.alpha)), t.strokeStyle = f, t.lineWidth = S.width ?? 1, S.type === "dashed" ? t.setLineDash([4, 4]) : S.type === "dotted" ? t.setLineDash([2, 4]) : t.setLineDash([]), t.stroke();
|
|
925
|
+
}), t.setLineDash([]);
|
|
926
|
+
const p = o.fontFamily || "Rajdhani, sans-serif";
|
|
927
|
+
for (const b of h) {
|
|
928
|
+
const u = a;
|
|
929
|
+
if (u.show === !1 || !b.name) continue;
|
|
930
|
+
const S = b.coordinates ? b.coordinates.map((T) => Y.polyToCanvas(T, i, s, n)) : [];
|
|
931
|
+
let g, f;
|
|
932
|
+
if (b.labelAt && Array.isArray(b.labelAt))
|
|
933
|
+
[g, f] = Y.polyToCanvas(b.labelAt, i, s, n);
|
|
934
|
+
else if (S.length > 0)
|
|
935
|
+
g = S.reduce((T, _) => T + _[0], 0) / S.length, f = S.reduce((T, _) => T + _[1], 0) / S.length;
|
|
1014
936
|
else
|
|
1015
937
|
continue;
|
|
1016
|
-
const y = Math.round((
|
|
1017
|
-
t.font = `${
|
|
1018
|
-
const
|
|
1019
|
-
if (
|
|
1020
|
-
let
|
|
1021
|
-
Array.isArray(
|
|
1022
|
-
const
|
|
1023
|
-
t.fillStyle =
|
|
938
|
+
const y = Math.round((u.fontSize || o.zoneLabelSize || 12) * 1), m = u.fontStyle || "bold";
|
|
939
|
+
t.font = `${m} ${y}px ${p}`, u.letterSpacing !== void 0 && "letterSpacing" in t && (t.letterSpacing = `${u.letterSpacing}px`), t.textAlign = "center", t.textBaseline = "middle";
|
|
940
|
+
const v = typeof u.formatter == "function" ? u.formatter(b) : b.name, x = t.measureText(v).width, A = y;
|
|
941
|
+
if (u.backgroundColor && u.backgroundColor !== "transparent") {
|
|
942
|
+
let T = 4, _ = 4;
|
|
943
|
+
Array.isArray(u.padding) ? (_ = u.padding[0], T = u.padding[1] !== void 0 ? u.padding[1] : _) : typeof lstyle.padding == "number" && (T = _ = lstyle.padding), T *= 1, _ *= 1;
|
|
944
|
+
const M = (u.borderRadius || 0) * 1, k = x + T * 2, P = A + _ * 2, E = g - k / 2, z = f - P / 2;
|
|
945
|
+
t.fillStyle = u.backgroundColor, t.beginPath(), t.roundRect ? t.roundRect(E, z, k, P, M) : t.rect(E, z, k, P), t.fill();
|
|
1024
946
|
}
|
|
1025
|
-
|
|
947
|
+
u.textShadow && u.textShadow !== "none" ? (t.shadowColor = u.textShadow, t.shadowBlur = 4) : (t.shadowColor = "transparent", t.shadowBlur = 0), t.fillStyle = u.color || o.zoneLabelColor || "#fff", t.fillText(v, g, f), t.shadowBlur = 0, t.shadowColor = "transparent", "letterSpacing" in t && (t.letterSpacing = "0px");
|
|
1026
948
|
}
|
|
1027
949
|
}
|
|
1028
950
|
}
|
|
1029
|
-
class
|
|
1030
|
-
static draw(t, e, o,
|
|
951
|
+
class $t {
|
|
952
|
+
static draw(t, e, o, i, s, n, r, h) {
|
|
1031
953
|
var d;
|
|
1032
|
-
const
|
|
954
|
+
const l = o.fontFamily || "Rajdhani, sans-serif";
|
|
1033
955
|
if (h && h.show !== !1) {
|
|
1034
|
-
const
|
|
1035
|
-
t.strokeStyle =
|
|
1036
|
-
for (const
|
|
956
|
+
const p = h.lineStyle || {}, b = (p.lineWidth ?? 1) * 1, u = p.lineColor || "#e5e7eb", S = p.lineType || "solid";
|
|
957
|
+
t.strokeStyle = u, t.lineWidth = b, S === "dashed" ? t.setLineDash([4, 4]) : S === "dotted" ? t.setLineDash([2, 4]) : t.setLineDash([]);
|
|
958
|
+
for (const g of [0.2, 0.4, 0.6, 0.8, 1]) {
|
|
1037
959
|
t.beginPath();
|
|
1038
|
-
for (let
|
|
1039
|
-
const [
|
|
1040
|
-
|
|
960
|
+
for (let f = 0; f < 5; f++) {
|
|
961
|
+
const [y, m] = Y.canvasVertex(f, i, s, n * g);
|
|
962
|
+
f === 0 ? t.moveTo(y, m) : t.lineTo(y, m);
|
|
1041
963
|
}
|
|
1042
964
|
t.closePath(), t.stroke();
|
|
1043
965
|
}
|
|
1044
|
-
for (let
|
|
1045
|
-
const [
|
|
1046
|
-
t.beginPath(), t.moveTo(
|
|
966
|
+
for (let g = 0; g < 5; g++) {
|
|
967
|
+
const [f, y] = Y.canvasVertex(g, i, s, n);
|
|
968
|
+
t.beginPath(), t.moveTo(i, s), t.lineTo(f, y), t.stroke();
|
|
1047
969
|
}
|
|
1048
970
|
t.setLineDash([]);
|
|
1049
971
|
}
|
|
1050
972
|
if (!e || e.show === !1) return;
|
|
1051
973
|
const c = ((d = e.labelStyle) == null ? void 0 : d.distance) !== void 0 ? e.labelStyle.distance : 27.2;
|
|
1052
|
-
e.data.forEach((
|
|
1053
|
-
const
|
|
1054
|
-
t.font = `${
|
|
974
|
+
e.data.forEach((p, b) => {
|
|
975
|
+
const u = p.labelStyle || {}, S = u.distance !== void 0 ? u.distance : c, g = typeof S == "string" && S.endsWith("%") ? parseFloat(S) / 100 * n : parseFloat(S) * 1, [f, y] = Y.canvasVertex(b, i, s, n + g), m = u.fontStyle || "normal", v = u.fontWeight || "bold", x = Math.round((u.fontSize || o.gasLabelSize || 14) * 1);
|
|
976
|
+
t.font = `${m} ${v} ${x}px ${l}`, t.fillStyle = u.color || o.gasLabelColor || "#fff", t.textAlign = "center", t.textBaseline = "middle", t.shadowColor = o.gasLabelShadow, t.shadowBlur = 7, t.fillText(p.name, f, y), t.shadowBlur = 0;
|
|
1055
977
|
});
|
|
1056
978
|
}
|
|
1057
979
|
}
|
|
1058
|
-
function
|
|
1059
|
-
const t =
|
|
980
|
+
function At(w) {
|
|
981
|
+
const t = w.trim().toLowerCase();
|
|
1060
982
|
if (t.startsWith("#")) {
|
|
1061
983
|
let o = t.slice(1);
|
|
1062
984
|
o.length === 3 && (o = o[0] + o[0] + o[1] + o[1] + o[2] + o[2]);
|
|
1063
|
-
const
|
|
1064
|
-
return [
|
|
985
|
+
const i = parseInt(o.substring(0, 2), 16), s = parseInt(o.substring(2, 4), 16), n = parseInt(o.substring(4, 6), 16), r = o.length === 8 ? parseInt(o.substring(6, 8), 16) / 255 : 1;
|
|
986
|
+
return [i, s, n, r];
|
|
1065
987
|
}
|
|
1066
988
|
const e = t.match(/rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\)/);
|
|
1067
989
|
return e ? [
|
|
@@ -1071,63 +993,63 @@ function wt(v) {
|
|
|
1071
993
|
e[4] !== void 0 ? parseFloat(e[4]) : 1
|
|
1072
994
|
] : t === "transparent" ? [0, 0, 0, 0] : [255, 255, 255, 1];
|
|
1073
995
|
}
|
|
1074
|
-
function
|
|
1075
|
-
const [o,
|
|
1076
|
-
return `rgba(${c},${d},${
|
|
996
|
+
function It(w, t, e) {
|
|
997
|
+
const [o, i, s, n] = At(w), [r, h, a, l] = At(t), c = Math.round(o + (r - o) * e), d = Math.round(i + (h - i) * e), p = Math.round(s + (a - s) * e), b = n + (l - n) * e;
|
|
998
|
+
return `rgba(${c},${d},${p},${b})`;
|
|
1077
999
|
}
|
|
1078
|
-
class
|
|
1000
|
+
class Ht {
|
|
1079
1001
|
/**
|
|
1080
1002
|
* 绘制数据点及其辉光、标签
|
|
1081
1003
|
*/
|
|
1082
|
-
static draw(t, e, o,
|
|
1004
|
+
static draw(t, e, o, i, s, n, r, h, a, l) {
|
|
1083
1005
|
if (!e || !e.data || !Array.isArray(e.data)) return [];
|
|
1084
|
-
const c = 1, d = o.fontFamily || "Rajdhani, sans-serif",
|
|
1085
|
-
if (!
|
|
1086
|
-
const
|
|
1087
|
-
if (!
|
|
1088
|
-
const
|
|
1089
|
-
let
|
|
1090
|
-
const [
|
|
1091
|
-
|
|
1092
|
-
const
|
|
1093
|
-
if (t.save(), t.globalAlpha =
|
|
1094
|
-
t.shadowColor =
|
|
1095
|
-
let
|
|
1096
|
-
if (Array.isArray(
|
|
1097
|
-
|
|
1006
|
+
const c = 1, d = o.fontFamily || "Rajdhani, sans-serif", p = [], b = e.data;
|
|
1007
|
+
if (!b || b.length === 0) return [];
|
|
1008
|
+
const u = Y.resolveData(b, h);
|
|
1009
|
+
if (!u) return [];
|
|
1010
|
+
const S = e.name, g = e.shape || "circle", f = e.color || "#409eff";
|
|
1011
|
+
let y = e.size !== void 0 ? e.size : 5;
|
|
1012
|
+
const [m, v] = Y.polyToCanvas(u, i, s, n), x = ht.diagnose(u, a, i, s, n), [A, T] = Y.ratioToDoc(u);
|
|
1013
|
+
l && l.series === e && (y *= 1.5);
|
|
1014
|
+
const M = e.itemStyle || {}, k = M.borderColor || "#fff", P = M.borderWidth !== void 0 ? M.borderWidth : 1, E = M.opacity !== void 0 ? M.opacity : 1, z = e.textStyle || {}, D = z.show !== void 0 ? z.show : !0, j = z.color || f, H = z.fontSize !== void 0 ? z.fontSize : 12, K = z.fontWeight || "normal", O = z.position || "top", ot = z.offset || [0, 0], R = e.glowStyle || {}, it = R.show !== void 0 ? R.show : !1, W = R.colors, N = R.blur !== void 0 ? R.blur : 15, $ = R.startColor || f, G = R.endColor || "transparent", q = R.count !== void 0 ? R.count : 3, Wt = R.glowDistance !== void 0 ? R.glowDistance : 2;
|
|
1015
|
+
if (t.save(), t.globalAlpha = E, it) {
|
|
1016
|
+
t.shadowColor = W ? W[0] : $, t.shadowBlur = N;
|
|
1017
|
+
let U = [], B = q;
|
|
1018
|
+
if (Array.isArray(W) && W.length > 0)
|
|
1019
|
+
U = W, B = U.length;
|
|
1098
1020
|
else
|
|
1099
|
-
for (let
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1021
|
+
for (let Z = 0; Z < B; Z++) {
|
|
1022
|
+
const tt = B > 1 ? Z / (B - 1) : 0;
|
|
1023
|
+
U.push(It($, G, tt));
|
|
1102
1024
|
}
|
|
1103
|
-
for (let
|
|
1104
|
-
const
|
|
1105
|
-
t.save(), t.fillStyle =
|
|
1025
|
+
for (let Z = B - 1; Z >= 0; Z--) {
|
|
1026
|
+
const tt = U[Z];
|
|
1027
|
+
t.save(), t.fillStyle = tt, t.beginPath(), lt(t, m, v, g, y, c, (Z + 1) * Wt), t.fill(), t.restore();
|
|
1106
1028
|
}
|
|
1107
1029
|
}
|
|
1108
|
-
if (t.beginPath(),
|
|
1109
|
-
t.save(), t.globalAlpha =
|
|
1110
|
-
let
|
|
1111
|
-
|
|
1030
|
+
if (t.beginPath(), lt(t, m, v, g, y, c, 0), g === "ring" ? (t.strokeStyle = f, t.lineWidth = P * c, t.stroke()) : (t.fillStyle = f, t.fill(), P > 0 && (t.strokeStyle = k, t.lineWidth = P * c, t.stroke())), t.restore(), D && S) {
|
|
1031
|
+
t.save(), t.globalAlpha = E, t.font = `${K} ${Math.round(H * c)}px ${d}`, t.fillStyle = j;
|
|
1032
|
+
let U = "center", B = "middle", Z = m + ot[0] * c, tt = v + ot[1] * c, st = 6 * c;
|
|
1033
|
+
g === "circle" || g === "ring" || g === "star" || g === "triangle" ? st += y * c : g === "square" && (st += y * c / 2), O === "top" ? (U = "center", B = "bottom", tt -= st) : O === "bottom" ? (U = "center", B = "top", tt += st) : O === "left" ? (U = "right", B = "middle", Z -= st) : O === "right" ? (U = "left", B = "middle", Z += st) : O === "center" && (U = "center", B = "middle"), t.textAlign = U, t.textBaseline = B, t.fillText(S, Z, tt), t.restore();
|
|
1112
1034
|
}
|
|
1113
|
-
return
|
|
1114
|
-
ratio:
|
|
1115
|
-
zone:
|
|
1116
|
-
docX:
|
|
1117
|
-
docY:
|
|
1118
|
-
rawData:
|
|
1119
|
-
name:
|
|
1035
|
+
return p.push({
|
|
1036
|
+
ratio: u,
|
|
1037
|
+
zone: x,
|
|
1038
|
+
docX: A,
|
|
1039
|
+
docY: T,
|
|
1040
|
+
rawData: b,
|
|
1041
|
+
name: S,
|
|
1120
1042
|
series: e
|
|
1121
|
-
}),
|
|
1043
|
+
}), p;
|
|
1122
1044
|
}
|
|
1123
1045
|
}
|
|
1124
|
-
const
|
|
1046
|
+
const V = class V {
|
|
1125
1047
|
constructor(t, e = {}) {
|
|
1126
1048
|
if (this._el = typeof t == "string" ? document.getElementById(t) : t, !this._el) throw new Error(`DuvalPentagon: container not found — "${t}"`);
|
|
1127
|
-
this._theme =
|
|
1049
|
+
this._theme = dt.resolve(e.theme || V.DEFAULTS.theme), this._opt = X(X(X({}, V.DEFAULTS), this._theme), e), this._normalizeOptions(), this._bus = new pt(), this._zoom = new St(this._opt.zoom), this._canvas = document.createElement("canvas"), this._ctx = this._canvas.getContext("2d"), Object.assign(this._canvas.style, { display: "block", width: "100%", height: "100%" }), this._el.appendChild(this._canvas), this._tooltipRenderer = new vt(this._el, this._theme), this._hoverRatio = null, this._hoverZone = null, this._hoverPoint = null, this._bindEvents(), this._observeResize(), this._syncCanvas(), this._renderFull();
|
|
1128
1050
|
}
|
|
1129
1051
|
_normalizeOptions() {
|
|
1130
|
-
if (this._opt.
|
|
1052
|
+
if (this._opt.vertex.data || (this._opt.vertex.data = ["H2", "C2H2", "C2H4", "CH4", "C2H6"]), !Array.isArray(this._opt.vertex.data) || this._opt.vertex.data.length !== 5)
|
|
1131
1053
|
throw new Error("DuvalPentagon: vertex.data must be an array of exactly 5 elements.");
|
|
1132
1054
|
const t = this._opt.vertex.labelStyle || {};
|
|
1133
1055
|
this._opt.vertex.data = this._opt.vertex.data.map((e) => {
|
|
@@ -1141,11 +1063,11 @@ const G = class G {
|
|
|
1141
1063
|
throw new Error("DuvalPentagon: each vertex object in vertex.data must have a 'name' property.");
|
|
1142
1064
|
return {
|
|
1143
1065
|
name: e.name,
|
|
1144
|
-
labelStyle:
|
|
1066
|
+
labelStyle: X({ ...t }, e.labelStyle || {})
|
|
1145
1067
|
};
|
|
1146
1068
|
} else
|
|
1147
1069
|
throw new Error("DuvalPentagon: vertex.data elements must be either strings or objects with a 'name' property.");
|
|
1148
|
-
}), this._opt.gasOrder = this._opt.vertex.data.map((e) => e.name), this._opt.zone ?
|
|
1070
|
+
}), this._opt.gasOrder = this._opt.vertex.data.map((e) => e.name), this._opt.zone ? typeof this._opt.zone == "object" && !this._opt.zone.data && (this._opt.zone.data = V.DEFAULT_ZONES) : this._opt.zone = { data: V.DEFAULT_ZONES };
|
|
1149
1071
|
}
|
|
1150
1072
|
/* 公开 API ─ */
|
|
1151
1073
|
/**
|
|
@@ -1154,7 +1076,7 @@ const G = class G {
|
|
|
1154
1076
|
* @returns {DuvalPentagon} - 当前实例,支持链式调用
|
|
1155
1077
|
*/
|
|
1156
1078
|
setOption(t) {
|
|
1157
|
-
return t.theme !== void 0 && (this._theme =
|
|
1079
|
+
return t.theme !== void 0 && (this._theme = dt.resolve(t.theme), this._tooltipRenderer.updateTheme(this._theme), this._opt = X(X(X({}, V.DEFAULTS), this._theme), this._opt)), X(this._opt, t), this._normalizeOptions(), this._syncCanvas(), this._render(), this;
|
|
1158
1080
|
}
|
|
1159
1081
|
/**
|
|
1160
1082
|
* 替换全部数据点并重绘
|
|
@@ -1164,6 +1086,15 @@ const G = class G {
|
|
|
1164
1086
|
setSeries(t) {
|
|
1165
1087
|
return this._opt.series = Array.isArray(t) ? t : [t], this._renderFull(), this;
|
|
1166
1088
|
}
|
|
1089
|
+
/**
|
|
1090
|
+
* 诊断指定的比值数据,返回命中的区域
|
|
1091
|
+
* @param {number[]} ratio - 五个比值数据数组
|
|
1092
|
+
* @returns {object|null} - 命中的故障区域对象
|
|
1093
|
+
*/
|
|
1094
|
+
diagnose(t) {
|
|
1095
|
+
const { cx: e, cy: o, R: i } = this._dims();
|
|
1096
|
+
return ht.diagnose(t, this._opt.zone, e, o, i);
|
|
1097
|
+
}
|
|
1167
1098
|
zoomReset() {
|
|
1168
1099
|
return this._zoom.reset(), this._renderFull(), this;
|
|
1169
1100
|
}
|
|
@@ -1184,25 +1115,25 @@ const G = class G {
|
|
|
1184
1115
|
const t = this._canvas;
|
|
1185
1116
|
this._onWheel = (e) => {
|
|
1186
1117
|
e.preventDefault();
|
|
1187
|
-
const o = t.getBoundingClientRect(),
|
|
1188
|
-
this._zoom.onWheel(e.deltaY,
|
|
1118
|
+
const o = t.getBoundingClientRect(), i = (e.clientX - o.left) * (this._cssW / o.width), s = (e.clientY - o.top) * (this._cssH / o.height);
|
|
1119
|
+
this._zoom.onWheel(e.deltaY, i, s), this._bus.emit("zoom", this._zoom.state), this._renderFull();
|
|
1189
1120
|
}, this._onDown = (e) => {
|
|
1190
1121
|
e.button === 0 && (this._zoom.startDrag(e.clientX, e.clientY), t.style.cursor = "grabbing");
|
|
1191
1122
|
}, this._onMove = (e) => {
|
|
1192
|
-
const o = t.getBoundingClientRect(),
|
|
1193
|
-
if (this._zoom.moveDrag(e.clientX, e.clientY,
|
|
1123
|
+
const o = t.getBoundingClientRect(), i = this._cssW / o.width;
|
|
1124
|
+
if (this._zoom.moveDrag(e.clientX, e.clientY, i)) {
|
|
1194
1125
|
this._renderFull();
|
|
1195
1126
|
return;
|
|
1196
1127
|
}
|
|
1197
|
-
const
|
|
1128
|
+
const s = ((e.clientX - o.left) * i - this._zoom.panX) / this._zoom.zoom, n = ((e.clientY - o.top) * i - this._zoom.panY) / this._zoom.zoom, { cx: r, cy: h, R: a, S: l } = this._dims();
|
|
1198
1129
|
let c = null, d = 1 / 0;
|
|
1199
1130
|
if (this._drawnResults)
|
|
1200
|
-
for (const
|
|
1201
|
-
const [
|
|
1202
|
-
|
|
1131
|
+
for (const u of this._drawnResults) {
|
|
1132
|
+
const [S, g] = Y.polyToCanvas(u.ratio, r, h, a), f = u.series.size || Math.max(5, l * 0.013), y = Math.hypot(S - s, g - n);
|
|
1133
|
+
y < Math.max(f * 1.5, 12) && y < d && (d = y, c = u);
|
|
1203
1134
|
}
|
|
1204
|
-
const
|
|
1205
|
-
if (c &&
|
|
1135
|
+
const b = (this._opt.tooltip || {}).show !== !1;
|
|
1136
|
+
if (c && b)
|
|
1206
1137
|
t.style.cursor = "pointer", this._hoverPoint = c, this._hoverRatio = c.ratio, this._hoverZone = c.zone, this._bus.emit("hover", {
|
|
1207
1138
|
ratio: c.ratio,
|
|
1208
1139
|
zone: c.zone,
|
|
@@ -1212,11 +1143,11 @@ const G = class G {
|
|
|
1212
1143
|
});
|
|
1213
1144
|
else {
|
|
1214
1145
|
t.style.cursor = "default", this._hoverPoint = null;
|
|
1215
|
-
const
|
|
1216
|
-
if (
|
|
1217
|
-
this._hoverRatio =
|
|
1218
|
-
const [
|
|
1219
|
-
this._bus.emit("hover", { ratio:
|
|
1146
|
+
const u = Y.canvasToRatio(s, n, r, h, a);
|
|
1147
|
+
if (u && b) {
|
|
1148
|
+
this._hoverRatio = u, this._hoverZone = ht.diagnose(u, this._opt.zone, r, h, a);
|
|
1149
|
+
const [S, g] = Y.ratioToDoc(u);
|
|
1150
|
+
this._bus.emit("hover", { ratio: u, zone: this._hoverZone, docX: S, docY: g });
|
|
1220
1151
|
} else
|
|
1221
1152
|
this._hoverRatio = null, this._hoverZone = null, this._bus.emit("hover", null);
|
|
1222
1153
|
}
|
|
@@ -1242,11 +1173,11 @@ const G = class G {
|
|
|
1242
1173
|
var a;
|
|
1243
1174
|
const t = this._cssW, e = this._cssH, o = ((a = this._opt) == null ? void 0 : a.grid) || {};
|
|
1244
1175
|
if (!(o.left !== void 0 || o.right !== void 0 || o.top !== void 0 || o.bottom !== void 0)) {
|
|
1245
|
-
const
|
|
1246
|
-
return { W: t, H: e, S:
|
|
1176
|
+
const l = Math.min(t, e);
|
|
1177
|
+
return { W: t, H: e, S: l, cx: t / 2, cy: e / 2, R: l * 0.385 };
|
|
1247
1178
|
}
|
|
1248
|
-
const
|
|
1249
|
-
return { W: t, H: e, S: h, cx:
|
|
1179
|
+
const s = gt(t, e, o, 0), r = Math.min(s.availW, s.availH) / 2, h = r / 0.385;
|
|
1180
|
+
return { W: t, H: e, S: h, cx: s.cx, cy: s.cy, R: r };
|
|
1250
1181
|
}
|
|
1251
1182
|
_render() {
|
|
1252
1183
|
this._hoverRatio = null, this._hoverZone = null, this._hoverPoint = null, this._renderFull();
|
|
@@ -1256,74 +1187,72 @@ const G = class G {
|
|
|
1256
1187
|
* @private
|
|
1257
1188
|
*/
|
|
1258
1189
|
_renderFull() {
|
|
1259
|
-
var
|
|
1190
|
+
var g;
|
|
1260
1191
|
const t = this._ctx;
|
|
1261
1192
|
if (!t) return;
|
|
1262
|
-
const e = window.devicePixelRatio || 1, { W: o, H:
|
|
1263
|
-
t.setTransform(e, 0, 0, e, 0, 0), t.clearRect(0, 0, o,
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
const
|
|
1267
|
-
for (const
|
|
1268
|
-
const
|
|
1269
|
-
Array.isArray(
|
|
1270
|
-
|
|
1193
|
+
const e = window.devicePixelRatio || 1, { W: o, H: i, S: s, cx: n, cy: r, R: h } = this._dims(), a = this._theme, l = this._opt.gasOrder, c = this._opt.zone, d = this._opt.vertex;
|
|
1194
|
+
t.setTransform(e, 0, 0, e, 0, 0), t.clearRect(0, 0, o, i);
|
|
1195
|
+
const p = this._opt.backgroundColor || a.backgroundColor || "transparent";
|
|
1196
|
+
p !== "transparent" && (t.fillStyle = p, t.fillRect(0, 0, o, i)), t.save(), this._zoom.applyTransform(t), ht.draw(t, c, a, n, r, h, s), $t.draw(t, d, a, n, r, h, s, this._opt.grid);
|
|
1197
|
+
const b = [];
|
|
1198
|
+
for (const f of this._opt.series || []) {
|
|
1199
|
+
const y = Ht.draw(t, f, a, n, r, h, s, l, c, this._hoverPoint);
|
|
1200
|
+
Array.isArray(y) && y.forEach((m) => {
|
|
1201
|
+
b.push({ series: f, ...m });
|
|
1271
1202
|
});
|
|
1272
1203
|
}
|
|
1273
|
-
this._drawnResults =
|
|
1274
|
-
const
|
|
1275
|
-
if (
|
|
1276
|
-
let
|
|
1277
|
-
|
|
1278
|
-
const
|
|
1279
|
-
let
|
|
1280
|
-
typeof
|
|
1204
|
+
this._drawnResults = b;
|
|
1205
|
+
const u = this._opt.tooltip || {};
|
|
1206
|
+
if (u.show !== !1 && this._hoverPoint) {
|
|
1207
|
+
let f = 0, y = 0;
|
|
1208
|
+
[f, y] = Y.polyToCanvas(this._hoverRatio, n, r, h);
|
|
1209
|
+
const m = f * this._zoom.zoom + this._zoom.panX, v = y * this._zoom.zoom + this._zoom.panY;
|
|
1210
|
+
let x = "";
|
|
1211
|
+
typeof u.formatter == "function" ? x = u.formatter({
|
|
1281
1212
|
ratio: this._hoverRatio,
|
|
1282
1213
|
zone: this._hoverZone,
|
|
1283
|
-
point: (
|
|
1284
|
-
gasOrder:
|
|
1285
|
-
}) :
|
|
1214
|
+
point: (g = this._hoverPoint) == null ? void 0 : g.series,
|
|
1215
|
+
gasOrder: l
|
|
1216
|
+
}) : x = this._defaultTooltipHTML(this._hoverRatio, this._hoverZone, a, l, this._hoverPoint), this._tooltipRenderer.show(x, m, v, u, a, this._hoverZone);
|
|
1286
1217
|
} else
|
|
1287
1218
|
this._tooltipRenderer.hide();
|
|
1288
|
-
t.restore(),
|
|
1219
|
+
t.restore(), b.length > 0 && this._bus.emit("diagnose", b);
|
|
1289
1220
|
}
|
|
1290
|
-
_defaultTooltipHTML(t, e, o,
|
|
1291
|
-
var
|
|
1292
|
-
const n = ((
|
|
1293
|
-
let
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
${h}
|
|
1298
|
-
<div style="color:${r}; font-size:13px; font-weight:bold; padding-bottom:8px; margin-bottom:8px; border-bottom:1px solid rgba(255,255,255,0.07);">
|
|
1299
|
-
${a}
|
|
1221
|
+
_defaultTooltipHTML(t, e, o, i, s) {
|
|
1222
|
+
var p;
|
|
1223
|
+
const n = ((p = this._opt.vertex) == null ? void 0 : p.data) || [], r = s == null ? void 0 : s.rawData, a = `<div style="font-size:14px; font-weight:bold; margin-bottom:4px; color:#fff;">${(s == null ? void 0 : s.name) || "Data Point"}</div>`, l = e ? `${e.name || ""} ${e.title || ""}`.trim() : "Outside", c = e ? e.color : "#fff";
|
|
1224
|
+
let d = `
|
|
1225
|
+
${a}
|
|
1226
|
+
<div style="color:${c}; font-size:13px; font-weight:bold; padding-bottom:8px; margin-bottom:8px; border-bottom:1px solid rgba(255,255,255,0.07);">
|
|
1227
|
+
${l}
|
|
1300
1228
|
</div>
|
|
1301
1229
|
`;
|
|
1302
|
-
return
|
|
1303
|
-
var
|
|
1304
|
-
const
|
|
1305
|
-
let
|
|
1306
|
-
if (
|
|
1307
|
-
if (Array.isArray(
|
|
1308
|
-
const x =
|
|
1230
|
+
return i.forEach((b, u) => {
|
|
1231
|
+
var f, y, m, v;
|
|
1232
|
+
const S = ((y = (f = n[u]) == null ? void 0 : f.labelStyle) == null ? void 0 : y.color) || ((v = (m = o.vertex) == null ? void 0 : m.labelStyle) == null ? void 0 : v.color) || "#fff";
|
|
1233
|
+
let g = "-";
|
|
1234
|
+
if (r)
|
|
1235
|
+
if (Array.isArray(r)) {
|
|
1236
|
+
const x = r[u];
|
|
1309
1237
|
if (x && typeof x == "object") {
|
|
1310
|
-
const
|
|
1311
|
-
|
|
1238
|
+
const A = r.find((T) => T.name === b);
|
|
1239
|
+
g = A && A.value !== void 0 ? A.value : "-";
|
|
1312
1240
|
} else
|
|
1313
|
-
|
|
1314
|
-
} else typeof
|
|
1315
|
-
|
|
1241
|
+
g = r[u] !== void 0 ? r[u] : "-";
|
|
1242
|
+
} else typeof r == "object" && (g = r[b] !== void 0 ? r[b] : "-");
|
|
1243
|
+
d += `
|
|
1316
1244
|
<div style="display:flex; align-items:center; margin-bottom:6px; font-size:13px;">
|
|
1317
|
-
<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background-color:${
|
|
1318
|
-
<span style="color:#cbd5e1; flex-grow:1;">${
|
|
1319
|
-
<span style="color:#fff; font-weight:bold; margin-left:20px;">${
|
|
1245
|
+
<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background-color:${S}; margin-right:8px;"></span>
|
|
1246
|
+
<span style="color:#cbd5e1; flex-grow:1;">${b}</span>
|
|
1247
|
+
<span style="color:#fff; font-weight:bold; margin-left:20px;">${g}</span>
|
|
1320
1248
|
</div>
|
|
1321
1249
|
`;
|
|
1322
|
-
}),
|
|
1250
|
+
}), d;
|
|
1323
1251
|
}
|
|
1324
1252
|
};
|
|
1325
|
-
|
|
1253
|
+
J(V, "DEFAULT_ZONES", nt), J(V, "DEFAULTS", {
|
|
1326
1254
|
theme: "dark",
|
|
1255
|
+
colors: Q,
|
|
1327
1256
|
vertex: {
|
|
1328
1257
|
show: !0,
|
|
1329
1258
|
data: ["H2", "C2H2", "C2H4", "CH4", "C2H6"]
|
|
@@ -1335,14 +1264,13 @@ K(G, "DEFAULT_ZONES", st), K(G, "DEFAULTS", {
|
|
|
1335
1264
|
},
|
|
1336
1265
|
zoom: { min: 0.3, max: 6, step: 0.12 },
|
|
1337
1266
|
tooltip: {
|
|
1338
|
-
show: !0
|
|
1339
|
-
showDiagnostic: !1,
|
|
1340
|
-
showPoint: !0
|
|
1267
|
+
show: !0
|
|
1341
1268
|
}
|
|
1342
1269
|
});
|
|
1343
|
-
let
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1270
|
+
let Ct = V;
|
|
1271
|
+
const ft = Object.freeze({
|
|
1272
|
+
colors: Q,
|
|
1273
|
+
zone: { data: Yt, alpha: 0.75 },
|
|
1346
1274
|
backgroundColor: "#050d1a",
|
|
1347
1275
|
triFill: "rgba(8,20,50,0)",
|
|
1348
1276
|
grid: {
|
|
@@ -1414,47 +1342,47 @@ const at = Object.freeze({
|
|
|
1414
1342
|
}
|
|
1415
1343
|
}
|
|
1416
1344
|
});
|
|
1417
|
-
class
|
|
1345
|
+
class L {
|
|
1418
1346
|
/** 计算等边三角形在给定视口下的顶点 */
|
|
1419
1347
|
static computeTri(t) {
|
|
1420
|
-
const { availW: e, availH: o, cx:
|
|
1348
|
+
const { availW: e, availH: o, cx: i, cy: s } = t, n = Math.max(0, Math.min(e, o / Math.sin(Math.PI / 3))), r = n * Math.sin(Math.PI / 3), h = i - n / 2, a = s - r / 2;
|
|
1421
1349
|
return {
|
|
1422
|
-
top: { x:
|
|
1423
|
-
left: { x: h, y: a +
|
|
1424
|
-
right: { x: h + n, y: a +
|
|
1350
|
+
top: { x: i, y: a },
|
|
1351
|
+
left: { x: h, y: a + r },
|
|
1352
|
+
right: { x: h + n, y: a + r }
|
|
1425
1353
|
};
|
|
1426
1354
|
}
|
|
1427
1355
|
/** 三元坐标(a,b,c)转笛卡尔坐标(x,y) */
|
|
1428
|
-
static t2c(t, e, o,
|
|
1429
|
-
const { top:
|
|
1356
|
+
static t2c(t, e, o, i) {
|
|
1357
|
+
const { top: s, left: n, right: r } = i;
|
|
1430
1358
|
return {
|
|
1431
|
-
x: t *
|
|
1432
|
-
y: t *
|
|
1359
|
+
x: t * s.x + e * n.x + o * r.x,
|
|
1360
|
+
y: t * s.y + e * n.y + o * r.y
|
|
1433
1361
|
};
|
|
1434
1362
|
}
|
|
1435
1363
|
/** 笛卡尔坐标(x,y)转三元坐标(a,b,c) */
|
|
1436
1364
|
static c2t(t, e, o) {
|
|
1437
|
-
const { top:
|
|
1365
|
+
const { top: i, left: s, right: n } = o, r = (s.y - n.y) * (i.x - n.x) + (n.x - s.x) * (i.y - n.y), h = ((s.y - n.y) * (t - n.x) + (n.x - s.x) * (e - n.y)) / r, a = ((n.y - i.y) * (t - n.x) + (i.x - n.x) * (e - n.y)) / r;
|
|
1438
1366
|
return { a: h, b: a, c: 1 - h - a };
|
|
1439
1367
|
}
|
|
1440
1368
|
/** 计算多边形像素面积 */
|
|
1441
1369
|
static polyArea(t) {
|
|
1442
1370
|
let e = 0;
|
|
1443
|
-
for (let o = 0,
|
|
1444
|
-
const
|
|
1445
|
-
e += t[o].x * t[
|
|
1371
|
+
for (let o = 0, i = t.length; o < i; o++) {
|
|
1372
|
+
const s = (o + 1) % i;
|
|
1373
|
+
e += t[o].x * t[s].y - t[s].x * t[o].y;
|
|
1446
1374
|
}
|
|
1447
1375
|
return Math.abs(e) / 2;
|
|
1448
1376
|
}
|
|
1449
1377
|
/** 计算多边形质心 */
|
|
1450
1378
|
static polyCentroid(t) {
|
|
1451
1379
|
const e = t.length;
|
|
1452
|
-
let o = 0,
|
|
1380
|
+
let o = 0, i = 0, s = 0;
|
|
1453
1381
|
for (let n = 0; n < e; n++) {
|
|
1454
|
-
const
|
|
1455
|
-
o += h,
|
|
1382
|
+
const r = (n + 1) % e, h = t[n].x * t[r].y - t[r].x * t[n].y;
|
|
1383
|
+
o += h, i += (t[n].x + t[r].x) * h, s += (t[n].y + t[r].y) * h;
|
|
1456
1384
|
}
|
|
1457
|
-
return o /= 2, { x:
|
|
1385
|
+
return o /= 2, { x: i / (6 * o), y: s / (6 * o) };
|
|
1458
1386
|
}
|
|
1459
1387
|
/**
|
|
1460
1388
|
* 解析并归一化数据点 (支持对象数组或原始数值数组)
|
|
@@ -1463,166 +1391,182 @@ class D {
|
|
|
1463
1391
|
static resolveData(t, e) {
|
|
1464
1392
|
let o = null;
|
|
1465
1393
|
if (Array.isArray(t) ? t.length >= 3 && (typeof t[0] == "object" && t[0] !== null ? e ? o = e.map((h) => {
|
|
1466
|
-
const a = t.find((
|
|
1394
|
+
const a = t.find((l) => l && l.name === h);
|
|
1467
1395
|
return a ? a.value : 0;
|
|
1468
1396
|
}) : o = [t[0].value, t[1].value, t[2].value] : o = [t[0], t[1], t[2]]) : t && t.value && Array.isArray(t.value) && t.value.length >= 3 && (o = [t.value[0], t.value[1], t.value[2]]), !o || o.some((h) => typeof h != "number" || isNaN(h))) return null;
|
|
1469
|
-
const [
|
|
1470
|
-
return
|
|
1397
|
+
const [i, s, n] = o.map((h) => Math.max(0, h || 0)), r = i + s + n;
|
|
1398
|
+
return r <= 1e-9 ? [0.3333, 0.3333, 0.3333] : [i / r, s / r, n / r];
|
|
1471
1399
|
}
|
|
1472
1400
|
}
|
|
1473
|
-
class
|
|
1401
|
+
class Nt {
|
|
1474
1402
|
constructor(t) {
|
|
1475
1403
|
this.ctx = t;
|
|
1476
1404
|
}
|
|
1477
1405
|
/** 全量渲染入口 */
|
|
1478
1406
|
render(t) {
|
|
1479
|
-
const e = this.ctx, { W: o, H:
|
|
1480
|
-
e.setTransform(1, 0, 0, 1, 0, 0), e.clearRect(0, 0, o *
|
|
1407
|
+
const e = this.ctx, { W: o, H: i, dpr: s, scale: n, tx: r, ty: h, option: a, tri: l, zones: c, hoveredPoint: d } = t;
|
|
1408
|
+
e.setTransform(1, 0, 0, 1, 0, 0), e.clearRect(0, 0, o * s, i * s), e.fillStyle = a.backgroundColor, e.fillRect(0, 0, o * s, i * s), e.setTransform(n * s, 0, 0, n * s, r * s, h * s), this.drawTriFill(l), this.drawZones(c, l, a), this.drawGrid(a, l), this.drawBorder(a, l), this.drawSideLabels(a, l), this.drawSeries(a, l, d), e.setTransform(1, 0, 0, 1, 0, 0);
|
|
1481
1409
|
}
|
|
1482
1410
|
drawTriFill(t) {
|
|
1483
|
-
const e = this.ctx, { top: o, left:
|
|
1484
|
-
e.beginPath(), e.moveTo(o.x, o.y), e.lineTo(
|
|
1411
|
+
const e = this.ctx, { top: o, left: i, right: s } = t;
|
|
1412
|
+
e.beginPath(), e.moveTo(o.x, o.y), e.lineTo(i.x, i.y), e.lineTo(s.x, s.y), e.closePath(), e.fillStyle = ft.triFill, e.fill();
|
|
1485
1413
|
}
|
|
1486
1414
|
drawZones(t, e, o) {
|
|
1487
|
-
var
|
|
1488
|
-
const
|
|
1489
|
-
t.forEach((
|
|
1490
|
-
!
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1415
|
+
var d, p, b, u, S, g;
|
|
1416
|
+
const i = this.ctx, s = this.ctx.getTransform().a / (window.devicePixelRatio || 1), n = (d = o.zone) == null ? void 0 : d.alpha, r = ((p = o.zone) == null ? void 0 : p.colors) || o.colors || Q;
|
|
1417
|
+
t.forEach((f, y) => {
|
|
1418
|
+
if (!f.coordinates || !f.coordinates.length) return;
|
|
1419
|
+
i.beginPath(), f.coordinates.forEach(([v, x, A], T) => {
|
|
1420
|
+
const _ = L.t2c(v, x, A, e);
|
|
1421
|
+
T === 0 ? i.moveTo(_.x, _.y) : i.lineTo(_.x, _.y);
|
|
1422
|
+
}), i.closePath();
|
|
1423
|
+
let m = f.color || r[y % r.length];
|
|
1424
|
+
n !== void 0 && m !== "transparent" && (m = zt(m, n)), i.fillStyle = m, i.fill();
|
|
1494
1425
|
});
|
|
1495
|
-
const
|
|
1496
|
-
if (t.forEach((
|
|
1497
|
-
const
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
const
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1426
|
+
const h = ((b = o.zone) == null ? void 0 : b.borderStyle) || {};
|
|
1427
|
+
if (t.forEach((f, y) => {
|
|
1428
|
+
const m = h;
|
|
1429
|
+
if (m.show === !1 || !f.coordinates || !f.coordinates.length) return;
|
|
1430
|
+
i.beginPath(), f.coordinates.forEach(([x, A, T], _) => {
|
|
1431
|
+
const M = L.t2c(x, A, T, e);
|
|
1432
|
+
_ === 0 ? i.moveTo(M.x, M.y) : i.lineTo(M.x, M.y);
|
|
1433
|
+
}), i.closePath();
|
|
1434
|
+
let v = m.color || f.color || r[y % r.length];
|
|
1435
|
+
m.alpha !== void 0 && v !== "transparent" && (v = zt(v, m.alpha)), i.strokeStyle = v, i.lineWidth = (m.width ?? 1) * s, m.type === "dashed" ? i.setLineDash([4, 4]) : m.type === "dotted" ? i.setLineDash([2, 4]) : i.setLineDash([]), i.stroke();
|
|
1436
|
+
}), i.setLineDash([]), !(o.showZoneLabel !== !1)) return;
|
|
1437
|
+
const l = ((S = (u = o.grid) == null ? void 0 : u.labelStyle) == null ? void 0 : S.fontFamily) || "Microsoft YaHei UI, monospace", c = ((g = o.zone) == null ? void 0 : g.labelStyle) || {};
|
|
1438
|
+
t.forEach((f) => {
|
|
1439
|
+
const y = c;
|
|
1440
|
+
if (y.show === !1 || !f.name) return;
|
|
1441
|
+
let m;
|
|
1442
|
+
const v = f.labelAt;
|
|
1443
|
+
if (v && Array.isArray(v) && v.length >= 3)
|
|
1444
|
+
m = L.t2c(v[0], v[1], v[2], e);
|
|
1445
|
+
else if (f.coordinates && f.coordinates.length > 0) {
|
|
1446
|
+
const E = f.coordinates.map(([z, D, j]) => L.t2c(z, D, j, e));
|
|
1447
|
+
m = {
|
|
1448
|
+
x: E.reduce((z, D) => z + D.x, 0) / E.length,
|
|
1449
|
+
y: E.reduce((z, D) => z + D.y, 0) / E.length
|
|
1450
|
+
};
|
|
1451
|
+
} else
|
|
1452
|
+
return;
|
|
1453
|
+
const x = Math.round((y.fontSize || 11) * s), A = y.fontStyle || "bold";
|
|
1454
|
+
i.font = `${A} ${x}px ${l}`, i.textAlign = "center", i.textBaseline = "middle";
|
|
1455
|
+
const T = typeof y.formatter == "function" ? y.formatter(f) : f.name, _ = i.measureText(T).width, M = x;
|
|
1456
|
+
let k = m.x, P = m.y;
|
|
1457
|
+
if (y.backgroundColor && y.backgroundColor !== "transparent") {
|
|
1458
|
+
let E = 4, z = 4;
|
|
1459
|
+
Array.isArray(y.padding) ? (z = y.padding[0], E = y.padding[1] !== void 0 ? y.padding[1] : z) : typeof y.padding == "number" && (E = z = y.padding), E *= s, z *= s;
|
|
1460
|
+
const D = (y.borderRadius || 3) * s, j = _ + E * 2, H = M + z * 2, K = k - j / 2, O = P - H / 2;
|
|
1461
|
+
i.fillStyle = y.backgroundColor, i.beginPath(), i.roundRect ? i.roundRect(K, O, j, H, D) : i.rect(K, O, j, H), i.fill();
|
|
1518
1462
|
}
|
|
1519
|
-
|
|
1520
|
-
}),
|
|
1463
|
+
y.textShadow && y.textShadow !== "none" ? (i.shadowColor = y.textShadow, i.shadowBlur = 4) : (i.shadowColor = "transparent", i.shadowBlur = 0), i.fillStyle = y.color || "#fff", i.fillText(T, k, P), i.shadowBlur = 0, i.shadowColor = "transparent";
|
|
1464
|
+
}), i.textBaseline = "alphabetic";
|
|
1521
1465
|
}
|
|
1522
|
-
drawBadge(t, e, o,
|
|
1523
|
-
const n = this.ctx, { badgePadding:
|
|
1524
|
-
n.beginPath(), n.roundRect ? n.roundRect(c, d,
|
|
1466
|
+
drawBadge(t, e, o, i, s) {
|
|
1467
|
+
const n = this.ctx, { badgePadding: r, badgeHeight: h, badgeRadius: a } = ft.ZONE_VIS, l = o + r * 2, c = t - l / 2, d = e - h / 2;
|
|
1468
|
+
n.beginPath(), n.roundRect ? n.roundRect(c, d, l, h, a) : n.rect(c, d, l, h), n.fillStyle = s, n.fill();
|
|
1525
1469
|
}
|
|
1526
|
-
drawArrow(t, e, o,
|
|
1527
|
-
const n = this.ctx,
|
|
1470
|
+
drawArrow(t, e, o, i, s) {
|
|
1471
|
+
const n = this.ctx, r = o - t, h = i - e, a = Math.hypot(r, h);
|
|
1528
1472
|
if (a < 1) return;
|
|
1529
|
-
const
|
|
1530
|
-
n.beginPath(), n.moveTo(o,
|
|
1473
|
+
const l = r / a, c = h / a, d = 7;
|
|
1474
|
+
n.beginPath(), n.moveTo(o, i), n.lineTo(o - l * d + c * d * 0.5, i - c * d - l * d * 0.5), n.lineTo(o - l * d - c * d * 0.5, i - c * d + l * d * 0.5), n.closePath(), n.fillStyle = s, n.fill();
|
|
1531
1475
|
}
|
|
1532
1476
|
drawGrid(t, e) {
|
|
1533
1477
|
if (!t.grid || !t.grid.show) return;
|
|
1534
|
-
const o = this.ctx,
|
|
1535
|
-
let
|
|
1536
|
-
const
|
|
1537
|
-
|
|
1538
|
-
const
|
|
1539
|
-
return (
|
|
1540
|
-
}, { top: c, left: d, right:
|
|
1541
|
-
bottom:
|
|
1542
|
-
left:
|
|
1543
|
-
right:
|
|
1478
|
+
const o = this.ctx, i = t.grid, s = i.steps || 10, n = i.majorEvery || 2, r = i.lineStyle || { color: "rgba(255,255,255,0.1)", width: 1, type: "solid" }, h = i.majorLineStyle || { color: "rgba(255,255,255,0.2)", width: 1, type: "solid" }, a = this.ctx.getTransform().a / (window.devicePixelRatio || 1), l = (u, S, g) => {
|
|
1479
|
+
let f = S.x - u.x, y = S.y - u.y;
|
|
1480
|
+
const m = Math.hypot(f, y);
|
|
1481
|
+
f /= m, y /= m;
|
|
1482
|
+
const v = { x: -y, y: f }, x = { x: y, y: -f };
|
|
1483
|
+
return (g.x - u.x) * v.x + (g.y - u.y) * v.y > 0 ? v : x;
|
|
1484
|
+
}, { top: c, left: d, right: p } = e, b = {
|
|
1485
|
+
bottom: l(d, p, c),
|
|
1486
|
+
left: l(d, c, p),
|
|
1487
|
+
right: l(p, c, d)
|
|
1544
1488
|
};
|
|
1545
|
-
for (let
|
|
1546
|
-
const
|
|
1547
|
-
o.strokeStyle =
|
|
1548
|
-
const
|
|
1549
|
-
o.beginPath(), o.moveTo(
|
|
1489
|
+
for (let u = 1; u < s; u++) {
|
|
1490
|
+
const S = u / s, g = u % n === 0, f = g ? h : r;
|
|
1491
|
+
o.strokeStyle = f.color || "transparent", o.lineWidth = (f.width ?? 1) * a, f.type === "dashed" ? o.setLineDash([4, 4]) : f.type === "dotted" ? o.setLineDash([2, 4]) : o.setLineDash([]);
|
|
1492
|
+
const y = (m, v) => {
|
|
1493
|
+
o.beginPath(), o.moveTo(m.x, m.y), o.lineTo(v.x, v.y), o.stroke();
|
|
1550
1494
|
};
|
|
1551
|
-
|
|
1495
|
+
y(L.t2c(S, 1 - S, 0, e), L.t2c(S, 0, 1 - S, e)), y(L.t2c(1 - S, S, 0, e), L.t2c(0, S, 1 - S, e)), y(L.t2c(1 - S, 0, S, e), L.t2c(0, 1 - S, S, e)), this.drawSideTick(u, s, S, t, e, g, b);
|
|
1552
1496
|
}
|
|
1553
1497
|
}
|
|
1554
|
-
drawSideTick(t, e, o,
|
|
1555
|
-
const a = (
|
|
1498
|
+
drawSideTick(t, e, o, i, s, n, r) {
|
|
1499
|
+
const a = (i.side || {}).tickStyle || {};
|
|
1556
1500
|
if (a.show === !1) return;
|
|
1557
|
-
const
|
|
1558
|
-
|
|
1559
|
-
const d = a.length || 6,
|
|
1560
|
-
|
|
1561
|
-
},
|
|
1562
|
-
|
|
1563
|
-
const
|
|
1564
|
-
|
|
1565
|
-
const
|
|
1566
|
-
|
|
1501
|
+
const l = this.ctx, c = Math.round(t * 100 / e);
|
|
1502
|
+
l.textAlign = "center", l.textBaseline = "middle";
|
|
1503
|
+
const d = a.length || 6, p = a.lineColor || "rgba(0,0,0,0.2)", b = a.color || "rgba(200,220,255)", u = a.offset !== void 0 ? a.offset : 15, S = a.fontFamily || "Microsoft YaHei UI, sans-serif", g = a.fontSize || 14, y = `${a.fontWeight || "normal"} ${g}px ${S}`, m = (T, _, M) => {
|
|
1504
|
+
l.beginPath(), l.moveTo(T.x, T.y), l.lineTo(T.x + _ * d, T.y + M * d), l.strokeStyle = p, l.lineWidth = 1.5, l.stroke();
|
|
1505
|
+
}, v = L.t2c(o, 1 - o, 0, s);
|
|
1506
|
+
m(v, r.left.x, r.left.y), n && (l.fillStyle = b, l.font = y, l.save(), l.translate(v.x - u, v.y - 8), l.rotate(-Math.PI / 3), l.fillText(c + "", 0, 0), l.restore());
|
|
1507
|
+
const x = L.t2c(1 - o, 0, o, s);
|
|
1508
|
+
m(x, r.right.x, r.right.y), n && (l.fillStyle = b, l.font = y, l.save(), l.translate(x.x + u, x.y - 8), l.rotate(Math.PI / 3), l.fillText(c + "", 0, 0), l.restore());
|
|
1509
|
+
const A = L.t2c(0, o, 1 - o, s);
|
|
1510
|
+
m(A, r.bottom.x, r.bottom.y), n && (l.fillStyle = b, l.font = y, l.fillText(c + "", A.x, A.y + u));
|
|
1567
1511
|
}
|
|
1568
1512
|
drawBorder(t, e) {
|
|
1569
|
-
const o = this.ctx, { top:
|
|
1513
|
+
const o = this.ctx, { top: i, left: s, right: n } = e, h = (t.side || {}).lineStyle || { color: "rgba(180,210,255,0.1)", width: 1.5, type: "solid" };
|
|
1570
1514
|
[
|
|
1571
|
-
{ f:
|
|
1572
|
-
{ f:
|
|
1573
|
-
{ f:
|
|
1574
|
-
].forEach(({ f:
|
|
1575
|
-
o.beginPath(), o.moveTo(
|
|
1515
|
+
{ f: i, t: s },
|
|
1516
|
+
{ f: i, t: n },
|
|
1517
|
+
{ f: s, t: n }
|
|
1518
|
+
].forEach(({ f: l, t: c }) => {
|
|
1519
|
+
o.beginPath(), o.moveTo(l.x, l.y), o.lineTo(c.x, c.y), o.strokeStyle = h.color || "transparent", o.lineWidth = h.width || 1, h.type === "dashed" ? o.setLineDash([4, 4]) : h.type === "dotted" ? o.setLineDash([2, 4]) : o.setLineDash([]), o.stroke();
|
|
1576
1520
|
}), o.setLineDash([]);
|
|
1577
1521
|
}
|
|
1578
1522
|
drawSideLabels(t, e) {
|
|
1579
|
-
var
|
|
1580
|
-
if (((
|
|
1581
|
-
const o = this.ctx, { top:
|
|
1582
|
-
o.textBaseline = "middle", o.textAlign = "center", o.fillStyle =
|
|
1583
|
-
const
|
|
1584
|
-
o.save(), o.translate(
|
|
1585
|
-
const
|
|
1586
|
-
o.save(), o.translate(
|
|
1523
|
+
var A;
|
|
1524
|
+
if (((A = t.side) == null ? void 0 : A.show) === !1) return;
|
|
1525
|
+
const o = this.ctx, { top: i, left: s, right: n } = e, r = t.side || {}, h = r.data || ["A", "B", "C"], a = r.labelStyle || {}, l = a.fontFamily || "Microsoft YaHei UI, sans-serif", c = a.fontSize || 14, d = a.fontWeight || "bold", p = a.color || "#00e5ff", b = a.offset !== void 0 ? a.offset : 40;
|
|
1526
|
+
o.textBaseline = "middle", o.textAlign = "center", o.fillStyle = p, o.font = `${d} ${c}px ${l}`;
|
|
1527
|
+
const u = { x: (i.x + s.x) / 2, y: (i.y + s.y) / 2 }, S = s.x - i.x, g = s.y - i.y, f = Math.hypot(S, g);
|
|
1528
|
+
o.save(), o.translate(u.x + -g / f * b, u.y + S / f * b), o.rotate(Math.atan2(g, S) + Math.PI), o.fillText((h[1] || "B") + " (%)", 0, 0), o.restore();
|
|
1529
|
+
const y = { x: (i.x + n.x) / 2, y: (i.y + n.y) / 2 }, m = n.x - i.x, v = n.y - i.y, x = Math.hypot(m, v);
|
|
1530
|
+
o.save(), o.translate(y.x + v / x * b, y.y + -m / x * b), o.rotate(Math.atan2(v, m)), o.fillText((h[2] || "C") + " (%)", 0, 0), o.restore(), o.save(), o.translate((s.x + n.x) / 2, (s.y + n.y) / 2 + b), o.fillText((h[0] || "A") + " (%)", 0, 0), o.restore();
|
|
1587
1531
|
}
|
|
1588
1532
|
drawSeries(t, e, o) {
|
|
1589
1533
|
var h;
|
|
1590
|
-
const
|
|
1534
|
+
const i = this.ctx, s = this.ctx.getTransform().a / (window.devicePixelRatio || 1), n = "Microsoft YaHei UI, sans-serif", r = (h = t.side) == null ? void 0 : h.data;
|
|
1591
1535
|
(t.series || []).forEach((a) => {
|
|
1592
|
-
const
|
|
1593
|
-
if (!
|
|
1594
|
-
const c = a.name, d =
|
|
1536
|
+
const l = a.data;
|
|
1537
|
+
if (!l || l.length === 0) return;
|
|
1538
|
+
const c = a.name, d = L.resolveData(l, r);
|
|
1595
1539
|
if (!d) return;
|
|
1596
|
-
const
|
|
1597
|
-
let
|
|
1598
|
-
|
|
1599
|
-
const
|
|
1600
|
-
if (
|
|
1601
|
-
|
|
1602
|
-
let
|
|
1603
|
-
if (Array.isArray(
|
|
1604
|
-
|
|
1540
|
+
const p = L.t2c(d[0], d[1], d[2], e), b = p.x, u = p.y, S = o && o.series === a, g = a.shape || "circle", f = a.color || "#409eff";
|
|
1541
|
+
let y = a.size !== void 0 ? a.size : 5;
|
|
1542
|
+
S && (y *= 1.5);
|
|
1543
|
+
const m = a.itemStyle || {}, v = m.borderColor || "#fff", x = m.borderWidth !== void 0 ? m.borderWidth : 1, A = m.opacity !== void 0 ? m.opacity : 1, T = a.textStyle || {}, _ = T.show !== void 0 ? T.show : !0, M = T.color || f, k = T.fontSize !== void 0 ? T.fontSize : 12, P = T.fontWeight || "normal", E = T.position || "top", z = T.offset || [0, 0], D = a.glowStyle || {}, j = D.show !== void 0 ? D.show : !1, H = D.colors, K = D.blur !== void 0 ? D.blur : 15, O = D.startColor || f, ot = D.endColor || "transparent", R = D.count !== void 0 ? D.count : 3, it = D.glowDistance !== void 0 ? D.glowDistance : 2;
|
|
1544
|
+
if (i.save(), i.globalAlpha = A, j) {
|
|
1545
|
+
i.shadowColor = H ? H[0] : O, i.shadowBlur = K;
|
|
1546
|
+
let W = [], N = R;
|
|
1547
|
+
if (Array.isArray(H) && H.length > 0)
|
|
1548
|
+
W = H, N = W.length;
|
|
1605
1549
|
else
|
|
1606
|
-
for (let
|
|
1607
|
-
const
|
|
1608
|
-
|
|
1550
|
+
for (let $ = 0; $ < N; $++) {
|
|
1551
|
+
const G = N > 1 ? $ / (N - 1) : 0;
|
|
1552
|
+
W.push(Ot(O, ot, G));
|
|
1609
1553
|
}
|
|
1610
|
-
for (let
|
|
1611
|
-
const
|
|
1612
|
-
|
|
1554
|
+
for (let $ = N - 1; $ >= 0; $--) {
|
|
1555
|
+
const G = W[$];
|
|
1556
|
+
i.save(), i.fillStyle = G, i.beginPath(), lt(i, b, u, g, y, s, ($ + 1) * it), i.fill(), i.restore();
|
|
1613
1557
|
}
|
|
1614
1558
|
}
|
|
1615
|
-
if (
|
|
1616
|
-
|
|
1617
|
-
let
|
|
1618
|
-
|
|
1559
|
+
if (i.beginPath(), lt(i, b, u, g, y, s, 0), g === "ring" ? (i.strokeStyle = f, i.lineWidth = x * s, i.stroke()) : (i.fillStyle = f, i.fill(), x > 0 && (i.strokeStyle = v, i.lineWidth = x * s, i.stroke())), i.restore(), _ && c) {
|
|
1560
|
+
i.save(), i.globalAlpha = A, i.font = `${P} ${Math.round(k * s)}px ${n}`, i.fillStyle = M;
|
|
1561
|
+
let W = "center", N = "middle", $ = b + z[0] * s, G = u + z[1] * s, q = 6 * s;
|
|
1562
|
+
g === "circle" || g === "ring" || g === "star" || g === "triangle" ? q += y * s : g === "square" && (q += y * s / 2), E === "top" ? (W = "center", N = "bottom", G -= q) : E === "bottom" ? (W = "center", N = "top", G += q) : E === "left" ? (W = "right", N = "middle", $ -= q) : E === "right" ? (W = "left", N = "middle", $ += q) : E === "center" && (W = "center", N = "middle"), i.textAlign = W, i.textBaseline = N, i.fillText(c, $, G), i.restore();
|
|
1619
1563
|
}
|
|
1620
1564
|
});
|
|
1621
1565
|
}
|
|
1622
1566
|
}
|
|
1623
|
-
class
|
|
1567
|
+
class Jt {
|
|
1624
1568
|
constructor(t, e = {}) {
|
|
1625
|
-
this.initDOM(t), this.renderer = new
|
|
1569
|
+
this.initDOM(t), this.renderer = new Nt(this.ctx), this.state = {
|
|
1626
1570
|
W: 0,
|
|
1627
1571
|
H: 0,
|
|
1628
1572
|
dpr: 1,
|
|
@@ -1633,7 +1577,7 @@ class Gt {
|
|
|
1633
1577
|
tri: {},
|
|
1634
1578
|
zones: [],
|
|
1635
1579
|
hoveredPoint: null
|
|
1636
|
-
}, this._zoom = new
|
|
1580
|
+
}, this._zoom = new St(e.zoom), this._bus = new pt(), this._initTooltip(), this.bindEvents(), this.ro = new ResizeObserver(() => this.fitCanvas()), this.ro.observe(this.container), this.fitCanvas(), Object.keys(e).length && this.setOption(e);
|
|
1637
1581
|
}
|
|
1638
1582
|
initDOM(t) {
|
|
1639
1583
|
let e = typeof t == "string" ? document.getElementById(t) : t;
|
|
@@ -1642,8 +1586,8 @@ class Gt {
|
|
|
1642
1586
|
}
|
|
1643
1587
|
_initTooltip() {
|
|
1644
1588
|
var e;
|
|
1645
|
-
const t = this.state.option.tooltip ||
|
|
1646
|
-
this._tooltip = new
|
|
1589
|
+
const t = this.state.option.tooltip || ft.tooltip;
|
|
1590
|
+
this._tooltip = new vt(this.container, {
|
|
1647
1591
|
tooltipBg: t.backgroundColor || "rgba(5,13,26,0.95)",
|
|
1648
1592
|
tooltipTextColor: ((e = t.textStyle) == null ? void 0 : e.color) || "#c8d8e8",
|
|
1649
1593
|
tooltipPadding: t.padding || 10,
|
|
@@ -1652,33 +1596,44 @@ class Gt {
|
|
|
1652
1596
|
}), this._tooltip.el.style.whiteSpace = "nowrap", this._tooltip.el.style.lineHeight = "1.6";
|
|
1653
1597
|
}
|
|
1654
1598
|
setOption(t) {
|
|
1655
|
-
!this.state.option || !Object.keys(this.state.option).length ? this.state.option =
|
|
1599
|
+
!this.state.option || !Object.keys(this.state.option).length ? this.state.option = X(X({}, ft), t) : X(this.state.option, t), this._normalizeOptions(), this.computeGeometry(), this.buildZonePaths(), this.render();
|
|
1600
|
+
}
|
|
1601
|
+
setSeries(t) {
|
|
1602
|
+
return this.state.option.series = Array.isArray(t) ? t : [t], this.render(), this;
|
|
1603
|
+
}
|
|
1604
|
+
on(t, e) {
|
|
1605
|
+
return this._bus.on(t, e), this;
|
|
1606
|
+
}
|
|
1607
|
+
off(t, e) {
|
|
1608
|
+
return this._bus.off(t, e), this;
|
|
1656
1609
|
}
|
|
1657
1610
|
_normalizeOptions() {
|
|
1658
1611
|
const t = this.state.option;
|
|
1659
|
-
t.
|
|
1612
|
+
t.side || (t.side = {}), (!t.side.data || t.side.data.length < 3) && (t.side.data = ["A", "B", "C"]);
|
|
1660
1613
|
}
|
|
1661
1614
|
computeGeometry() {
|
|
1662
1615
|
const t = window.devicePixelRatio || 1;
|
|
1663
1616
|
this.state.W = this.canvas.width / t, this.state.H = this.canvas.height / t, this.state.dpr = t;
|
|
1664
|
-
const e = this.state.option.padding ?? 45, o = this.state.option.grid || {},
|
|
1665
|
-
this.state.tri =
|
|
1617
|
+
const e = this.state.option.padding ?? 45, o = this.state.option.grid || {}, i = gt(this.state.W, this.state.H, o, e);
|
|
1618
|
+
this.state.tri = L.computeTri(i);
|
|
1666
1619
|
}
|
|
1667
1620
|
buildZonePaths() {
|
|
1668
|
-
var
|
|
1669
|
-
const { option: t, tri: e } = this.state, o = ((
|
|
1670
|
-
this.state.zones = o.map((
|
|
1671
|
-
const n = { ...
|
|
1672
|
-
if (
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
n.
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1621
|
+
var i;
|
|
1622
|
+
const { option: t, tri: e } = this.state, o = ((i = t.zone) == null ? void 0 : i.data) || [];
|
|
1623
|
+
this.state.zones = o.map((s) => {
|
|
1624
|
+
const n = { ...s }, r = new Path2D(), h = s.coordinates;
|
|
1625
|
+
if (h) {
|
|
1626
|
+
if (h.forEach(([a, l, c], d) => {
|
|
1627
|
+
const p = L.t2c(a, l, c, e);
|
|
1628
|
+
d === 0 ? r.moveTo(p.x, p.y) : r.lineTo(p.x, p.y);
|
|
1629
|
+
}), r.closePath(), n.path = r, s.labelAt)
|
|
1630
|
+
n.labelPos = { a: s.labelAt[0], b: s.labelAt[1], c: s.labelAt[2] };
|
|
1631
|
+
else {
|
|
1632
|
+
const l = (s.coordinates || []).map((p) => L.t2c(p[0], p[1], p[2], e)), c = L.polyCentroid(l), d = L.c2t(c.x, c.y, e);
|
|
1633
|
+
n.labelPos = { a: d.a, b: d.b, c: d.c };
|
|
1634
|
+
}
|
|
1635
|
+
return n;
|
|
1680
1636
|
}
|
|
1681
|
-
return n;
|
|
1682
1637
|
});
|
|
1683
1638
|
}
|
|
1684
1639
|
fitCanvas() {
|
|
@@ -1686,141 +1641,165 @@ class Gt {
|
|
|
1686
1641
|
this.canvas.width = Math.round(e * t), this.canvas.height = Math.round(o * t), this.canvas.style.width = e + "px", this.canvas.style.height = o + "px", this.state.scale = 1, this.state.tx = 0, this.state.ty = 0, this._zoom && this._zoom.reset(), Object.keys(this.state.option).length && (this.computeGeometry(), this.buildZonePaths(), this.render());
|
|
1687
1642
|
}
|
|
1688
1643
|
render() {
|
|
1644
|
+
var o;
|
|
1645
|
+
if (!this.state.option) return;
|
|
1689
1646
|
this.state.scale = this._zoom.zoom, this.state.tx = this._zoom.panX, this.state.ty = this._zoom.panY, this.renderer.render(this.state);
|
|
1647
|
+
const t = [], e = (o = this.state.option.side) == null ? void 0 : o.data;
|
|
1648
|
+
(this.state.option.series || []).forEach((i) => {
|
|
1649
|
+
const s = i.data;
|
|
1650
|
+
if (!s || s.length === 0) return;
|
|
1651
|
+
const n = L.resolveData(s, e);
|
|
1652
|
+
if (!n) return;
|
|
1653
|
+
const r = this.getZoneAt(n[0], n[1], n[2]);
|
|
1654
|
+
t.push({
|
|
1655
|
+
series: i,
|
|
1656
|
+
zone: r,
|
|
1657
|
+
ratio: n
|
|
1658
|
+
});
|
|
1659
|
+
}), t.length > 0 && this._bus.emit("diagnose", t);
|
|
1690
1660
|
}
|
|
1691
1661
|
bindEvents() {
|
|
1692
1662
|
const t = this.canvas;
|
|
1693
1663
|
this._onWheel = (e) => {
|
|
1694
1664
|
e.preventDefault();
|
|
1695
|
-
const o = t.getBoundingClientRect(),
|
|
1696
|
-
this._zoom.onWheel(e.deltaY,
|
|
1665
|
+
const o = t.getBoundingClientRect(), i = (e.clientX - o.left) * (this.state.W / o.width), s = (e.clientY - o.top) * (this.state.H / o.height);
|
|
1666
|
+
this._zoom.onWheel(e.deltaY, i, s), this._bus.emit("zoom", this._zoom.state), this.render();
|
|
1697
1667
|
}, this._onDown = (e) => {
|
|
1698
1668
|
if (e.button !== 0) return;
|
|
1699
|
-
const o = t.getBoundingClientRect(),
|
|
1700
|
-
this._zoom.startDrag(e.clientX *
|
|
1669
|
+
const o = t.getBoundingClientRect(), i = this.state.W / o.width, s = this.state.H / o.height;
|
|
1670
|
+
this._zoom.startDrag(e.clientX * i, e.clientY * s), t.style.cursor = "grabbing";
|
|
1701
1671
|
}, this._onMove = (e) => {
|
|
1702
|
-
const o = t.getBoundingClientRect(),
|
|
1703
|
-
if (this._zoom.moveDrag(e.clientX *
|
|
1672
|
+
const o = t.getBoundingClientRect(), i = this.state.W / o.width, s = this.state.H / o.height;
|
|
1673
|
+
if (this._zoom.moveDrag(e.clientX * i, e.clientY * s, 1)) {
|
|
1704
1674
|
this.render();
|
|
1705
1675
|
return;
|
|
1706
1676
|
}
|
|
1707
1677
|
this.handleMouseMove(e);
|
|
1708
1678
|
}, this._onUp = () => {
|
|
1709
|
-
this._zoom.endDrag() && (t.style.cursor = this.state.hoveredPoint ? "pointer" : "default",
|
|
1679
|
+
this._zoom.endDrag() && (t.style.cursor = this.state.hoveredPoint ? "pointer" : "default", this._bus.emit("zoom", this._zoom.state));
|
|
1710
1680
|
}, this._onLeave = () => {
|
|
1711
|
-
this.hideTooltip(), this.state.hoveredPoint = null,
|
|
1681
|
+
this.hideTooltip(), this.state.hoveredPoint = null, this._bus.emit("hover", null), this.render();
|
|
1712
1682
|
}, this._onDbl = () => {
|
|
1713
|
-
this.
|
|
1683
|
+
this.zoomReset();
|
|
1714
1684
|
}, t.addEventListener("wheel", this._onWheel, { passive: !1 }), t.addEventListener("mousedown", this._onDown), t.addEventListener("mousemove", this._onMove), t.addEventListener("mouseleave", this._onLeave), t.addEventListener("dblclick", this._onDbl), t.addEventListener("click", this.handleClick.bind(this)), window.addEventListener("mouseup", this._onUp);
|
|
1715
1685
|
}
|
|
1716
1686
|
handleMouseMove(t) {
|
|
1717
|
-
var
|
|
1718
|
-
const e = this.canvas.getBoundingClientRect(), o = this.state.W / e.width,
|
|
1719
|
-
if (a < -1e-7 ||
|
|
1687
|
+
var u;
|
|
1688
|
+
const e = this.canvas.getBoundingClientRect(), o = this.state.W / e.width, i = this.state.H / e.height, s = (t.clientX - e.left) * o, n = (t.clientY - e.top) * i, r = (s - this._zoom.panX) / this._zoom.zoom, h = (n - this._zoom.panY) / this._zoom.zoom, { a, b: l, c } = L.c2t(r, h, this.state.tri);
|
|
1689
|
+
if (a < -1e-7 || l < -1e-7 || c < -1e-7) {
|
|
1720
1690
|
this.hideTooltip(), this.state.hoveredPoint !== null && (this.state.hoveredPoint = null, this.canvas.style.cursor = "default", this.render());
|
|
1721
1691
|
return;
|
|
1722
1692
|
}
|
|
1723
|
-
let d = null,
|
|
1724
|
-
const
|
|
1725
|
-
(this.state.option.series || []).forEach((
|
|
1726
|
-
const
|
|
1727
|
-
if (!
|
|
1728
|
-
const
|
|
1729
|
-
if (!
|
|
1730
|
-
const
|
|
1731
|
-
|
|
1732
|
-
}), d !== this.state.hoveredPoint && (this.state.hoveredPoint = d, this.canvas.style.cursor = d ? "pointer" : "default", this.render()), this.showTooltip(
|
|
1693
|
+
let d = null, p = 14;
|
|
1694
|
+
const b = (u = this.state.option.side) == null ? void 0 : u.data;
|
|
1695
|
+
(this.state.option.series || []).forEach((S) => {
|
|
1696
|
+
const g = S.data;
|
|
1697
|
+
if (!g) return;
|
|
1698
|
+
const f = L.resolveData(g, b);
|
|
1699
|
+
if (!f) return;
|
|
1700
|
+
const y = L.t2c(...f, this.state.tri), m = Math.hypot(y.x - r, y.y - h);
|
|
1701
|
+
m < p && (p = m, d = { series: S, raw: f });
|
|
1702
|
+
}), d !== this.state.hoveredPoint && (this.state.hoveredPoint = d, this.canvas.style.cursor = d ? "pointer" : "default", this.render()), this.showTooltip(r, h, a, l, c);
|
|
1733
1703
|
}
|
|
1734
1704
|
handleClick(t) {
|
|
1735
1705
|
if (this._zoom.isDragging) return;
|
|
1736
|
-
const e = this.canvas.getBoundingClientRect(), o = this.state.W / e.width,
|
|
1737
|
-
if (a < -1e-7 ||
|
|
1738
|
-
const d = this.getZoneAt(a,
|
|
1739
|
-
|
|
1740
|
-
new CustomEvent("triangle:click", { detail: { a, b:
|
|
1706
|
+
const e = this.canvas.getBoundingClientRect(), o = this.state.W / e.width, i = this.state.H / e.height, s = (t.clientX - e.left) * o, n = (t.clientY - e.top) * i, r = (s - this._zoom.panX) / this._zoom.zoom, h = (n - this._zoom.panY) / this._zoom.zoom, { a, b: l, c } = L.c2t(r, h, this.state.tri);
|
|
1707
|
+
if (a < -1e-7 || l < -1e-7 || c < -1e-7) return;
|
|
1708
|
+
const d = this.getZoneAt(a, l, c);
|
|
1709
|
+
this._bus.emit("click", { a, b: l, c, zone: d }), this.canvas.dispatchEvent(
|
|
1710
|
+
new CustomEvent("triangle:click", { detail: { a, b: l, c, zone: d }, bubbles: !0 })
|
|
1741
1711
|
);
|
|
1742
1712
|
}
|
|
1743
|
-
showTooltip(t, e, o,
|
|
1744
|
-
var
|
|
1713
|
+
showTooltip(t, e, o, i, s) {
|
|
1714
|
+
var g, f;
|
|
1745
1715
|
const n = this.state.option.tooltip || {};
|
|
1746
|
-
if (n.show === !1 || !this.state.hoveredPoint
|
|
1716
|
+
if (n.show === !1 || !this.state.hoveredPoint) {
|
|
1747
1717
|
this.hideTooltip();
|
|
1748
1718
|
return;
|
|
1749
1719
|
}
|
|
1750
|
-
const
|
|
1751
|
-
if (
|
|
1752
|
-
ratio: [o,
|
|
1753
|
-
zone:
|
|
1754
|
-
point: ((
|
|
1720
|
+
const r = this.getZoneAt(o, i, s), a = (this.state.option.side || {}).data || ["A", "B", "C"];
|
|
1721
|
+
if (this._bus.emit("hover", {
|
|
1722
|
+
ratio: [o, i, s],
|
|
1723
|
+
zone: r,
|
|
1724
|
+
point: ((g = this.state.hoveredPoint) == null ? void 0 : g.series) || null
|
|
1755
1725
|
}), n.formatter) {
|
|
1756
|
-
const
|
|
1726
|
+
const y = n.formatter({
|
|
1757
1727
|
a: o,
|
|
1758
|
-
b:
|
|
1759
|
-
c:
|
|
1728
|
+
b: i,
|
|
1729
|
+
c: s,
|
|
1760
1730
|
sNames: a,
|
|
1761
|
-
zone:
|
|
1762
|
-
point: (
|
|
1763
|
-
}),
|
|
1764
|
-
this._tooltip.show(
|
|
1731
|
+
zone: r,
|
|
1732
|
+
point: (f = this.state.hoveredPoint) == null ? void 0 : f.series
|
|
1733
|
+
}), m = t * this._zoom.zoom + this._zoom.panX, v = e * this._zoom.zoom + this._zoom.panY;
|
|
1734
|
+
this._tooltip.show(y, m, v, n, {}, r);
|
|
1765
1735
|
return;
|
|
1766
1736
|
}
|
|
1767
|
-
const
|
|
1768
|
-
this._tooltip.show(
|
|
1737
|
+
const l = this._defaultTooltipHTML(o, i, s, a, r), c = t * this._zoom.zoom + this._zoom.panX, d = e * this._zoom.zoom + this._zoom.panY, p = this.canvas.getBoundingClientRect(), b = this.container.getBoundingClientRect(), u = p.left - b.left, S = p.top - b.top;
|
|
1738
|
+
this._tooltip.show(l, c + u, d + S, n, {}, r);
|
|
1769
1739
|
}
|
|
1770
1740
|
hideTooltip() {
|
|
1771
1741
|
this._tooltip && this._tooltip.hide();
|
|
1772
1742
|
}
|
|
1773
1743
|
getZoneAt(t, e, o) {
|
|
1774
|
-
const
|
|
1775
|
-
|
|
1776
|
-
const n = (this.state.zones || []).find((
|
|
1777
|
-
return
|
|
1744
|
+
const i = L.t2c(t, e, o, this.state.tri), s = this.ctx;
|
|
1745
|
+
s.save(), s.setTransform(1, 0, 0, 1, 0, 0);
|
|
1746
|
+
const n = (this.state.zones || []).find((r) => r.path && s.isPointInPath(r.path, i.x, i.y));
|
|
1747
|
+
return s.restore(), n;
|
|
1778
1748
|
}
|
|
1779
|
-
|
|
1780
|
-
this.state.scale = 1, this.state.tx = 0, this.state.ty = 0, this.render(),
|
|
1749
|
+
zoomReset() {
|
|
1750
|
+
this.state.scale = 1, this.state.tx = 0, this.state.ty = 0, this.render(), this._bus.emit("zoom", { scale: this.state.scale, tx: this.state.tx, ty: this.state.ty });
|
|
1781
1751
|
}
|
|
1782
1752
|
dispose() {
|
|
1783
|
-
var t, e, o;
|
|
1784
|
-
(t = this.ro) == null || t.disconnect(), (e = this._tooltip) == null || e.dispose(), (o = this.canvas) == null || o.remove();
|
|
1753
|
+
var t, e, o, i;
|
|
1754
|
+
(t = this.ro) == null || t.disconnect(), (e = this._tooltip) == null || e.dispose(), (o = this.canvas) == null || o.remove(), window.removeEventListener("mouseup", this._onUp), (i = this._bus) == null || i.dispose();
|
|
1785
1755
|
}
|
|
1786
1756
|
/**
|
|
1787
1757
|
* 默认 tooltip HTML 生成
|
|
1788
1758
|
* @private
|
|
1789
1759
|
*/
|
|
1790
|
-
_defaultTooltipHTML(t, e, o,
|
|
1791
|
-
var
|
|
1792
|
-
const n = this.state.hoveredPoint,
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1760
|
+
_defaultTooltipHTML(t, e, o, i, s) {
|
|
1761
|
+
var S, g, f;
|
|
1762
|
+
const n = this.state.hoveredPoint, h = `<div style="font-size:14px; font-weight:bold; margin-bottom:4px; color:#fff;">${((S = n == null ? void 0 : n.series) == null ? void 0 : S.name) || "Data Point"}</div>`, a = {
|
|
1763
|
+
PD: "局部放电",
|
|
1764
|
+
D1: "低能放电",
|
|
1765
|
+
D2: "高能放电",
|
|
1766
|
+
T1: "热故障,t<300℃",
|
|
1767
|
+
T2: "热故障,300℃<t<700℃",
|
|
1768
|
+
T3: "热故障,t>700℃",
|
|
1769
|
+
DT: "热和放电混合故障",
|
|
1770
|
+
S: "温度<200℃时的杂散气体",
|
|
1771
|
+
C: "绝缘纸可能碳化",
|
|
1772
|
+
O: "矿物油过热",
|
|
1773
|
+
"T3-H": "仅矿物油过热",
|
|
1774
|
+
ND: "正常"
|
|
1775
|
+
}, l = (s == null ? void 0 : s.title) || (s == null ? void 0 : s.desc) || (s ? a[s.name] : "") || "", c = s ? `${s.name || s.id || ""} ${l}`.trim() : "Outside", d = s && ((g = s.color) == null ? void 0 : g.replace(/[\d.]+\)$/, "1)")) || "#fff";
|
|
1776
|
+
let p = `
|
|
1777
|
+
${h}
|
|
1778
|
+
<div style="color:${d}; font-size:13px; font-weight:bold; padding-bottom:8px; margin-bottom:8px; border-bottom:1px solid rgba(255,255,255,0.07);">
|
|
1779
|
+
${c}
|
|
1780
|
+
</div>
|
|
1802
1781
|
`;
|
|
1803
|
-
const
|
|
1804
|
-
return
|
|
1805
|
-
const
|
|
1806
|
-
let
|
|
1807
|
-
|
|
1782
|
+
const b = ["#00e5ff", "#ff6b35", "#ffcc02"], u = (f = n == null ? void 0 : n.series) == null ? void 0 : f.data;
|
|
1783
|
+
return i.forEach((y, m) => {
|
|
1784
|
+
const v = b[m % 3];
|
|
1785
|
+
let x = "-";
|
|
1786
|
+
u && (Array.isArray(u) ? x = u[m] !== void 0 ? u[m] : "-" : typeof u == "object" && (u.value && Array.isArray(u.value) ? x = u.value[m] !== void 0 ? u.value[m] : "-" : u[y] !== void 0 && (x = u[y]))), p += `
|
|
1808
1787
|
<div style="display:flex; align-items:center; margin-bottom:6px; font-size:13px;">
|
|
1809
|
-
<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background-color:${
|
|
1810
|
-
<span style="color:#cbd5e1; flex-grow:1;">${
|
|
1811
|
-
<span style="color:#fff; font-weight:bold; margin-left:20px;">${
|
|
1788
|
+
<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background-color:${v}; margin-right:8px;"></span>
|
|
1789
|
+
<span style="color:#cbd5e1; flex-grow:1;">${y}</span>
|
|
1790
|
+
<span style="color:#fff; font-weight:bold; margin-left:20px;">${x}</span>
|
|
1812
1791
|
</div>
|
|
1813
1792
|
`;
|
|
1814
|
-
}),
|
|
1793
|
+
}), p;
|
|
1815
1794
|
}
|
|
1816
1795
|
}
|
|
1817
|
-
function
|
|
1818
|
-
const t =
|
|
1796
|
+
function bt(w) {
|
|
1797
|
+
const t = w.trim().toLowerCase();
|
|
1819
1798
|
if (t.startsWith("#")) {
|
|
1820
1799
|
let o = t.slice(1);
|
|
1821
1800
|
o.length === 3 && (o = o[0] + o[0] + o[1] + o[1] + o[2] + o[2]);
|
|
1822
|
-
const
|
|
1823
|
-
return [
|
|
1801
|
+
const i = parseInt(o.substring(0, 2), 16), s = parseInt(o.substring(2, 4), 16), n = parseInt(o.substring(4, 6), 16), r = o.length === 8 ? parseInt(o.substring(6, 8), 16) / 255 : 1;
|
|
1802
|
+
return [i, s, n, r];
|
|
1824
1803
|
}
|
|
1825
1804
|
const e = t.match(/rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\)/);
|
|
1826
1805
|
return e ? [
|
|
@@ -1830,13 +1809,18 @@ function St(v) {
|
|
|
1830
1809
|
e[4] !== void 0 ? parseFloat(e[4]) : 1
|
|
1831
1810
|
] : t === "transparent" ? [0, 0, 0, 0] : [255, 255, 255, 1];
|
|
1832
1811
|
}
|
|
1833
|
-
function
|
|
1834
|
-
const [
|
|
1835
|
-
return `rgba(${
|
|
1812
|
+
function zt(w, t = 1) {
|
|
1813
|
+
const [e, o, i, s] = bt(w);
|
|
1814
|
+
return `rgba(${e},${o},${i},${s * t})`;
|
|
1836
1815
|
}
|
|
1837
|
-
|
|
1816
|
+
function Ot(w, t, e) {
|
|
1817
|
+
const [o, i, s, n] = bt(w), [r, h, a, l] = bt(t), c = Math.round(o + (r - o) * e), d = Math.round(i + (h - i) * e), p = Math.round(s + (a - s) * e), b = n + (l - n) * e;
|
|
1818
|
+
return `rgba(${c},${d},${p},${b})`;
|
|
1819
|
+
}
|
|
1820
|
+
const C = Object.freeze({
|
|
1821
|
+
colors: Q,
|
|
1838
1822
|
// 故障区域定义(用于诊断逻辑与 3D/2D 绘图)
|
|
1839
|
-
ZONES:
|
|
1823
|
+
ZONES: Rt,
|
|
1840
1824
|
// 坐标轴固定配置(X: C2H4/C2H6, Y: CH4/H2, Z: C2H2/C2H4)
|
|
1841
1825
|
AXES: {
|
|
1842
1826
|
x: { color: "#ff9a3c", label: "X (C₂H₄/C₂H₆)" },
|
|
@@ -1963,31 +1947,31 @@ class F {
|
|
|
1963
1947
|
return t < 0.01 ? t.toFixed(4) : t.toFixed(3);
|
|
1964
1948
|
}
|
|
1965
1949
|
}
|
|
1966
|
-
class
|
|
1967
|
-
constructor(t, e, o,
|
|
1968
|
-
this.ctx = t, this.opts =
|
|
1950
|
+
class jt {
|
|
1951
|
+
constructor(t, e, o, i = {}) {
|
|
1952
|
+
this.ctx = t, this.opts = i, this.layout = i.layout ?? "fill", this.resize(e, o), this.updateOptions(i);
|
|
1969
1953
|
}
|
|
1970
1954
|
/** 更新渲染配置 */
|
|
1971
1955
|
updateOptions(t = {}) {
|
|
1972
1956
|
this.opts = { ...this.opts, ...t }, (t.layout !== void 0 || t.grid !== void 0) && (t.layout !== void 0 && (this.layout = t.layout), this.resize(this.W, this.H));
|
|
1973
1957
|
const e = this.opts.theme ?? "dark";
|
|
1974
|
-
this.theme =
|
|
1958
|
+
this.theme = C.THEMES[e] ?? C.THEMES.dark, this.themeName = e, this.zone = this.processZones(this.opts.zone ?? C.ZONES);
|
|
1975
1959
|
const o = {
|
|
1976
1960
|
show: !0,
|
|
1977
1961
|
fill: { show: !0, alpha: this.theme.wallFillAlpha, colors: { xy: void 0, xz: void 0, yz: void 0 } },
|
|
1978
1962
|
grid: { show: !0, lineStyle: { lineWidth: 0.6, alpha: parseInt(this.theme.wallGridAlpha, 16) / 255, type: "solid" } },
|
|
1979
1963
|
border: { show: !0, lineStyle: { lineWidth: 0.8, alpha: parseInt(this.theme.wallEdgeAlpha, 16) / 255, type: "solid" } }
|
|
1980
|
-
},
|
|
1964
|
+
}, i = {
|
|
1981
1965
|
show: !0,
|
|
1982
1966
|
lineStyle: { lineWidth: 1.8, arrowSize: 9 },
|
|
1983
1967
|
labelStyle: { show: !0, fontSize: 14, fontWeight: "bold", distance: 16 },
|
|
1984
1968
|
tickLabelStyle: { show: !0, fontSize: 12, color: "rgba(255, 255, 255, 0.8)" },
|
|
1985
1969
|
data: {
|
|
1986
|
-
x: { name:
|
|
1987
|
-
y: { name:
|
|
1988
|
-
z: { name:
|
|
1970
|
+
x: { name: C.AXES.x.label, color: C.AXES.x.color },
|
|
1971
|
+
y: { name: C.AXES.y.label, color: C.AXES.y.color },
|
|
1972
|
+
z: { name: C.AXES.z.label, color: C.AXES.z.color }
|
|
1989
1973
|
}
|
|
1990
|
-
},
|
|
1974
|
+
}, s = {
|
|
1991
1975
|
show: !0,
|
|
1992
1976
|
fade3DAlpha: 0.03,
|
|
1993
1977
|
grid: {
|
|
@@ -2003,41 +1987,45 @@ class It {
|
|
|
2003
1987
|
},
|
|
2004
1988
|
zone: {
|
|
2005
1989
|
show: !0,
|
|
2006
|
-
alpha: 0.
|
|
2007
|
-
borderStyle: { show: !0,
|
|
1990
|
+
alpha: 0.75,
|
|
1991
|
+
borderStyle: { show: !0, width: 1.4 }
|
|
2008
1992
|
}
|
|
2009
1993
|
};
|
|
2010
|
-
this.opts.wall =
|
|
1994
|
+
this.opts.wall = X(o, this.opts.wall || {}), this.opts.axis = X(i, this.opts.axis || {}), this.opts.plane2D = X(s, this.opts.plane2D || {});
|
|
2011
1995
|
}
|
|
2012
1996
|
/** 预计算区域数据 */
|
|
2013
1997
|
processZones(t) {
|
|
2014
|
-
let e = [], o = {};
|
|
2015
|
-
return
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
1998
|
+
let e = [], o = {}, i, s = {}, n = this.opts.colors || C.colors || Q;
|
|
1999
|
+
return t && typeof t == "object" && Array.isArray(t.data) ? (e = t.data, o = t.labelStyle || {}, i = t.alpha, s = t.borderStyle || {}, t.colors && (n = t.colors)) : e = C.ZONES, e.map((r, h) => {
|
|
2000
|
+
let a = r.color || n[h % n.length];
|
|
2001
|
+
i !== void 0 && a !== "transparent" && (a = mt(a, i));
|
|
2002
|
+
const [l, c, d] = ut(a), p = o, b = p.color || a;
|
|
2003
|
+
let u = [];
|
|
2004
|
+
p.fontWeight && u.push(p.fontWeight), p.fontSize && u.push(p.fontSize + "px"), p.fontFamily && u.push(p.fontFamily);
|
|
2005
|
+
const S = u.length > 0 ? u.join(" ") : null, g = s;
|
|
2006
|
+
let f = g.color || a;
|
|
2007
|
+
g.alpha !== void 0 && f !== "transparent" && (f = mt(f, g.alpha));
|
|
2008
|
+
const y = r.coordinates && r.coordinates[0] ? r.coordinates[0] : [0, 0, 0], m = r.coordinates && r.coordinates[1] ? r.coordinates[1] : [0, 0, 0];
|
|
2009
|
+
return {
|
|
2010
|
+
...r,
|
|
2011
|
+
fillBase: `rgba(${l},${c},${d},`,
|
|
2012
|
+
edgeStr: f,
|
|
2013
|
+
x0: F.realToU(y[0]),
|
|
2014
|
+
x1: F.realToU(m[0]),
|
|
2015
|
+
y0: F.realToU(y[1]),
|
|
2016
|
+
y1: F.realToU(m[1]),
|
|
2017
|
+
z0: F.realToU(y[2]),
|
|
2018
|
+
z1: F.realToU(m[2]),
|
|
2019
|
+
labelColor: b,
|
|
2020
|
+
labelFontStr: S
|
|
2033
2021
|
};
|
|
2034
2022
|
});
|
|
2035
2023
|
}
|
|
2036
2024
|
/** 获取配置的字体样式 */
|
|
2037
2025
|
getFont(t) {
|
|
2038
|
-
var
|
|
2039
|
-
const e =
|
|
2040
|
-
return `${o.fontWeight ?? (t === "axis" || t === "zone" ? "bold" : e.fontWeight)} ${
|
|
2026
|
+
var r;
|
|
2027
|
+
const e = C.TEXT_STYLE, o = ((r = this.opts.textStyle) == null ? void 0 : r[t]) ?? this.opts.textStyle ?? {}, i = o.fontSize ?? e.fontSize, s = o.fontFamily ?? e.fontFamily;
|
|
2028
|
+
return `${o.fontWeight ?? (t === "axis" || t === "zone" ? "bold" : e.fontWeight)} ${i}px ${s}`;
|
|
2041
2029
|
}
|
|
2042
2030
|
/** 更新渲染器主题 */
|
|
2043
2031
|
setTheme(t) {
|
|
@@ -2048,31 +2036,31 @@ class It {
|
|
|
2048
2036
|
this.W = t, this.H = e;
|
|
2049
2037
|
const o = this.opts.grid;
|
|
2050
2038
|
if (o && (o.left !== void 0 || o.right !== void 0 || o.top !== void 0 || o.bottom !== void 0)) {
|
|
2051
|
-
const
|
|
2052
|
-
this.renderW =
|
|
2039
|
+
const s = gt(t, e, o, 0);
|
|
2040
|
+
this.renderW = s.availW, this.renderH = s.availH, this.offsetX = s.left, this.offsetY = s.top;
|
|
2053
2041
|
} else if (this.layout === "square") {
|
|
2054
|
-
const
|
|
2055
|
-
this.renderW =
|
|
2042
|
+
const s = Math.min(t, e);
|
|
2043
|
+
this.renderW = s, this.renderH = s, this.offsetX = (t - s) / 2, this.offsetY = (e - s) / 2;
|
|
2056
2044
|
} else
|
|
2057
2045
|
this.renderW = t, this.renderH = e, this.offsetX = 0, this.offsetY = 0;
|
|
2058
|
-
this.CX = this.offsetX + this.renderW *
|
|
2046
|
+
this.CX = this.offsetX + this.renderW * C.PROJ.cx, this.CY = this.offsetY + this.renderH * C.PROJ.cy;
|
|
2059
2047
|
}
|
|
2060
2048
|
/**
|
|
2061
2049
|
* 核心投影函数:将 0-1 坐标系的 3D 点映射为 2D 屏幕画布坐标
|
|
2062
2050
|
* 逻辑:平移中心 -> 执行绕 X, Y 轴旋转矩阵 -> 应用视场角(FOV)进行透视缩放 -> 映射至屏幕中心
|
|
2063
2051
|
*/
|
|
2064
2052
|
proj(t, e, o) {
|
|
2065
|
-
const
|
|
2053
|
+
const i = t - 0.5, s = e - 0.5, n = o - 0.5, r = this.cam.rotX * Math.PI / 180, h = this.cam.rotY * Math.PI / 180, a = Math.cos(r), l = Math.sin(r), c = Math.cos(h), d = Math.sin(h), p = i * c + s * d, b = -i * d + s * c, u = n * a - b * l, S = n * l + b * a, g = Math.min(this.renderW, this.renderH) * C.PROJ.scaleK * this.cam.zoomFactor, f = C.PROJ.fov, y = S + f;
|
|
2066
2054
|
return {
|
|
2067
|
-
x: this.CX +
|
|
2068
|
-
y: this.CY -
|
|
2069
|
-
depth:
|
|
2055
|
+
x: this.CX + p / y * g * f,
|
|
2056
|
+
y: this.CY - u / y * g * f,
|
|
2057
|
+
depth: S
|
|
2070
2058
|
};
|
|
2071
2059
|
}
|
|
2072
2060
|
/** 判断法向量是否背向相机 (Backface Culling) */
|
|
2073
2061
|
isBackface(t, e, o) {
|
|
2074
|
-
const
|
|
2075
|
-
return o *
|
|
2062
|
+
const i = this.cam.rotX * Math.PI / 180, s = this.cam.rotY * Math.PI / 180, n = Math.cos(i), r = Math.sin(i), h = Math.cos(s), a = Math.sin(s), l = -t * a + e * h;
|
|
2063
|
+
return o * r + l * n > 0;
|
|
2076
2064
|
}
|
|
2077
2065
|
/**
|
|
2078
2066
|
* 渲染主循环
|
|
@@ -2081,90 +2069,90 @@ class It {
|
|
|
2081
2069
|
* @param {string} view 当前视图 ID ('3d', 'xz' 等)
|
|
2082
2070
|
* @param {number} flat 扁平化程度 (0-1), 用于 3D 转换 2D 平面的视觉过度
|
|
2083
2071
|
*/
|
|
2084
|
-
draw(t, e, o,
|
|
2085
|
-
var
|
|
2086
|
-
const
|
|
2087
|
-
|
|
2088
|
-
const
|
|
2089
|
-
|
|
2090
|
-
const
|
|
2091
|
-
[...
|
|
2092
|
-
(
|
|
2093
|
-
).forEach((
|
|
2072
|
+
draw(t, e, o, i) {
|
|
2073
|
+
var l;
|
|
2074
|
+
const s = this.ctx, n = window.devicePixelRatio || 1;
|
|
2075
|
+
s.setTransform(n, 0, 0, n, 0, 0), s.clearRect(0, 0, this.W, this.H), this.cam = t;
|
|
2076
|
+
const r = ((l = this.opts.plane2D) == null ? void 0 : l.fade3DAlpha) ?? 0.03, h = 1 - i * (1 - r);
|
|
2077
|
+
s.globalAlpha = h, this.drawWalls(h), this.drawGrid(h), this.drawZones(h), this.drawAxes(h), this.drawTickLabels(h);
|
|
2078
|
+
const a = Array.isArray(e) ? e : [];
|
|
2079
|
+
[...a].sort(
|
|
2080
|
+
(c, d) => this.proj(F.realToU(c.position.x), F.realToU(c.position.y), F.realToU(c.position.z)).depth - this.proj(F.realToU(d.position.x), F.realToU(d.position.y), F.realToU(d.position.z)).depth
|
|
2081
|
+
).forEach((c) => this.drawPoint3D(c, h)), s.globalAlpha = 1, i > 0 && this.opts.plane2D.show && this.draw2DOverlay(o, i, a);
|
|
2094
2082
|
}
|
|
2095
2083
|
// 基础绘制
|
|
2096
2084
|
face(t, e, o) {
|
|
2097
|
-
const
|
|
2098
|
-
|
|
2099
|
-
for (let n = 1; n <
|
|
2100
|
-
|
|
2085
|
+
const i = this.ctx, s = t.map((n) => this.proj(...n));
|
|
2086
|
+
i.beginPath(), i.moveTo(s[0].x, s[0].y);
|
|
2087
|
+
for (let n = 1; n < s.length; n++) i.lineTo(s[n].x, s[n].y);
|
|
2088
|
+
i.closePath(), e && (i.fillStyle = e, i.fill()), o && (i.strokeStyle = o, i.lineWidth = 0.8, i.stroke());
|
|
2101
2089
|
}
|
|
2102
2090
|
line(t, e) {
|
|
2103
2091
|
const o = this.ctx;
|
|
2104
2092
|
o.beginPath(), o.moveTo(t.x, t.y), o.lineTo(e.x, e.y), o.stroke();
|
|
2105
2093
|
}
|
|
2106
|
-
box(t, e, o,
|
|
2094
|
+
box(t, e, o, i, s, n, r, h) {
|
|
2107
2095
|
[
|
|
2108
|
-
{ f: [[t, o,
|
|
2109
|
-
{ f: [[t, o, n], [e, o, n], [e,
|
|
2110
|
-
{ f: [[t, o,
|
|
2111
|
-
{ f: [[t,
|
|
2112
|
-
{ f: [[t, o,
|
|
2113
|
-
{ f: [[e, o,
|
|
2114
|
-
].filter(({ n:
|
|
2115
|
-
f:
|
|
2116
|
-
d:
|
|
2117
|
-
})).sort((
|
|
2096
|
+
{ f: [[t, o, s], [e, o, s], [e, i, s], [t, i, s]], n: [0, 0, -1] },
|
|
2097
|
+
{ f: [[t, o, n], [e, o, n], [e, i, n], [t, i, n]], n: [0, 0, 1] },
|
|
2098
|
+
{ f: [[t, o, s], [e, o, s], [e, o, n], [t, o, n]], n: [0, -1, 0] },
|
|
2099
|
+
{ f: [[t, i, s], [e, i, s], [e, i, n], [t, i, n]], n: [0, 1, 0] },
|
|
2100
|
+
{ f: [[t, o, s], [t, i, s], [t, i, n], [t, o, n]], n: [-1, 0, 0] },
|
|
2101
|
+
{ f: [[e, o, s], [e, i, s], [e, i, n], [e, o, n]], n: [1, 0, 0] }
|
|
2102
|
+
].filter(({ n: l }) => !this.isBackface(l[0], l[1], l[2])).map(({ f: l }) => ({
|
|
2103
|
+
f: l,
|
|
2104
|
+
d: l.reduce((c, d) => c + this.proj(...d).depth, 0) / l.length
|
|
2105
|
+
})).sort((l, c) => l.d - c.d).forEach(({ f: l }) => this.face(l, r, h));
|
|
2118
2106
|
}
|
|
2119
2107
|
drawWalls(t = 1) {
|
|
2120
2108
|
const e = this.ctx, o = this.opts.wall;
|
|
2121
2109
|
if (!o.show) return;
|
|
2122
|
-
const
|
|
2110
|
+
const i = this.opts.axis.data, s = C.TICKS.vals, n = [
|
|
2123
2111
|
{
|
|
2124
2112
|
// X-Z 面 (底层底面通常认为是 z=0 或 y=0)
|
|
2125
2113
|
pts: [[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]],
|
|
2126
|
-
color: o.fill.colors.xz ||
|
|
2127
|
-
segs: (
|
|
2128
|
-
gridColor:
|
|
2114
|
+
color: o.fill.colors.xz || i.x.color,
|
|
2115
|
+
segs: (r) => [[this.proj(r, 0, 0), this.proj(r, 0, 1)], [this.proj(0, 0, r), this.proj(1, 0, r)]],
|
|
2116
|
+
gridColor: i.x.color
|
|
2129
2117
|
},
|
|
2130
2118
|
{
|
|
2131
2119
|
// Y-Z 面
|
|
2132
2120
|
pts: [[0, 0, 0], [0, 1, 0], [0, 1, 1], [0, 0, 1]],
|
|
2133
|
-
color: o.fill.colors.yz ||
|
|
2134
|
-
segs: (
|
|
2135
|
-
gridColor:
|
|
2121
|
+
color: o.fill.colors.yz || i.y.color,
|
|
2122
|
+
segs: (r) => [[this.proj(0, r, 0), this.proj(0, r, 1)], [this.proj(0, 0, r), this.proj(0, 1, r)]],
|
|
2123
|
+
gridColor: i.y.color
|
|
2136
2124
|
},
|
|
2137
2125
|
{
|
|
2138
2126
|
// X-Y 面
|
|
2139
2127
|
pts: [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]],
|
|
2140
|
-
color: o.fill.colors.xy ||
|
|
2141
|
-
segs: (
|
|
2142
|
-
gridColor:
|
|
2128
|
+
color: o.fill.colors.xy || i.z.color,
|
|
2129
|
+
segs: (r) => [[this.proj(r, 0, 0), this.proj(r, 1, 0)], [this.proj(0, r, 0), this.proj(1, r, 0)]],
|
|
2130
|
+
gridColor: i.z.color
|
|
2143
2131
|
}
|
|
2144
2132
|
];
|
|
2145
|
-
o.fill.show && (e.globalAlpha = o.fill.alpha * t, n.forEach((
|
|
2146
|
-
e.strokeStyle =
|
|
2147
|
-
}), e.setLineDash([]), e.globalAlpha = t), o.border.show && (e.lineWidth = o.border.lineStyle.lineWidth, e.globalAlpha = o.border.lineStyle.alpha * t, o.border.lineStyle.type === "dashed" ? e.setLineDash([4, 4]) : o.border.lineStyle.type === "dotted" ? e.setLineDash([2, 2]) : e.setLineDash([]), n.forEach(({ pts:
|
|
2148
|
-
e.strokeStyle = h,
|
|
2133
|
+
o.fill.show && (e.globalAlpha = o.fill.alpha * t, n.forEach((r) => this.face(r.pts, r.color)), e.globalAlpha = t), o.grid.show && (e.lineWidth = o.grid.lineStyle.lineWidth, e.globalAlpha = o.grid.lineStyle.alpha * t, o.grid.lineStyle.type === "dashed" ? e.setLineDash([4, 4]) : o.grid.lineStyle.type === "dotted" ? e.setLineDash([2, 2]) : e.setLineDash([]), n.forEach(({ gridColor: r, segs: h }) => {
|
|
2134
|
+
e.strokeStyle = r, s.forEach((a) => h(a).forEach(([l, c]) => this.line(l, c)));
|
|
2135
|
+
}), e.setLineDash([]), e.globalAlpha = t), o.border.show && (e.lineWidth = o.border.lineStyle.lineWidth, e.globalAlpha = o.border.lineStyle.alpha * t, o.border.lineStyle.type === "dashed" ? e.setLineDash([4, 4]) : o.border.lineStyle.type === "dotted" ? e.setLineDash([2, 2]) : e.setLineDash([]), n.forEach(({ pts: r, gridColor: h }) => {
|
|
2136
|
+
e.strokeStyle = h, r.forEach((a, l) => this.line(this.proj(...a), this.proj(...r[(l + 1) % r.length])));
|
|
2149
2137
|
}), e.setLineDash([]), e.globalAlpha = t);
|
|
2150
2138
|
}
|
|
2151
2139
|
drawGrid(t = 1) {
|
|
2152
2140
|
const e = this.ctx;
|
|
2153
|
-
e.globalAlpha = t, e.strokeStyle = this.theme.outerGrid, e.lineWidth = 0.4,
|
|
2141
|
+
e.globalAlpha = t, e.strokeStyle = this.theme.outerGrid, e.lineWidth = 0.4, C.TICKS.vals.forEach((o) => {
|
|
2154
2142
|
this.line(this.proj(1, o, 0), this.proj(1, o, 1)), this.line(this.proj(1, 0, o), this.proj(1, 1, o));
|
|
2155
2143
|
});
|
|
2156
2144
|
}
|
|
2157
2145
|
drawZones(t) {
|
|
2158
|
-
const e = this.ctx, o =
|
|
2146
|
+
const e = this.ctx, o = C.ZONE_VIS;
|
|
2159
2147
|
[...this.zone].sort(
|
|
2160
|
-
(
|
|
2161
|
-
).forEach((
|
|
2148
|
+
(i, s) => this.proj((i.x0 + i.x1) / 2, (i.y0 + i.y1) / 2, (i.z0 + i.z1) / 2).depth - this.proj((s.x0 + s.x1) / 2, (s.y0 + s.y1) / 2, (s.z0 + s.z1) / 2).depth
|
|
2149
|
+
).forEach((i) => {
|
|
2162
2150
|
e.globalAlpha = t;
|
|
2163
|
-
const
|
|
2164
|
-
if (this.box(
|
|
2151
|
+
const s = i.fillAlpha !== void 0 ? i.fillAlpha : o.fillAlpha;
|
|
2152
|
+
if (this.box(i.x0, i.x1, i.y0, i.y1, i.z0, i.z1, i.fillBase + s + ")", i.edgeStr), t > 0.05) {
|
|
2165
2153
|
e.globalAlpha = t * o.labelAlpha;
|
|
2166
|
-
const n = this.proj((
|
|
2167
|
-
e.font =
|
|
2154
|
+
const n = this.proj((i.x0 + i.x1) / 2, (i.y0 + i.y1) / 2, (i.z0 + i.z1) / 2);
|
|
2155
|
+
e.font = i.labelFontStr || this.getFont("zone"), e.textAlign = "center", e.fillStyle = i.labelColor, e.fillText(i.name, n.x, n.y);
|
|
2168
2156
|
}
|
|
2169
2157
|
e.globalAlpha = t;
|
|
2170
2158
|
});
|
|
@@ -2177,107 +2165,110 @@ class It {
|
|
|
2177
2165
|
{ from: [0, 0, 0], to: [1.18, 0, 0], lp: [1.22, 0, 0], ...o.data.x },
|
|
2178
2166
|
{ from: [0, 0, 0], to: [0, 1.18, 0], lp: [0, 1.22, 0], ...o.data.y },
|
|
2179
2167
|
{ from: [0, 0, 0], to: [0, 0, 1.22], lp: [0, 0, 1.28], ...o.data.z }
|
|
2180
|
-
].forEach((
|
|
2181
|
-
var
|
|
2182
|
-
const
|
|
2183
|
-
if (e.beginPath(), e.moveTo(
|
|
2184
|
-
const h = n.x -
|
|
2185
|
-
e.beginPath(), e.moveTo(n.x, n.y), e.lineTo(n.x - c *
|
|
2168
|
+
].forEach((i) => {
|
|
2169
|
+
var r;
|
|
2170
|
+
const s = this.proj(...i.from), n = this.proj(...i.to);
|
|
2171
|
+
if (e.beginPath(), e.moveTo(s.x, s.y), e.lineTo(n.x, n.y), e.strokeStyle = i.color, e.lineWidth = o.lineStyle.lineWidth, e.stroke(), o.lineStyle.arrowSize > 0) {
|
|
2172
|
+
const h = n.x - s.x, a = n.y - s.y, l = Math.hypot(h, a) || 1, c = h / l, d = a / l, p = o.lineStyle.arrowSize;
|
|
2173
|
+
e.beginPath(), e.moveTo(n.x, n.y), e.lineTo(n.x - c * p + d * (p / 2.25), n.y - d * p - c * (p / 2.25)), e.lineTo(n.x - c * p - d * (p / 2.25), n.y - d * p + c * (p / 2.25)), e.closePath(), e.fillStyle = i.color, e.fill();
|
|
2186
2174
|
}
|
|
2187
2175
|
if (o.labelStyle.show) {
|
|
2188
|
-
const h = n.x -
|
|
2189
|
-
e.fillStyle =
|
|
2176
|
+
const h = n.x - s.x, a = n.y - s.y, l = Math.hypot(h, a) || 1, c = n.x + h / l * o.labelStyle.distance, d = n.y + a / l * o.labelStyle.distance;
|
|
2177
|
+
e.fillStyle = i.color, e.font = `${o.labelStyle.fontWeight} ${o.labelStyle.fontSize}px ${((r = this.opts.textStyle) == null ? void 0 : r.fontFamily) || C.TEXT_STYLE.fontFamily}`, e.textAlign = "center", e.textBaseline = "middle", e.fillText(i.name, c, d);
|
|
2190
2178
|
}
|
|
2191
2179
|
});
|
|
2192
2180
|
}
|
|
2193
2181
|
drawTickLabels(t = 1) {
|
|
2194
2182
|
const e = this.ctx;
|
|
2195
2183
|
e.globalAlpha = t;
|
|
2196
|
-
const { vals: o, labels:
|
|
2197
|
-
e.font = this.getFont("tick"), o.forEach((n,
|
|
2184
|
+
const { vals: o, labels: i } = C.TICKS, s = this.theme.tickAlpha;
|
|
2185
|
+
e.font = this.getFont("tick"), o.forEach((n, r) => {
|
|
2198
2186
|
let h = this.proj(n, 0, 0);
|
|
2199
|
-
e.fillStyle =
|
|
2187
|
+
e.fillStyle = C.AXES.x.color + s, e.textAlign = "center", e.fillText(i[r], h.x, h.y + 13), h = this.proj(0, n, 0), e.fillStyle = C.AXES.y.color + s, e.textAlign = "left", e.fillText(i[r], h.x + 7, h.y + 4), h = this.proj(0, 0, n), e.fillStyle = C.AXES.z.color + s, e.textAlign = "right", e.fillText(i[r], h.x - 7, h.y + 4);
|
|
2200
2188
|
}), e.textAlign = "center";
|
|
2201
2189
|
}
|
|
2202
2190
|
drawPoint3D(t, e) {
|
|
2203
|
-
const o = F.realToU(t.position.x),
|
|
2204
|
-
this.drawPointAt(this.proj(o,
|
|
2191
|
+
const o = F.realToU(t.position.x), i = F.realToU(t.position.y), s = F.realToU(t.position.z);
|
|
2192
|
+
this.drawPointAt(this.proj(o, i, s), t, e);
|
|
2205
2193
|
}
|
|
2206
2194
|
drawPointAt(t, e, o = 1) {
|
|
2207
|
-
var
|
|
2208
|
-
const
|
|
2209
|
-
if (d &&
|
|
2210
|
-
let
|
|
2211
|
-
const
|
|
2212
|
-
if (Array.isArray(
|
|
2213
|
-
|
|
2195
|
+
var u, S;
|
|
2196
|
+
const i = this.ctx, s = C.POINT, n = t.x ?? t.cx, r = t.y ?? t.cy, h = ((u = e.itemStyle) == null ? void 0 : u.radius) ?? s.defaultSize, a = ((S = e.itemStyle) == null ? void 0 : S.color) ?? e.color, l = e.name, c = e.textStyle || {}, d = e.glowStyle !== void 0, p = e.glowStyle || {};
|
|
2197
|
+
if (d && p.show !== !1) {
|
|
2198
|
+
let g = [], f = 3, y = p.glowDistance !== void 0 ? p.glowDistance : 4;
|
|
2199
|
+
const m = p.color ?? a;
|
|
2200
|
+
if (Array.isArray(p.colors) && p.colors.length > 0)
|
|
2201
|
+
g = p.colors, f = g.length;
|
|
2214
2202
|
else {
|
|
2215
|
-
const
|
|
2216
|
-
|
|
2217
|
-
for (let
|
|
2218
|
-
const
|
|
2219
|
-
|
|
2203
|
+
const v = p.startColor || mt(m, 0.15), x = p.endColor || "transparent";
|
|
2204
|
+
f = p.count !== void 0 ? parseInt(p.count, 10) : 3, g = [];
|
|
2205
|
+
for (let A = 0; A < f; A++) {
|
|
2206
|
+
const T = f > 1 ? A / (f - 1) : 0;
|
|
2207
|
+
g.push(Bt(v, x, T));
|
|
2220
2208
|
}
|
|
2221
2209
|
}
|
|
2222
|
-
for (let
|
|
2223
|
-
const
|
|
2224
|
-
|
|
2210
|
+
for (let v = f - 1; v >= 0; v--) {
|
|
2211
|
+
const x = g[v];
|
|
2212
|
+
i.save(), i.fillStyle = x, i.beginPath(), i.arc(n, r, h + (v + 1) * y, 0, Math.PI * 2), i.fill(), i.restore();
|
|
2225
2213
|
}
|
|
2226
2214
|
}
|
|
2227
|
-
|
|
2228
|
-
const
|
|
2229
|
-
|
|
2215
|
+
i.globalAlpha = o, i.beginPath(), i.arc(n, r, h, 0, Math.PI * 2);
|
|
2216
|
+
const b = i.createRadialGradient(n - h * s.hlOffset, r - h * s.hlOffset, 1, n, r, h);
|
|
2217
|
+
b.addColorStop(0, "rgba(255,255,255,0.9)"), b.addColorStop(0.4, a + "ee"), b.addColorStop(1, a + "88"), i.fillStyle = b, i.fill(), i.strokeStyle = this.theme.pointStroke, i.lineWidth = 1.3, i.stroke(), i.restore(), l && (i.font = c.bold ? `bold ${c.fontSize || 12}px ${c.fontFamily || "sans-serif"}` : `${c.fontSize || 12}px ${c.fontFamily || "sans-serif"}`, i.fillStyle = c.color ?? e.color, i.textAlign = "left", i.fillText(l, n + h + 3, r - 2));
|
|
2230
2218
|
}
|
|
2231
2219
|
draw2DOverlay(t, e, o) {
|
|
2232
|
-
var
|
|
2233
|
-
const
|
|
2234
|
-
if (!
|
|
2235
|
-
const
|
|
2236
|
-
|
|
2237
|
-
let a = this.offsetX,
|
|
2238
|
-
const
|
|
2239
|
-
if (!(
|
|
2240
|
-
const _ =
|
|
2241
|
-
a = _.l,
|
|
2220
|
+
var T;
|
|
2221
|
+
const i = C.PLANES[t];
|
|
2222
|
+
if (!i) return;
|
|
2223
|
+
const s = this.ctx, n = this.theme, r = this.opts.plane2D, h = this.opts.axis.data;
|
|
2224
|
+
s.save(), s.globalAlpha = e;
|
|
2225
|
+
let a = this.offsetX, l = this.offsetY, c = this.offsetX + this.renderW, d = this.offsetY + this.renderH;
|
|
2226
|
+
const p = this.opts.grid || {};
|
|
2227
|
+
if (!(p.left !== void 0 || p.right !== void 0 || p.top !== void 0 || p.bottom !== void 0)) {
|
|
2228
|
+
const _ = C.PAD2D || { l: 70, r: 30, t: 50, b: 60 };
|
|
2229
|
+
a = _.l, l = _.t, c = this.W - _.r, d = this.H - _.b;
|
|
2242
2230
|
}
|
|
2243
|
-
const
|
|
2244
|
-
a =
|
|
2245
|
-
const { vals:
|
|
2231
|
+
const u = c - a, S = d - l, g = Math.min(u, S), f = a + u / 2, y = l + S / 2;
|
|
2232
|
+
a = f - g / 2, c = f + g / 2, l = y - g / 2, d = y + g / 2;
|
|
2233
|
+
const { vals: m, labels: v } = C.TICKS, x = (_, M) => ({
|
|
2246
2234
|
cx: a + _ * (c - a),
|
|
2247
|
-
cy: d -
|
|
2248
|
-
}),
|
|
2249
|
-
if (
|
|
2250
|
-
|
|
2251
|
-
i.
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
const
|
|
2256
|
-
|
|
2257
|
-
}),
|
|
2258
|
-
const
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2235
|
+
cy: d - M * (d - l)
|
|
2236
|
+
}), A = this.themeName ?? "dark";
|
|
2237
|
+
if (r.grid.show && (s.fillStyle = r.grid.backgroundColor ?? i.bgColor[A] ?? i.bgColor.dark, s.fillRect(a, l, c - a, d - l)), r.zone.show && this.zone.forEach((_) => {
|
|
2238
|
+
var W;
|
|
2239
|
+
const [M, k] = [_[i.hAxis + "0"], _[i.hAxis + "1"]], [P, E] = [_[i.vAxis + "0"], _[i.vAxis + "1"]], z = x(M, P), D = x(k, E), j = D.cx - z.cx, H = z.cy - D.cy, K = _.fillAlpha !== void 0 ? _.fillAlpha : r.zone.alpha;
|
|
2240
|
+
s.fillStyle = _.fillBase + K + ")", s.fillRect(z.cx, D.cy, j, H), r.zone.borderStyle.show && (s.strokeStyle = _.edgeStr, s.lineWidth = r.zone.borderStyle.width ?? 1.4, s.strokeRect(z.cx, D.cy, j, H));
|
|
2241
|
+
const O = (z.cx + D.cx) / 2, ot = (z.cy + D.cy) / 2;
|
|
2242
|
+
s.font = _.labelFontStr || this.getFont("zone"), s.textAlign = "center", s.fillStyle = _.labelColor;
|
|
2243
|
+
const R = ((W = this.opts.zone) == null ? void 0 : W.labelStyle) || {}, it = typeof R.formatter == "function" ? R.formatter(_) : _.name;
|
|
2244
|
+
s.fillText(it, O, ot + 4);
|
|
2245
|
+
}), r.grid.show && (s.strokeStyle = r.grid.lineStyle.color || n.plane2dGrid, s.lineWidth = r.grid.lineStyle.lineWidth, s.globalAlpha = e * r.grid.lineStyle.alpha, r.grid.lineStyle.type === "dashed" ? s.setLineDash([4, 4]) : r.grid.lineStyle.type === "dotted" ? s.setLineDash([2, 2]) : s.setLineDash([]), m.forEach((_) => {
|
|
2246
|
+
const M = x(_, 0).cx, k = x(0, _).cy;
|
|
2247
|
+
s.beginPath(), s.moveTo(M, l), s.lineTo(M, d), s.stroke(), s.beginPath(), s.moveTo(a, k), s.lineTo(c, k), s.stroke();
|
|
2248
|
+
}), s.setLineDash([]), s.globalAlpha = e), r.axis.show) {
|
|
2249
|
+
const _ = h[i.hAxis].color, M = h[i.vAxis].color;
|
|
2250
|
+
s.lineWidth = r.axis.lineStyle.lineWidth, s.globalAlpha = e * r.axis.lineStyle.alpha, s.strokeStyle = _, s.beginPath(), s.moveTo(a, d), s.lineTo(c + 10, d), s.stroke(), s.strokeStyle = M, s.beginPath(), s.moveTo(a, d), s.lineTo(a, l - 10), s.stroke(), s.globalAlpha = e;
|
|
2251
|
+
const k = ((T = this.opts.textStyle) == null ? void 0 : T.fontFamily) || C.TEXT_STYLE.fontFamily;
|
|
2252
|
+
if (r.axis.tickLabelStyle.show) {
|
|
2253
|
+
s.font = `${r.axis.tickLabelStyle.fontSize}px ${k}`;
|
|
2254
|
+
const P = r.axis.tickLabelStyle.distance;
|
|
2255
|
+
m.forEach((E, z) => {
|
|
2256
|
+
s.fillStyle = _, s.textAlign = "center", s.fillText(v[z], x(E, 0).cx, d + P + r.axis.tickLabelStyle.fontSize / 2), s.fillStyle = M, s.textAlign = "right", s.fillText(v[z], a - P + 2, x(0, E).cy + r.axis.tickLabelStyle.fontSize / 3);
|
|
2266
2257
|
});
|
|
2267
2258
|
}
|
|
2268
|
-
if (
|
|
2269
|
-
|
|
2270
|
-
const P =
|
|
2271
|
-
|
|
2259
|
+
if (r.axis.labelStyle.show) {
|
|
2260
|
+
s.font = `bold ${r.axis.labelStyle.fontSize}px ${k}`;
|
|
2261
|
+
const P = r.axis.labelStyle.distance;
|
|
2262
|
+
s.textAlign = "center", s.fillStyle = _, s.fillText(h[i.hAxis].name, (a + c) / 2, d + P + r.axis.labelStyle.fontSize), s.save(), s.translate(a - P - r.axis.labelStyle.fontSize, (l + d) / 2), s.rotate(-Math.PI / 2), s.fillStyle = M, s.fillText(h[i.vAxis].name, 0, 0), s.restore();
|
|
2272
2263
|
}
|
|
2273
2264
|
}
|
|
2274
2265
|
o.forEach((_) => {
|
|
2275
|
-
const
|
|
2276
|
-
this.drawPointAt(
|
|
2277
|
-
}),
|
|
2266
|
+
const M = x(F.realToU(_.position[i.hAxis]), F.realToU(_.position[i.vAxis]));
|
|
2267
|
+
this.drawPointAt(M, _, e);
|
|
2268
|
+
}), s.restore();
|
|
2278
2269
|
}
|
|
2279
2270
|
}
|
|
2280
|
-
const
|
|
2271
|
+
const rt = class rt {
|
|
2281
2272
|
/**
|
|
2282
2273
|
* 构造函数
|
|
2283
2274
|
* @param {string|HTMLElement} container 容器选择器或元素
|
|
@@ -2286,15 +2277,16 @@ const it = class it {
|
|
|
2286
2277
|
* @param {string} opts.theme 初始主题 ('dark' | 'light')
|
|
2287
2278
|
*/
|
|
2288
2279
|
constructor(t, e = {}) {
|
|
2289
|
-
this.series = [], this.opts = e, this.cam = {
|
|
2290
|
-
rotX:
|
|
2291
|
-
rotY:
|
|
2280
|
+
if (this.series = [], this.opts = e, this.cam = {
|
|
2281
|
+
rotX: C.CAM.elev,
|
|
2282
|
+
rotY: C.CAM.yaw,
|
|
2292
2283
|
zoomFactor: 1
|
|
2293
2284
|
}, this.view = e.initialView ?? "3d", this.layout = e.layout ?? "fill", this.drag = { active: !1, lastX: 0, lastY: 0 }, this.tween = {
|
|
2294
2285
|
from: { rotX: 0, rotY: 0 },
|
|
2295
2286
|
to: { rotX: 0, rotY: 0 },
|
|
2296
2287
|
t: 1
|
|
2297
|
-
}, this.animId = null, this.pinchDist = null, this.
|
|
2288
|
+
}, this.animId = null, this.pinchDist = null, this._bus = new pt(), t = typeof t == "string" ? document.querySelector(t) : t, !t) throw new Error("ThreeRatioChart: container not found");
|
|
2289
|
+
this.buildDOM(t), this.renderer = new jt(this.ctx, this.W, this.H, e), this.bindEvents(), this.applyView(), this.render();
|
|
2298
2290
|
}
|
|
2299
2291
|
/**
|
|
2300
2292
|
* 设置图表配置(主要用于更新数据或视角)
|
|
@@ -2316,29 +2308,32 @@ const it = class it {
|
|
|
2316
2308
|
const e = Array.isArray(t.series) ? t.series : [t.series];
|
|
2317
2309
|
this.series = e.map((o) => ({
|
|
2318
2310
|
name: o.name ?? "",
|
|
2319
|
-
color: o.color ??
|
|
2311
|
+
color: o.color ?? C.POINT.defaultColor,
|
|
2320
2312
|
itemStyle: o.itemStyle ?? {},
|
|
2321
2313
|
textStyle: o.textStyle ?? {},
|
|
2322
2314
|
glowStyle: o.glowStyle,
|
|
2323
2315
|
position: o.position ?? { x: 0, y: 0, z: 0 }
|
|
2324
2316
|
})), this.emit("dataChange", [...this.series]), this.render();
|
|
2325
2317
|
}
|
|
2326
|
-
t.view && t.view !== this.view && this.setView(t.view);
|
|
2318
|
+
return t.view && t.view !== this.view && this.setView(t.view), this;
|
|
2327
2319
|
}
|
|
2328
2320
|
}
|
|
2321
|
+
setSeries(t) {
|
|
2322
|
+
return this.setOption({ series: t });
|
|
2323
|
+
}
|
|
2329
2324
|
/**
|
|
2330
2325
|
* 切换视图角度(包含平滑补间动画)
|
|
2331
2326
|
* @param {string} v 视图 ID
|
|
2332
2327
|
*/
|
|
2333
2328
|
setView(t) {
|
|
2334
|
-
if (!
|
|
2329
|
+
if (!rt.VIEWS[t]) return;
|
|
2335
2330
|
this.view = t, cancelAnimationFrame(this.animId);
|
|
2336
2331
|
const e = this.getViewTarget(t);
|
|
2337
2332
|
this.tween = {
|
|
2338
2333
|
from: { rotX: this.cam.rotX, rotY: this.cam.rotY },
|
|
2339
2334
|
to: e,
|
|
2340
2335
|
t: 0
|
|
2341
|
-
}, this.cv.style.cursor = t === "3d" ? "grab" : "default", this.runTween(), this.emit("viewChange", t);
|
|
2336
|
+
}, this.cv.style.cursor = t === "3d" ? "grab" : "default", this.runTween(), this._bus.emit("viewChange", t);
|
|
2342
2337
|
}
|
|
2343
2338
|
/** 切换主题渲染 */
|
|
2344
2339
|
setTheme(t) {
|
|
@@ -2349,26 +2344,45 @@ const it = class it {
|
|
|
2349
2344
|
* @returns {Array} 匹配到的诊断区域信息数组
|
|
2350
2345
|
*/
|
|
2351
2346
|
diagnose(t, e, o) {
|
|
2352
|
-
if (!this.renderer) return [{ ...this.opts.unknown ??
|
|
2353
|
-
const
|
|
2354
|
-
|
|
2347
|
+
if (!this.renderer) return [{ ...this.opts.unknown ?? C.UNKNOWN }];
|
|
2348
|
+
const i = this.renderer.zone.filter((s) => {
|
|
2349
|
+
if (!s.coordinates || s.coordinates.length < 2) return !1;
|
|
2350
|
+
const n = s.coordinates[0], r = s.coordinates[1];
|
|
2351
|
+
return t >= n[0] && t < r[0] && e >= n[1] && e < r[1] && o >= n[2] && o < r[2];
|
|
2352
|
+
}).map((s) => ({ name: s.name, title: s.title, color: s.color || "#fff" }));
|
|
2353
|
+
return i.length ? i : [{ ...this.opts.unknown ?? C.UNKNOWN }];
|
|
2355
2354
|
}
|
|
2356
2355
|
on(t, e) {
|
|
2357
|
-
|
|
2356
|
+
return this._bus.on(t, e), this;
|
|
2357
|
+
}
|
|
2358
|
+
off(t, e) {
|
|
2359
|
+
return this._bus.off(t, e), this;
|
|
2358
2360
|
}
|
|
2359
2361
|
emit(t, ...e) {
|
|
2360
|
-
|
|
2362
|
+
this._bus.emit(t, ...e);
|
|
2361
2363
|
}
|
|
2362
2364
|
render() {
|
|
2363
|
-
!this.renderer || !this.ctx
|
|
2365
|
+
if (!this.renderer || !this.ctx) return;
|
|
2366
|
+
this.renderer.draw(this.cam, this.series, this.view, this.flatness());
|
|
2367
|
+
const t = [];
|
|
2368
|
+
this.series.forEach((e) => {
|
|
2369
|
+
if (e.position) {
|
|
2370
|
+
const o = this.diagnose(e.position.x, e.position.y, e.position.z);
|
|
2371
|
+
t.push({
|
|
2372
|
+
series: e,
|
|
2373
|
+
zone: o.length ? o[0] : null,
|
|
2374
|
+
position: e.position
|
|
2375
|
+
});
|
|
2376
|
+
}
|
|
2377
|
+
}), t.length > 0 && this._bus.emit("diagnose", t);
|
|
2364
2378
|
}
|
|
2365
2379
|
dispose() {
|
|
2366
|
-
var t, e;
|
|
2367
|
-
cancelAnimationFrame(this.animId), (t = this.resizeObs) == null || t.disconnect(), (e = this.cv) == null || e.remove(), window.removeEventListener("mousemove", this.onMouseMove), window.removeEventListener("mouseup", this.onMouseUp);
|
|
2380
|
+
var t, e, o;
|
|
2381
|
+
cancelAnimationFrame(this.animId), (t = this.resizeObs) == null || t.disconnect(), (e = this.cv) == null || e.remove(), window.removeEventListener("mousemove", this.onMouseMove), window.removeEventListener("mouseup", this.onMouseUp), (o = this._bus) == null || o.dispose();
|
|
2368
2382
|
}
|
|
2369
2383
|
// 内部方法
|
|
2370
2384
|
getViewTarget(t) {
|
|
2371
|
-
const e =
|
|
2385
|
+
const e = rt.VIEWS[t];
|
|
2372
2386
|
return {
|
|
2373
2387
|
rotX: typeof e.rotX == "function" ? e.rotX() : e.rotX,
|
|
2374
2388
|
rotY: typeof e.rotY == "function" ? e.rotY() : e.rotY
|
|
@@ -2386,20 +2400,23 @@ const it = class it {
|
|
|
2386
2400
|
return Math.max(0, 1 - (Math.abs(this.cam.rotX - t.rotX) + Math.abs(this.cam.rotY - t.rotY)) / 30);
|
|
2387
2401
|
}
|
|
2388
2402
|
runTween() {
|
|
2389
|
-
this.tween.t = Math.min(1, this.tween.t +
|
|
2403
|
+
this.tween.t = Math.min(1, this.tween.t + C.TWEEN.step);
|
|
2390
2404
|
const t = ((e) => e < 0.5 ? 2 * e * e : 1 - Math.pow(-2 * e + 2, 2) / 2)(this.tween.t);
|
|
2391
2405
|
this.cam.rotX = this.tween.from.rotX + (this.tween.to.rotX - this.tween.from.rotX) * t, this.cam.rotY = this.tween.from.rotY + (this.tween.to.rotY - this.tween.from.rotY) * t, this.render(), this.tween.t < 1 && (this.animId = requestAnimationFrame(() => this.runTween()));
|
|
2392
2406
|
}
|
|
2393
2407
|
buildDOM(t) {
|
|
2394
|
-
const e = t.getBoundingClientRect();
|
|
2395
|
-
this.W =
|
|
2396
|
-
var
|
|
2397
|
-
const { width: s, height:
|
|
2398
|
-
s > 0 &&
|
|
2408
|
+
const e = window.devicePixelRatio || 1, o = t.getBoundingClientRect();
|
|
2409
|
+
this.W = o.width > 0 ? Math.round(o.width) : 600, this.H = o.height > 0 ? Math.round(o.height) : 540, this.cv = document.createElement("canvas"), this.cv.className = "trc-canvas", this.cv.width = this.W * e, this.cv.height = this.H * e, this.cv.style.cssText = "width:100%;height:100%;display:block;touch-action:none;", this.ctx = this.cv.getContext("2d"), t.appendChild(this.cv), this.resizeObs = new ResizeObserver((i) => {
|
|
2410
|
+
var r;
|
|
2411
|
+
const { width: s, height: n } = i[0].contentRect;
|
|
2412
|
+
if (s > 0 && n > 0) {
|
|
2413
|
+
const h = window.devicePixelRatio || 1;
|
|
2414
|
+
this.W = Math.round(s), this.H = Math.round(n), this.cv.width = this.W * h, this.cv.height = this.H * h, (r = this.renderer) == null || r.resize(this.W, this.H), this.render();
|
|
2415
|
+
}
|
|
2399
2416
|
}), this.resizeObs.observe(t);
|
|
2400
2417
|
}
|
|
2401
2418
|
bindEvents() {
|
|
2402
|
-
const t =
|
|
2419
|
+
const t = C.DRAG, e = this.cv;
|
|
2403
2420
|
e.addEventListener("mousedown", (o) => {
|
|
2404
2421
|
this.view === "3d" && (this.drag = { active: !0, lastX: o.clientX, lastY: o.clientY }, e.style.cursor = "grabbing", cancelAnimationFrame(this.animId));
|
|
2405
2422
|
}), this.onMouseMove = (o) => {
|
|
@@ -2427,14 +2444,14 @@ const it = class it {
|
|
|
2427
2444
|
(o) => {
|
|
2428
2445
|
if (this.view === "3d")
|
|
2429
2446
|
if (o.touches.length === 2 && this.pinchDist !== null) {
|
|
2430
|
-
const
|
|
2447
|
+
const i = Math.hypot(
|
|
2431
2448
|
o.touches[0].clientX - o.touches[1].clientX,
|
|
2432
2449
|
o.touches[0].clientY - o.touches[1].clientY
|
|
2433
2450
|
);
|
|
2434
2451
|
this.cam.zoomFactor = Math.max(
|
|
2435
2452
|
t.zoomMin,
|
|
2436
|
-
Math.min(t.zoomMax, this.cam.zoomFactor *
|
|
2437
|
-
), this.pinchDist =
|
|
2453
|
+
Math.min(t.zoomMax, this.cam.zoomFactor * i / this.pinchDist)
|
|
2454
|
+
), this.pinchDist = i, this.render();
|
|
2438
2455
|
} else this.drag.active && o.touches.length === 1 && (this.cam.rotY += (o.touches[0].clientX - this.drag.lastX) * t.rotYSens, this.cam.rotX = Math.max(
|
|
2439
2456
|
t.rotXMin,
|
|
2440
2457
|
Math.min(t.rotXMax, this.cam.rotX + (o.touches[0].clientY - this.drag.lastY) * t.rotXSens)
|
|
@@ -2459,20 +2476,20 @@ const it = class it {
|
|
|
2459
2476
|
);
|
|
2460
2477
|
}
|
|
2461
2478
|
};
|
|
2462
|
-
|
|
2463
|
-
"3d": { rotX: () =>
|
|
2479
|
+
J(rt, "VIEWS", {
|
|
2480
|
+
"3d": { rotX: () => C.CAM.elev, rotY: () => C.CAM.yaw },
|
|
2464
2481
|
xz: { rotX: 0, rotY: 0 },
|
|
2465
2482
|
yz: { rotX: 0, rotY: 90 },
|
|
2466
2483
|
xy: { rotX: 90, rotY: 0 }
|
|
2467
2484
|
});
|
|
2468
|
-
let
|
|
2469
|
-
function
|
|
2470
|
-
const t =
|
|
2485
|
+
let Mt = rt;
|
|
2486
|
+
function ut(w) {
|
|
2487
|
+
const t = w.trim().toLowerCase();
|
|
2471
2488
|
if (t.startsWith("#")) {
|
|
2472
2489
|
let o = t.slice(1);
|
|
2473
2490
|
o.length === 3 && (o = o[0] + o[0] + o[1] + o[1] + o[2] + o[2]);
|
|
2474
|
-
const
|
|
2475
|
-
return [
|
|
2491
|
+
const i = parseInt(o.substring(0, 2), 16), s = parseInt(o.substring(2, 4), 16), n = parseInt(o.substring(4, 6), 16), r = o.length === 8 ? parseInt(o.substring(6, 8), 16) / 255 : 1;
|
|
2492
|
+
return [i, s, n, r];
|
|
2476
2493
|
}
|
|
2477
2494
|
const e = t.match(/rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\)/);
|
|
2478
2495
|
return e ? [
|
|
@@ -2482,15 +2499,22 @@ function ht(v) {
|
|
|
2482
2499
|
e[4] !== void 0 ? parseFloat(e[4]) : 1
|
|
2483
2500
|
] : t === "transparent" ? [0, 0, 0, 0] : [255, 255, 255, 1];
|
|
2484
2501
|
}
|
|
2485
|
-
function
|
|
2486
|
-
const [e, o,
|
|
2487
|
-
return `rgba(${e},${o},${
|
|
2502
|
+
function mt(w, t) {
|
|
2503
|
+
const [e, o, i, s] = ut(w);
|
|
2504
|
+
return `rgba(${e},${o},${i},${t !== void 0 ? t : s})`;
|
|
2505
|
+
}
|
|
2506
|
+
function Bt(w, t, e) {
|
|
2507
|
+
const [o, i, s, n] = ut(w), [r, h, a, l] = ut(t), c = Math.round(o + (r - o) * e), d = Math.round(i + (h - i) * e), p = Math.round(s + (a - s) * e), b = n + (l - n) * e;
|
|
2508
|
+
return `rgba(${c},${d},${p},${b})`;
|
|
2488
2509
|
}
|
|
2489
|
-
function
|
|
2490
|
-
|
|
2491
|
-
|
|
2510
|
+
function Dt(w, t) {
|
|
2511
|
+
return w ? w.startsWith("#") ? wt(w, t) : w.startsWith("rgb") ? w.replace(/rgb(a)?\(([^)]+)\)/, (e, o, i) => {
|
|
2512
|
+
const s = i.split(","), n = s[0].trim(), r = s[1].trim(), h = s[2].trim();
|
|
2513
|
+
return `rgba(${n},${r},${h},${t})`;
|
|
2514
|
+
}) : w : `rgba(0,0,0,${t})`;
|
|
2492
2515
|
}
|
|
2493
|
-
const
|
|
2516
|
+
const Zt = {
|
|
2517
|
+
colors: Q,
|
|
2494
2518
|
theme: "light",
|
|
2495
2519
|
backgroundColor: "transparent",
|
|
2496
2520
|
grid: {
|
|
@@ -2502,7 +2526,8 @@ const jt = {
|
|
|
2502
2526
|
majorLineStyle: { type: "solid", width: 0.8, color: null }
|
|
2503
2527
|
},
|
|
2504
2528
|
zone: {
|
|
2505
|
-
data:
|
|
2529
|
+
data: Ft,
|
|
2530
|
+
alpha: 0.75,
|
|
2506
2531
|
labelStyle: { show: !0, fontSize: 12, borderRadius: 4 },
|
|
2507
2532
|
borderStyle: { show: !0, stroke: 1, type: "solid", color: null }
|
|
2508
2533
|
},
|
|
@@ -2510,8 +2535,8 @@ const jt = {
|
|
|
2510
2535
|
title: "",
|
|
2511
2536
|
min: -2,
|
|
2512
2537
|
max: 3,
|
|
2513
|
-
//
|
|
2514
|
-
labelStyle: { fontSize: 11, fontWeight: "normal", offsetX: 0, offsetY: 0, color: null },
|
|
2538
|
+
// 以10为底的对数范围 (例如 -2 表示 10^-2 = 0.01)
|
|
2539
|
+
labelStyle: { fontSize: 11, fontWeight: "normal", offsetX: 0, offsetY: 0, color: null, scientific: !0, formatter: null },
|
|
2515
2540
|
lineStyle: { show: !0, stroke: 1.5, type: "solid", color: null },
|
|
2516
2541
|
titleStyle: { fontSize: 13, color: null, fontWeight: "normal", align: "center", offsetX: 0, offsetY: 0 }
|
|
2517
2542
|
},
|
|
@@ -2519,14 +2544,14 @@ const jt = {
|
|
|
2519
2544
|
title: "",
|
|
2520
2545
|
min: -3,
|
|
2521
2546
|
max: 3,
|
|
2522
|
-
//
|
|
2523
|
-
labelStyle: { fontSize: 11, fontWeight: "normal", offsetX: 0, offsetY: 0, color: null },
|
|
2547
|
+
// 以10为底的对数范围
|
|
2548
|
+
labelStyle: { fontSize: 11, fontWeight: "normal", offsetX: 0, offsetY: 0, color: null, scientific: !0, formatter: null },
|
|
2524
2549
|
lineStyle: { show: !0, stroke: 1.5, type: "solid", color: null },
|
|
2525
2550
|
titleStyle: { fontSize: 13, color: null, fontWeight: "normal", align: "center", offsetX: 0, offsetY: 0 }
|
|
2526
2551
|
},
|
|
2527
2552
|
tooltip: { show: !0, formatter: null },
|
|
2528
2553
|
series: []
|
|
2529
|
-
},
|
|
2554
|
+
}, Et = {
|
|
2530
2555
|
light: {
|
|
2531
2556
|
backgroundColor: "#ffffff",
|
|
2532
2557
|
text: "#333333",
|
|
@@ -2554,35 +2579,36 @@ const jt = {
|
|
|
2554
2579
|
tooltipTextColor: "rgba(255,255,255,0.9)"
|
|
2555
2580
|
}
|
|
2556
2581
|
};
|
|
2557
|
-
function
|
|
2558
|
-
const t = Math.round(
|
|
2582
|
+
function Lt(w) {
|
|
2583
|
+
const t = Math.round(w);
|
|
2559
2584
|
return "10" + String(t).split("").map(
|
|
2560
2585
|
(o) => ({ "-": "⁻", 0: "⁰", 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹" })[o] || o
|
|
2561
2586
|
).join("");
|
|
2562
2587
|
}
|
|
2563
|
-
class
|
|
2588
|
+
class Pt {
|
|
2589
|
+
/** 构造函数,初始化容器、合并配置并绑定事件 */
|
|
2564
2590
|
constructor(t, e = {}) {
|
|
2565
2591
|
if (typeof t == "string" && (t = document.querySelector(t)), !t) throw new Error("[ETRAChart] Container element not found");
|
|
2566
|
-
this._container = t, this._opt =
|
|
2567
|
-
|
|
2568
|
-
const
|
|
2569
|
-
this._zoom.onWheel(
|
|
2570
|
-
}, this._onDown = (
|
|
2571
|
-
|
|
2572
|
-
}, this._onMove = (
|
|
2573
|
-
const
|
|
2574
|
-
if (this._zoom.moveDrag(
|
|
2592
|
+
this._container = t, this._opt = X(X({}, Zt), e), this._bus = new pt(), this._initDOM(), this._zoom = new St(this._opt.zoom || {}), this._tooltipRenderer = new vt(this._container, this._theme), this._hoverZone = null, this._hoverPoint = null, typeof ResizeObserver < "u" && (this._ro = new ResizeObserver(() => this.resize()), this._ro.observe(this._container)), this._onWheel = (i) => {
|
|
2593
|
+
i.preventDefault();
|
|
2594
|
+
const s = this._canvas.getBoundingClientRect(), n = i.clientX - s.left, r = i.clientY - s.top;
|
|
2595
|
+
this._zoom.onWheel(i.deltaY, n, r), this._bus.emit("zoom", this._zoom.state), this._render();
|
|
2596
|
+
}, this._onDown = (i) => {
|
|
2597
|
+
i.button === 0 && (this._zoom.startDrag(i.clientX, i.clientY), this._canvas.style.cursor = "grabbing");
|
|
2598
|
+
}, this._onMove = (i) => {
|
|
2599
|
+
const s = this._canvas.getBoundingClientRect();
|
|
2600
|
+
if (this._zoom.moveDrag(i.clientX, i.clientY, 1)) {
|
|
2575
2601
|
this._render();
|
|
2576
2602
|
return;
|
|
2577
2603
|
}
|
|
2578
2604
|
if (!this._coordMap || !this._drawnPoints) return;
|
|
2579
|
-
const n =
|
|
2580
|
-
let
|
|
2581
|
-
for (const
|
|
2582
|
-
const
|
|
2583
|
-
|
|
2605
|
+
const n = i.clientX - s.left, r = i.clientY - s.top, { panX: h, panY: a, zoom: l } = this._zoom, c = (n - h) / l, d = (r - a) / l;
|
|
2606
|
+
let p = null, b = 1 / 0;
|
|
2607
|
+
for (const u of this._drawnPoints) {
|
|
2608
|
+
const S = Math.hypot(c - u.px, d - u.py), g = u.series.size || 6;
|
|
2609
|
+
S < g * 2 + 5 && S < b && (b = S, p = u);
|
|
2584
2610
|
}
|
|
2585
|
-
|
|
2611
|
+
p !== this._hoverPoint && (this._hoverPoint = p, this._render(), p ? (this._canvas.style.cursor = "pointer", this._bus.emit("hover", p)) : (this._canvas.style.cursor = "default", this._bus.emit("hover", null)));
|
|
2586
2612
|
}, this._onUp = () => {
|
|
2587
2613
|
this._zoom.endDrag() && (this._canvas.style.cursor = this._hoverPoint ? "pointer" : "default", this._bus.emit("zoom", this._zoom.state));
|
|
2588
2614
|
}, this._onLeave = () => {
|
|
@@ -2593,198 +2619,247 @@ class zt {
|
|
|
2593
2619
|
const o = this._canvas;
|
|
2594
2620
|
o.addEventListener("wheel", this._onWheel, { passive: !1 }), o.addEventListener("mousedown", this._onDown), o.addEventListener("mousemove", this._onMove), o.addEventListener("mouseleave", this._onLeave), o.addEventListener("dblclick", this._onDbl), window.addEventListener("mouseup", this._onUp), this._render();
|
|
2595
2621
|
}
|
|
2622
|
+
/** 静态工厂方法,快速初始化图表实例 */
|
|
2596
2623
|
static init(t, e) {
|
|
2597
|
-
return new
|
|
2624
|
+
return new Pt(t, e);
|
|
2598
2625
|
}
|
|
2626
|
+
/** 获取当前匹配的主题配置 */
|
|
2599
2627
|
get _theme() {
|
|
2600
|
-
return
|
|
2628
|
+
return Et[this._opt.theme] || Et.light;
|
|
2601
2629
|
}
|
|
2630
|
+
/** 初始化 DOM 结构,创建内部 Canvas 画布 */
|
|
2602
2631
|
_initDOM() {
|
|
2603
2632
|
this._container.style.position = "relative", this._container.style.overflow = "hidden", this._canvas = document.createElement("canvas"), this._canvas.style.display = "block", this._canvas.style.width = "100%", this._canvas.style.height = "100%", this._container.appendChild(this._canvas), this._ctx = this._canvas.getContext("2d");
|
|
2604
2633
|
}
|
|
2634
|
+
/** 设置或更新图表配置项,并触发重绘 */
|
|
2605
2635
|
setOption(t) {
|
|
2606
|
-
return this._opt =
|
|
2636
|
+
return this._opt = X(this._opt, t), t.series !== void 0 && (this._opt.series = Array.isArray(t.series) ? t.series : [t.series]), this._coordMap = null, this._canvas && this._canvas.width > 0 && this._render(), this;
|
|
2637
|
+
}
|
|
2638
|
+
/** 单独更新数据系列并重绘 */
|
|
2639
|
+
setSeries(t) {
|
|
2640
|
+
return this._opt.series = Array.isArray(t) ? t : [t], this._render(), this;
|
|
2641
|
+
}
|
|
2642
|
+
/**
|
|
2643
|
+
* 诊断指定的坐标数据,返回命中的区域
|
|
2644
|
+
* @param {number} x - 原始或对数 X 坐标 (取决于实际的 logScale 配置)
|
|
2645
|
+
* @param {number} y - 原始或对数 Y 坐标
|
|
2646
|
+
* @returns {object|null} - 命中的故障区域对象
|
|
2647
|
+
*/
|
|
2648
|
+
diagnose(t, e) {
|
|
2649
|
+
if (!this._opt.zone || !this._opt.zone.data) return null;
|
|
2650
|
+
for (const o of this._opt.zone.data)
|
|
2651
|
+
if (o.coordinates && ct(t, e, o.coordinates))
|
|
2652
|
+
return o;
|
|
2653
|
+
return null;
|
|
2607
2654
|
}
|
|
2655
|
+
/** 绑定事件监听器 (如 hover, zoom, diagnose) */
|
|
2608
2656
|
on(t, e) {
|
|
2609
2657
|
return this._bus.on(t, e), this;
|
|
2610
2658
|
}
|
|
2659
|
+
/** 移除指定的事件监听器 */
|
|
2611
2660
|
off(t, e) {
|
|
2612
2661
|
return this._bus.off(t, e), this;
|
|
2613
2662
|
}
|
|
2663
|
+
/** 强制触发图表尺寸重新计算并重绘 */
|
|
2614
2664
|
resize() {
|
|
2615
2665
|
return this._render(), this;
|
|
2616
2666
|
}
|
|
2667
|
+
/** 销毁图表实例,解绑事件清理 DOM 和内存 */
|
|
2617
2668
|
dispose() {
|
|
2618
2669
|
this._ro && this._ro.disconnect(), this._tooltipRenderer.dispose(), this._canvas && this._canvas.parentNode && this._canvas.parentNode.removeChild(this._canvas), this._bus.dispose(), window.removeEventListener("mouseup", this._onUp);
|
|
2619
2670
|
}
|
|
2671
|
+
/** 计算当前画布物理尺寸和图表可用绘图网格范围 */
|
|
2620
2672
|
_dims() {
|
|
2621
|
-
const t = this._container.getBoundingClientRect(), e = t.width || 600, o = t.height || 400,
|
|
2622
|
-
(this._canvas.width !== Math.round(e *
|
|
2623
|
-
const
|
|
2624
|
-
return { W: e, H: o, box:
|
|
2673
|
+
const t = this._container.getBoundingClientRect(), e = t.width || 600, o = t.height || 400, i = window.devicePixelRatio || 1;
|
|
2674
|
+
(this._canvas.width !== Math.round(e * i) || this._canvas.height !== Math.round(o * i)) && (this._canvas.width = Math.round(e * i), this._canvas.height = Math.round(o * i));
|
|
2675
|
+
const s = gt(e, o, this._opt.grid, 0);
|
|
2676
|
+
return { W: e, H: o, box: s, dpr: i };
|
|
2625
2677
|
}
|
|
2678
|
+
/** 核心主渲染流程 */
|
|
2626
2679
|
_render() {
|
|
2627
|
-
const { W: t, H: e, box: o, dpr:
|
|
2628
|
-
if (!
|
|
2629
|
-
const n = this._theme,
|
|
2630
|
-
|
|
2631
|
-
const h =
|
|
2632
|
-
h !== "transparent" && (
|
|
2633
|
-
const a =
|
|
2634
|
-
this._coordMap = { xMin: a, xMax:
|
|
2635
|
-
const
|
|
2636
|
-
if (this._drawAxes(
|
|
2637
|
-
const
|
|
2638
|
-
let
|
|
2639
|
-
typeof
|
|
2640
|
-
series:
|
|
2641
|
-
logX:
|
|
2642
|
-
logY:
|
|
2643
|
-
rawX: Math.pow(10,
|
|
2644
|
-
rawY: Math.pow(10,
|
|
2645
|
-
zone:
|
|
2646
|
-
}) :
|
|
2680
|
+
const { W: t, H: e, box: o, dpr: i } = this._dims(), s = this._ctx;
|
|
2681
|
+
if (!s) return;
|
|
2682
|
+
const n = this._theme, r = this._opt;
|
|
2683
|
+
s.setTransform(i, 0, 0, i, 0, 0), s.clearRect(0, 0, t, e);
|
|
2684
|
+
const h = r.backgroundColor || n.backgroundColor || "transparent";
|
|
2685
|
+
h !== "transparent" && (s.fillStyle = h, s.fillRect(0, 0, t, e));
|
|
2686
|
+
const a = r.xAxis.min, l = r.xAxis.max, c = r.yAxis.min, d = r.yAxis.max, p = o.availW, b = o.availH, u = o.left, S = o.top, g = (m) => u + (m - a) / (l - a) * p, f = (m) => S + (d - m) / (d - c) * b;
|
|
2687
|
+
this._coordMap = { xMin: a, xMax: l, yMin: c, yMax: d, plotW: p, plotH: b, gL: u, gT: S, toPixX: g, toPixY: f }, s.save(), this._zoom.applyTransform(s), this._drawGrid(s, g, f, n, r), this._drawZones(s, g, f, n, r);
|
|
2688
|
+
const y = this._drawSeries(s, g, f, n, r);
|
|
2689
|
+
if (this._drawAxes(s, g, f, n, r, t, e, u, S, p, b), s.restore(), r.tooltip.show && this._hoverPoint) {
|
|
2690
|
+
const m = this._hoverPoint, v = g(m.logX) * this._zoom.zoom + this._zoom.panX, x = f(m.logY) * this._zoom.zoom + this._zoom.panY;
|
|
2691
|
+
let A = "";
|
|
2692
|
+
typeof r.tooltip.formatter == "function" ? A = r.tooltip.formatter({
|
|
2693
|
+
series: m.series,
|
|
2694
|
+
logX: m.logX,
|
|
2695
|
+
logY: m.logY,
|
|
2696
|
+
rawX: Math.pow(10, m.logX),
|
|
2697
|
+
rawY: Math.pow(10, m.logY),
|
|
2698
|
+
zone: m.zone
|
|
2699
|
+
}) : A = this._defaultTooltipHTML(m, r), this._tooltipRenderer.show(A, v, x, r.tooltip, n, m.zone);
|
|
2647
2700
|
} else
|
|
2648
2701
|
this._tooltipRenderer.hide();
|
|
2649
|
-
|
|
2650
|
-
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2702
|
+
y.length > 0 && this._bus.emit("diagnose", y);
|
|
2703
|
+
}
|
|
2704
|
+
/** 绘制背景对数网格(主网格和次级网格) */
|
|
2705
|
+
_drawGrid(t, e, o, i, s) {
|
|
2706
|
+
const n = s.xAxis.min, r = s.xAxis.max, h = s.yAxis.min, a = s.yAxis.max, l = this._coordMap.gL, c = this._coordMap.gT, d = this._coordMap.plotW, p = this._coordMap.plotH, b = s.grid.lineStyle || {}, u = b.color || i.gridLineMajor, S = i.gridLine;
|
|
2707
|
+
for (let g = Math.ceil(n); g <= Math.floor(r); g++) {
|
|
2708
|
+
const f = e(g);
|
|
2709
|
+
t.beginPath(), t.moveTo(f, c), t.lineTo(f, c + p), t.strokeStyle = u, t.lineWidth = b.width || 0.4, b.type === "dashed" ? t.setLineDash([4, 3]) : t.setLineDash([]), t.stroke(), t.setLineDash([]), t.strokeStyle = S, t.lineWidth = 0.25;
|
|
2710
|
+
for (let y = 2; y <= 9; y++) {
|
|
2711
|
+
const m = g + Math.log10(y);
|
|
2712
|
+
if (m > r) break;
|
|
2713
|
+
const v = e(m);
|
|
2714
|
+
t.beginPath(), t.moveTo(v, c), t.lineTo(v, c + p), t.stroke();
|
|
2661
2715
|
}
|
|
2662
2716
|
}
|
|
2663
|
-
for (let
|
|
2664
|
-
const
|
|
2665
|
-
t.beginPath(), t.moveTo(
|
|
2666
|
-
for (let
|
|
2667
|
-
const
|
|
2668
|
-
if (
|
|
2669
|
-
const
|
|
2670
|
-
t.beginPath(), t.moveTo(
|
|
2717
|
+
for (let g = Math.ceil(h); g <= Math.floor(a); g++) {
|
|
2718
|
+
const f = o(g);
|
|
2719
|
+
t.beginPath(), t.moveTo(l, f), t.lineTo(l + d, f), t.strokeStyle = u, t.lineWidth = b.width || 0.4, b.type === "dashed" ? t.setLineDash([4, 3]) : t.setLineDash([]), t.stroke(), t.setLineDash([]), t.strokeStyle = S, t.lineWidth = 0.25;
|
|
2720
|
+
for (let y = 2; y <= 9; y++) {
|
|
2721
|
+
const m = g + Math.log10(y);
|
|
2722
|
+
if (m > a) break;
|
|
2723
|
+
const v = o(m);
|
|
2724
|
+
t.beginPath(), t.moveTo(l, v), t.lineTo(l + d, v), t.stroke();
|
|
2671
2725
|
}
|
|
2672
2726
|
}
|
|
2673
2727
|
}
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2728
|
+
/** 绘制诊断区域多边形及其文本标签 */
|
|
2729
|
+
_drawZones(t, e, o, i, s) {
|
|
2730
|
+
const n = s.zone;
|
|
2731
|
+
if (!n || !n.data) return;
|
|
2732
|
+
const r = n.alpha, h = n.colors || s.colors || Q;
|
|
2733
|
+
for (let a = 0; a < n.data.length; a++) {
|
|
2734
|
+
const l = n.data[a];
|
|
2735
|
+
if (!l.coordinates || l.coordinates.length < 3) continue;
|
|
2736
|
+
t.beginPath(), l.coordinates.forEach((d, p) => {
|
|
2737
|
+
const b = e(d[0]), u = o(d[1]);
|
|
2738
|
+
p === 0 ? t.moveTo(b, u) : t.lineTo(b, u);
|
|
2739
|
+
}), t.closePath();
|
|
2740
|
+
let c = l.color || h[a % h.length];
|
|
2741
|
+
if (r !== void 0 && c !== "transparent" && (c = Dt(c, r)), t.fillStyle = c, t.fill(), n.borderStyle.show) {
|
|
2742
|
+
let d = n.borderStyle.color || c;
|
|
2743
|
+
n.borderStyle.alpha !== void 0 && d !== "transparent" && (d = Dt(d, n.borderStyle.alpha)), t.strokeStyle = d, t.lineWidth = n.borderStyle.width ?? 1, n.borderStyle.type === "dashed" ? t.setLineDash([5, 3]) : t.setLineDash([]), t.stroke(), t.setLineDash([]);
|
|
2744
|
+
}
|
|
2745
|
+
if (n.labelStyle.show && l.name) {
|
|
2746
|
+
let d = 0, p = 0;
|
|
2747
|
+
l.coordinates.forEach((T) => {
|
|
2748
|
+
d += e(T[0]), p += o(T[1]);
|
|
2749
|
+
});
|
|
2750
|
+
const b = d / l.coordinates.length, u = p / l.coordinates.length, S = this._coordMap.gL, g = this._coordMap.gT, f = this._coordMap.plotW, y = this._coordMap.plotH, m = Math.max(S + 4, Math.min(S + f - 4, b)), v = Math.max(g + 4, Math.min(g + y - 4, u)), x = n.labelStyle.fontSize || 12;
|
|
2751
|
+
t.textAlign = "center", t.textBaseline = "middle";
|
|
2752
|
+
const A = typeof n.labelStyle.formatter == "function" ? n.labelStyle.formatter(l) : l.name;
|
|
2753
|
+
t.font = `${n.labelStyle.fontWeight || "500"} ${x}px system-ui, sans-serif`, t.fillStyle = n.labelStyle.color || i.text, t.fillText(A, m, v);
|
|
2754
|
+
}
|
|
2694
2755
|
}
|
|
2695
2756
|
}
|
|
2696
|
-
_drawAxes(t, e, o,
|
|
2697
|
-
const d =
|
|
2698
|
-
t.beginPath(), t.rect(h, a,
|
|
2699
|
-
const
|
|
2757
|
+
_drawAxes(t, e, o, i, s, n, r, h, a, l, c) {
|
|
2758
|
+
const d = s.xAxis.min, p = s.xAxis.max, b = s.yAxis.min, u = s.yAxis.max;
|
|
2759
|
+
t.beginPath(), t.rect(h, a, l, c), t.strokeStyle = i.axisLine, t.lineWidth = 1, t.stroke();
|
|
2760
|
+
const S = s.xAxis.labelStyle.color || i.textSecondary, g = s.yAxis.labelStyle.color || i.textSecondary;
|
|
2700
2761
|
t.textAlign = "center", t.textBaseline = "middle";
|
|
2701
|
-
for (let
|
|
2702
|
-
const
|
|
2703
|
-
t.font = `${
|
|
2762
|
+
for (let f = Math.ceil(d); f <= Math.floor(p); f++) {
|
|
2763
|
+
const y = e(f), m = s.xAxis.labelStyle;
|
|
2764
|
+
t.font = `${m.fontWeight || "normal"} ${m.fontSize || 11}px system-ui, sans-serif`, t.fillStyle = S;
|
|
2765
|
+
const v = typeof m.formatter == "function" ? m.formatter(f, Math.pow(10, f)) : m.scientific === !1 ? String(Number(Math.pow(10, f).toPrecision(4))) : Lt(f);
|
|
2766
|
+
t.fillText(v, y + (m.offsetX || 0), a + c + 16 + (m.offsetY || 0));
|
|
2704
2767
|
}
|
|
2705
2768
|
t.textAlign = "right";
|
|
2706
|
-
for (let
|
|
2707
|
-
const
|
|
2708
|
-
t.font = `${
|
|
2769
|
+
for (let f = Math.ceil(b); f <= Math.floor(u); f++) {
|
|
2770
|
+
const y = o(f), m = s.yAxis.labelStyle;
|
|
2771
|
+
t.font = `${m.fontWeight || "normal"} ${m.fontSize || 11}px system-ui, sans-serif`, t.fillStyle = g;
|
|
2772
|
+
const v = typeof m.formatter == "function" ? m.formatter(f, Math.pow(10, f)) : m.scientific === !1 ? String(Number(Math.pow(10, f).toPrecision(4))) : Lt(f);
|
|
2773
|
+
t.fillText(v, h - 6 + (m.offsetX || 0), y + (m.offsetY || 0));
|
|
2709
2774
|
}
|
|
2710
|
-
if (
|
|
2711
|
-
const
|
|
2712
|
-
t.textAlign =
|
|
2775
|
+
if (s.xAxis.title) {
|
|
2776
|
+
const f = s.xAxis.titleStyle, y = { left: h, center: h + l / 2, right: h + l }, m = (y[f.align] || y.center) + (f.offsetX || 0), v = a + c + 38 + (f.offsetY || 0);
|
|
2777
|
+
t.textAlign = f.align === "left" ? "left" : f.align === "right" ? "right" : "center", t.font = `${f.fontWeight || "normal"} ${f.fontSize || 13}px system-ui, sans-serif`, t.fillStyle = f.color || i.text, t.fillText(s.xAxis.title, m, v);
|
|
2713
2778
|
}
|
|
2714
|
-
if (
|
|
2715
|
-
const
|
|
2716
|
-
t.save(), t.translate(
|
|
2779
|
+
if (s.yAxis.title) {
|
|
2780
|
+
const f = s.yAxis.titleStyle, y = { left: a + c, center: a + c / 2, right: a }, m = y[f.align] || y.center, v = 14 + (f.offsetX || 0), x = m + (f.offsetY || 0);
|
|
2781
|
+
t.save(), t.translate(v, x), t.rotate(-Math.PI / 2), t.textAlign = f.align === "left" ? "right" : f.align === "right" ? "left" : "center", t.font = `${f.fontWeight || "normal"} ${f.fontSize || 13}px system-ui, sans-serif`, t.fillStyle = f.color || i.text, t.fillText(s.yAxis.title, 0, 0), t.restore();
|
|
2717
2782
|
}
|
|
2718
2783
|
}
|
|
2719
|
-
|
|
2720
|
-
|
|
2784
|
+
/** 绘制所有数据点,并进行区域碰撞检测诊断 */
|
|
2785
|
+
_drawSeries(t, e, o, i, s) {
|
|
2786
|
+
var r, h, a;
|
|
2721
2787
|
const n = [];
|
|
2722
|
-
for (const
|
|
2788
|
+
for (const l of s.series || []) {
|
|
2723
2789
|
let c = 0, d = 0;
|
|
2724
|
-
if (Array.isArray(
|
|
2725
|
-
const
|
|
2726
|
-
c =
|
|
2727
|
-
} else if (
|
|
2728
|
-
c =
|
|
2790
|
+
if (Array.isArray(l.data) && l.data.length >= 2) {
|
|
2791
|
+
const x = typeof l.data[0] == "object" ? l.data[0].value : l.data[0], A = typeof l.data[1] == "object" ? l.data[1].value : l.data[1];
|
|
2792
|
+
c = l.logScale === !1 ? x : Math.log10(x || 1e-9), d = l.logScale === !1 ? A : Math.log10(A || 1e-9);
|
|
2793
|
+
} else if (l.dataX !== void 0 && l.dataY !== void 0)
|
|
2794
|
+
c = l.logScale === !1 ? l.dataX : Math.log10(l.dataX || 1e-9), d = l.logScale === !1 ? l.dataY : Math.log10(l.dataY || 1e-9);
|
|
2729
2795
|
else
|
|
2730
2796
|
continue;
|
|
2731
|
-
const
|
|
2732
|
-
let
|
|
2733
|
-
if (
|
|
2734
|
-
for (const
|
|
2735
|
-
if (
|
|
2736
|
-
|
|
2797
|
+
const p = e(c), b = o(d);
|
|
2798
|
+
let u = null;
|
|
2799
|
+
if (s.zone && s.zone.data) {
|
|
2800
|
+
for (const x of s.zone.data)
|
|
2801
|
+
if (x.coordinates && ct(c, d, x.coordinates)) {
|
|
2802
|
+
u = x;
|
|
2737
2803
|
break;
|
|
2738
2804
|
}
|
|
2739
2805
|
}
|
|
2740
|
-
n.push({ series:
|
|
2741
|
-
const
|
|
2742
|
-
|
|
2743
|
-
const
|
|
2744
|
-
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2806
|
+
n.push({ series: l, zone: u, logX: c, logY: d, px: p, py: b });
|
|
2807
|
+
const S = l.color || "#00e5ff";
|
|
2808
|
+
let g = l.size || 6;
|
|
2809
|
+
const f = l.shape || "circle", y = this._hoverPoint && this._hoverPoint.series === l;
|
|
2810
|
+
y && (g *= 1.5), t.save(), t.translate(p, b);
|
|
2811
|
+
const m = l.glowStyle || {};
|
|
2812
|
+
(m.show || y && m.show !== !1) && (t.shadowColor = m.color || wt(S, 0.8), t.shadowBlur = m.blur || 15), t.fillStyle = S, t.strokeStyle = ((r = l.itemStyle) == null ? void 0 : r.borderColor) || "none", t.lineWidth = ((h = l.itemStyle) == null ? void 0 : h.borderWidth) || 0, (t.strokeStyle === "none" || !((a = l.itemStyle) != null && a.borderColor)) && (t.lineWidth = 0), t.beginPath(), lt(t, 0, 0, f, g, 1, 0), t.fill(), t.lineWidth > 0 && t.stroke();
|
|
2813
|
+
const v = l.textStyle;
|
|
2814
|
+
if (v && v.show && l.name) {
|
|
2747
2815
|
t.shadowBlur = 0;
|
|
2748
|
-
const
|
|
2749
|
-
top: [0, -(
|
|
2750
|
-
bottom: [0,
|
|
2751
|
-
left: [-(
|
|
2752
|
-
right: [
|
|
2753
|
-
}, [
|
|
2754
|
-
t.textAlign =
|
|
2816
|
+
const x = {
|
|
2817
|
+
top: [0, -(g + 6)],
|
|
2818
|
+
bottom: [0, g + 12],
|
|
2819
|
+
left: [-(g + 6), 4],
|
|
2820
|
+
right: [g + 6, 4]
|
|
2821
|
+
}, [A, T] = x[v.position] || x.top;
|
|
2822
|
+
t.textAlign = v.position === "left" ? "right" : v.position === "right" ? "left" : "center", t.textBaseline = "middle", t.font = `${v.fontWeight || "normal"} ${v.fontSize || 12}px system-ui, sans-serif`, t.fillStyle = v.color || S, t.fillText(l.name, A, T);
|
|
2755
2823
|
}
|
|
2756
2824
|
t.restore();
|
|
2757
2825
|
}
|
|
2758
2826
|
return this._drawnPoints = n, n;
|
|
2759
2827
|
}
|
|
2828
|
+
/** 生成默认的浮窗 (Tooltip) HTML 结构 */
|
|
2760
2829
|
_defaultTooltipHTML(t, e) {
|
|
2761
|
-
const o = t.series,
|
|
2830
|
+
const o = t.series, i = Math.pow(10, t.logX).toPrecision(4), s = Math.pow(10, t.logY).toPrecision(4), n = e.xAxis.title || "X", r = e.yAxis.title || "Y", a = `<div style="font-size:14px; font-weight:bold; margin-bottom:4px; color:#fff;">${(o == null ? void 0 : o.name) || t.name || "Data Point"}</div>`, l = t.zone ? `${t.zone.name || ""} ${t.zone.title || t.zone.desc || ""}`.trim() : "Outside", c = t.zone && t.zone.color || "#fff";
|
|
2762
2831
|
return `
|
|
2763
|
-
|
|
2764
|
-
<div style="font-size:13px; font-weight:bold;
|
|
2765
|
-
|
|
2766
|
-
|
|
2832
|
+
${a}
|
|
2833
|
+
<div style="color:${c}; font-size:13px; font-weight:bold; padding-bottom:8px; margin-bottom:8px; border-bottom:1px solid rgba(255,255,255,0.07);">
|
|
2834
|
+
${l}
|
|
2835
|
+
</div>
|
|
2836
|
+
<div style="display:flex; align-items:center; margin-bottom:6px; font-size:13px;">
|
|
2837
|
+
<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background-color:#00e5ff; margin-right:8px;"></span>
|
|
2838
|
+
<span style="color:#cbd5e1; flex-grow:1;">${n}</span>
|
|
2839
|
+
<span style="color:#fff; font-weight:bold; margin-left:20px;">${i}</span>
|
|
2767
2840
|
</div>
|
|
2768
|
-
<div style="
|
|
2769
|
-
<span
|
|
2841
|
+
<div style="display:flex; align-items:center; margin-bottom:6px; font-size:13px;">
|
|
2842
|
+
<span style="display:inline-block; width:8px; height:8px; border-radius:50%; background-color:#ff6b35; margin-right:8px;"></span>
|
|
2843
|
+
<span style="color:#cbd5e1; flex-grow:1;">${r}</span>
|
|
2844
|
+
<span style="color:#fff; font-weight:bold; margin-left:20px;">${s}</span>
|
|
2770
2845
|
</div>
|
|
2771
2846
|
`;
|
|
2772
2847
|
}
|
|
2773
2848
|
}
|
|
2774
2849
|
export {
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2850
|
+
qt as DiagnosticTools,
|
|
2851
|
+
Ct as DuvalPentagon,
|
|
2852
|
+
Jt as DuvalTriangle,
|
|
2853
|
+
Pt as ETRAChart,
|
|
2854
|
+
Ft as ETRA_ZONES_A,
|
|
2855
|
+
Kt as ETRA_ZONES_B,
|
|
2856
|
+
nt as PENTAGON_ZONES_1,
|
|
2857
|
+
at as PENTAGON_ZONES_2,
|
|
2858
|
+
Rt as THREE_RADIO_ZONES,
|
|
2859
|
+
Yt as TRIANGLE_ZONES_1,
|
|
2860
|
+
Gt as TRIANGLE_ZONES_4,
|
|
2861
|
+
Vt as TRIANGLE_ZONES_5,
|
|
2862
|
+
Mt as ThreeRatioChart,
|
|
2863
|
+
yt as computedPercent
|
|
2789
2864
|
};
|
|
2790
2865
|
//# sourceMappingURL=index.js.map
|