@iyulab/u-widgets 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/dist/u-widgets-charts.js +119 -113
- package/dist/u-widgets-charts.js.map +1 -1
- package/dist/u-widgets-tools.js +11 -10
- package/dist/u-widgets-tools.js.map +1 -1
- package/dist/u-widgets.d.ts +31 -2
- package/dist/u-widgets.js +65 -49
- package/dist/u-widgets.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,6 +88,46 @@ AI assistants can use u-widgets via [MCP server](docs/mcp-server.md):
|
|
|
88
88
|
npx @iyulab/u-widgets-mcp
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
## Framework Integration
|
|
92
|
+
|
|
93
|
+
u-widgets is a browser-only Web Component library — it requires DOM APIs (`customElements`, `HTMLElement`) and cannot run in Node.js or server-side environments.
|
|
94
|
+
|
|
95
|
+
### Next.js (App Router)
|
|
96
|
+
|
|
97
|
+
Create a client-side wrapper component:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
// components/widget.tsx
|
|
101
|
+
"use client";
|
|
102
|
+
import "@iyulab/u-widgets";
|
|
103
|
+
|
|
104
|
+
export function Widget({ spec }: { spec: object }) {
|
|
105
|
+
return <u-widget spec={JSON.stringify(spec)} />;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Use the wrapper from Server Components:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
// app/dashboard/page.tsx
|
|
113
|
+
import { Widget } from "@/components/widget";
|
|
114
|
+
|
|
115
|
+
export default async function Page() {
|
|
116
|
+
const data = await fetchData();
|
|
117
|
+
return <Widget spec={{ widget: "stat-group", data }} />;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For pages where SSR hydration mismatch is a concern, use dynamic import:
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import dynamic from "next/dynamic";
|
|
125
|
+
const Widget = dynamic(
|
|
126
|
+
() => import("@/components/widget").then((m) => m.Widget),
|
|
127
|
+
{ ssr: false }
|
|
128
|
+
);
|
|
129
|
+
```
|
|
130
|
+
|
|
91
131
|
## Documentation
|
|
92
132
|
|
|
93
133
|
- [Widget Reference](docs/widgets.md) — Schema, mapping, options, theming
|
package/dist/u-widgets-charts.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { css as V, LitElement as I, nothing as P, html as E } from "lit";
|
|
2
2
|
import { property as R, customElement as T } from "lit/decorators.js";
|
|
3
3
|
import { a as D, t as $ } from "./tokens-x1kDxgG8.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as N from "echarts/core";
|
|
5
5
|
import { BarChart as B, LineChart as q, PieChart as G, ScatterChart as H, RadarChart as K, HeatmapChart as U, BoxplotChart as W, FunnelChart as J, TreemapChart as Q } from "echarts/charts";
|
|
6
6
|
import { GridComponent as X, TooltipComponent as Y, LegendComponent as Z, RadarComponent as ee, MarkLineComponent as te, VisualMapComponent as re } from "echarts/components";
|
|
7
7
|
import { CanvasRenderer as se } from "echarts/renderers";
|
|
@@ -54,103 +54,109 @@ function F(e, t, i, r) {
|
|
|
54
54
|
if (!Array.isArray(e)) return {};
|
|
55
55
|
const n = t?.x ?? C(e), s = t?.y ?? [k(e)].filter(Boolean);
|
|
56
56
|
if (!n || s.length === 0) return {};
|
|
57
|
-
const c = e.map((
|
|
58
|
-
const
|
|
59
|
-
name:
|
|
57
|
+
const c = e.map((l) => String(l[n] ?? "")), u = !!r.horizontal, f = Array.isArray(r.series) ? r.series : [], y = s.map((l, x) => {
|
|
58
|
+
const o = {
|
|
59
|
+
name: l,
|
|
60
60
|
type: i,
|
|
61
|
-
data: e.map((
|
|
61
|
+
data: e.map((h) => h[l] ?? null)
|
|
62
62
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
r._area && (o.areaStyle = {}), r.smooth && (o.smooth = !0), r.step && (o.step = r.step === !0 ? "end" : r.step);
|
|
64
|
+
const a = f[x];
|
|
65
|
+
return a && (a.color && (o.itemStyle = { color: a.color }, o.lineStyle = { ...o.lineStyle ?? {}, color: a.color }), a.lineStyle && (o.lineStyle = { ...o.lineStyle ?? {}, ...a.lineStyle }), a.symbol !== void 0 && (o.symbol = a.symbol), a.label && (o.name = a.label)), o;
|
|
66
|
+
}), b = { type: "category", data: c }, p = { type: "value" };
|
|
67
|
+
r.histogram && (b.axisTick = { alignWithLabel: !0 }, y.forEach((l) => {
|
|
68
|
+
l.barCategoryGap = "0%";
|
|
67
69
|
}));
|
|
68
|
-
const
|
|
69
|
-
xAxis: u ?
|
|
70
|
-
yAxis: u ?
|
|
71
|
-
series:
|
|
70
|
+
const g = {
|
|
71
|
+
xAxis: u ? p : b,
|
|
72
|
+
yAxis: u ? b : p,
|
|
73
|
+
series: y,
|
|
72
74
|
tooltip: { trigger: "axis" }
|
|
73
75
|
};
|
|
74
|
-
s.length > 1
|
|
75
|
-
|
|
76
|
+
if (s.length > 1) {
|
|
77
|
+
const l = y.map((x) => x.name);
|
|
78
|
+
g.legend = { data: l };
|
|
79
|
+
}
|
|
80
|
+
r.stack && g.series.forEach((l) => {
|
|
81
|
+
l.stack = "total";
|
|
76
82
|
});
|
|
77
|
-
const
|
|
78
|
-
return Array.isArray(
|
|
83
|
+
const m = r.referenceLines;
|
|
84
|
+
return Array.isArray(m) && m.length > 0 && y.length > 0 && (y[0].markLine = {
|
|
79
85
|
silent: !0,
|
|
80
86
|
symbol: "none",
|
|
81
|
-
data:
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
return
|
|
87
|
+
data: m.map((l) => {
|
|
88
|
+
const x = {};
|
|
89
|
+
l.axis === "x" ? x.xAxis = l.value : x.yAxis = l.value, l.label && (x.name = l.label);
|
|
90
|
+
const o = {};
|
|
91
|
+
return l.color && (o.color = l.color), l.style && (o.type = l.style), Object.keys(o).length > 0 && (x.lineStyle = o), l.label && (x.label = { formatter: l.label, position: "end" }), x;
|
|
86
92
|
})
|
|
87
|
-
}),
|
|
93
|
+
}), g;
|
|
88
94
|
}
|
|
89
95
|
function ne(e, t, i) {
|
|
90
96
|
if (!Array.isArray(e)) return {};
|
|
91
|
-
const r = j(e), n = t?.x ?? r[0], s = (t?.y ?? [r[1]])[0], c = t?.color, u = t?.size,
|
|
97
|
+
const r = j(e), n = t?.x ?? r[0], s = (t?.y ?? [r[1]])[0], c = t?.color, u = t?.size, f = t?.opacity;
|
|
92
98
|
if (!n || !s) return {};
|
|
93
|
-
const
|
|
99
|
+
const y = {
|
|
94
100
|
xAxis: { type: "value" },
|
|
95
101
|
yAxis: { type: "value" },
|
|
96
102
|
tooltip: { trigger: "item" }
|
|
97
103
|
};
|
|
98
|
-
let
|
|
99
|
-
if (
|
|
100
|
-
for (const
|
|
101
|
-
const
|
|
102
|
-
|
|
104
|
+
let b = 1 / 0, p = -1 / 0;
|
|
105
|
+
if (f)
|
|
106
|
+
for (const o of e) {
|
|
107
|
+
const a = Number(o[f] ?? 0);
|
|
108
|
+
a < b && (b = a), a > p && (p = a);
|
|
103
109
|
}
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
if (u &&
|
|
107
|
-
const
|
|
108
|
-
return { value:
|
|
110
|
+
const g = p - b || 1, m = (o) => {
|
|
111
|
+
const a = [Number(o[n] ?? 0), Number(o[s] ?? 0)];
|
|
112
|
+
if (u && a.push(Number(o[u] ?? 0)), f) {
|
|
113
|
+
const S = 0.1 + 0.9 * ((Number(o[f] ?? 0) - b) / g);
|
|
114
|
+
return { value: a, itemStyle: { opacity: Math.round(S * 100) / 100 } };
|
|
109
115
|
}
|
|
110
|
-
return
|
|
111
|
-
},
|
|
112
|
-
const
|
|
113
|
-
return Math.max(4, Math.min(60, Math.sqrt(
|
|
116
|
+
return a;
|
|
117
|
+
}, l = u ? (o) => {
|
|
118
|
+
const h = (Array.isArray(o) ? o : o.value)[2] ?? 0;
|
|
119
|
+
return Math.max(4, Math.min(60, Math.sqrt(h) * 4));
|
|
114
120
|
} : void 0;
|
|
115
121
|
if (c) {
|
|
116
|
-
const
|
|
117
|
-
for (const
|
|
118
|
-
const
|
|
119
|
-
|
|
122
|
+
const o = /* @__PURE__ */ new Map();
|
|
123
|
+
for (const h of e) {
|
|
124
|
+
const S = String(h[c] ?? "unknown");
|
|
125
|
+
o.has(S) || o.set(S, []), o.get(S).push(m(h));
|
|
120
126
|
}
|
|
121
|
-
const
|
|
122
|
-
for (const [
|
|
123
|
-
const
|
|
124
|
-
|
|
127
|
+
const a = [];
|
|
128
|
+
for (const [h, S] of o) {
|
|
129
|
+
const d = { name: h, type: "scatter", data: S };
|
|
130
|
+
l && (d.symbolSize = l), a.push(d);
|
|
125
131
|
}
|
|
126
|
-
|
|
132
|
+
y.series = a, y.legend = { data: Array.from(o.keys()) };
|
|
127
133
|
} else {
|
|
128
|
-
const
|
|
129
|
-
|
|
134
|
+
const a = { type: "scatter", data: e.map((h) => m(h)) };
|
|
135
|
+
l && (a.symbolSize = l), y.series = [a];
|
|
130
136
|
}
|
|
131
|
-
const
|
|
132
|
-
if (Array.isArray(
|
|
133
|
-
const
|
|
134
|
-
|
|
137
|
+
const x = i.referenceLines;
|
|
138
|
+
if (Array.isArray(x) && x.length > 0) {
|
|
139
|
+
const o = y.series[0];
|
|
140
|
+
o.markLine = {
|
|
135
141
|
silent: !0,
|
|
136
142
|
symbol: "none",
|
|
137
|
-
data:
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
return
|
|
143
|
+
data: x.map((a) => {
|
|
144
|
+
const h = {};
|
|
145
|
+
a.axis === "x" ? h.xAxis = a.value : h.yAxis = a.value, a.label && (h.name = a.label);
|
|
146
|
+
const S = {};
|
|
147
|
+
return a.color && (S.color = a.color), a.style && (S.type = a.style), Object.keys(S).length > 0 && (h.lineStyle = S), a.label && (h.label = { formatter: a.label, position: "end" }), h;
|
|
142
148
|
})
|
|
143
149
|
};
|
|
144
150
|
}
|
|
145
|
-
return
|
|
151
|
+
return y;
|
|
146
152
|
}
|
|
147
153
|
function ae(e, t, i) {
|
|
148
154
|
if (!Array.isArray(e)) return {};
|
|
149
155
|
const r = t?.label ?? C(e), n = t?.value ?? k(e);
|
|
150
156
|
if (!r || !n) return {};
|
|
151
|
-
const s = e.map((
|
|
152
|
-
name: String(
|
|
153
|
-
value: Number(
|
|
157
|
+
const s = e.map((f) => ({
|
|
158
|
+
name: String(f[r] ?? ""),
|
|
159
|
+
value: Number(f[n] ?? 0)
|
|
154
160
|
})), u = {
|
|
155
161
|
type: "pie",
|
|
156
162
|
radius: i.donut ? ["40%", "70%"] : "50%",
|
|
@@ -171,7 +177,7 @@ function oe(e, t, i) {
|
|
|
171
177
|
name: String(u[r] ?? "")
|
|
172
178
|
})), c = n.map((u) => ({
|
|
173
179
|
name: u,
|
|
174
|
-
value: e.map((
|
|
180
|
+
value: e.map((f) => Number(f[u] ?? 0))
|
|
175
181
|
}));
|
|
176
182
|
return {
|
|
177
183
|
tooltip: {},
|
|
@@ -187,73 +193,73 @@ function oe(e, t, i) {
|
|
|
187
193
|
}
|
|
188
194
|
function le(e, t, i) {
|
|
189
195
|
if (!Array.isArray(e)) return {};
|
|
190
|
-
const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((
|
|
191
|
-
if (!u || !
|
|
192
|
-
const
|
|
193
|
-
for (const
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
+
const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((d) => typeof r[d] == "string"), c = n.filter((d) => typeof r[d] == "number"), u = t?.x ?? s[0], f = t?.y?.[0] ?? s.find((d) => d !== u), y = t?.value ?? c[0];
|
|
197
|
+
if (!u || !f || !y) return {};
|
|
198
|
+
const b = [], p = [], g = /* @__PURE__ */ new Set(), m = /* @__PURE__ */ new Set();
|
|
199
|
+
for (const d of e) {
|
|
200
|
+
const A = String(d[u] ?? ""), w = String(d[f] ?? "");
|
|
201
|
+
g.has(A) || (g.add(A), b.push(A)), m.has(w) || (m.add(w), p.push(w));
|
|
196
202
|
}
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
let
|
|
203
|
-
for (const
|
|
204
|
-
const
|
|
205
|
-
|
|
203
|
+
const l = /* @__PURE__ */ new Map();
|
|
204
|
+
b.forEach((d, A) => l.set(d, A));
|
|
205
|
+
const x = /* @__PURE__ */ new Map();
|
|
206
|
+
p.forEach((d, A) => x.set(d, A));
|
|
207
|
+
const o = [];
|
|
208
|
+
let a = 1 / 0, h = -1 / 0;
|
|
209
|
+
for (const d of e) {
|
|
210
|
+
const A = l.get(String(d[u] ?? "")) ?? 0, w = x.get(String(d[f] ?? "")) ?? 0, v = d[y] != null ? Number(d[y]) : null;
|
|
211
|
+
o.push([A, w, v]), v != null && (v < a && (a = v), v > h && (h = v));
|
|
206
212
|
}
|
|
207
|
-
isFinite(
|
|
208
|
-
const
|
|
213
|
+
isFinite(a) || (a = 0, h = 1);
|
|
214
|
+
const S = i.colorRange ?? ["#313695", "#4575b4", "#74add1", "#abd9e9", "#fee090", "#fdae61", "#f46d43", "#d73027"];
|
|
209
215
|
return {
|
|
210
|
-
xAxis: { type: "category", data:
|
|
211
|
-
yAxis: { type: "category", data:
|
|
216
|
+
xAxis: { type: "category", data: b, splitArea: { show: !0 } },
|
|
217
|
+
yAxis: { type: "category", data: p, splitArea: { show: !0 } },
|
|
212
218
|
visualMap: {
|
|
213
|
-
min: i.min != null ? Number(i.min) :
|
|
214
|
-
max: i.max != null ? Number(i.max) :
|
|
219
|
+
min: i.min != null ? Number(i.min) : a,
|
|
220
|
+
max: i.max != null ? Number(i.max) : h,
|
|
215
221
|
calculable: !0,
|
|
216
222
|
orient: "horizontal",
|
|
217
223
|
left: "center",
|
|
218
224
|
bottom: 0,
|
|
219
|
-
inRange: { color:
|
|
225
|
+
inRange: { color: S }
|
|
220
226
|
},
|
|
221
227
|
tooltip: {
|
|
222
228
|
trigger: "item",
|
|
223
|
-
formatter: (
|
|
224
|
-
const
|
|
225
|
-
return
|
|
229
|
+
formatter: (d) => {
|
|
230
|
+
const A = d.data;
|
|
231
|
+
return A ? `${b[A[0]]} × ${p[A[1]]}: ${A[2] != null ? A[2] : "-"}` : "";
|
|
226
232
|
}
|
|
227
233
|
},
|
|
228
234
|
grid: { bottom: 60 },
|
|
229
235
|
series: [{
|
|
230
236
|
type: "heatmap",
|
|
231
|
-
data:
|
|
237
|
+
data: o,
|
|
232
238
|
label: { show: i.showLabel !== !1 }
|
|
233
239
|
}]
|
|
234
240
|
};
|
|
235
241
|
}
|
|
236
242
|
function ce(e, t, i) {
|
|
237
243
|
if (!Array.isArray(e) || e.length === 0) return {};
|
|
238
|
-
const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((
|
|
239
|
-
let
|
|
244
|
+
const r = e[0] ?? {}, n = Object.keys(r), s = n.filter((g) => typeof r[g] == "string"), c = n.filter((g) => typeof r[g] == "number"), u = t?.x ?? s[0];
|
|
245
|
+
let f;
|
|
240
246
|
if (t?.y && t.y.length >= 5)
|
|
241
|
-
|
|
247
|
+
f = t.y.slice(0, 5);
|
|
242
248
|
else {
|
|
243
|
-
const
|
|
244
|
-
|
|
249
|
+
const m = ["min", "q1", "median", "q3", "max"].filter((l) => c.includes(l));
|
|
250
|
+
f = m.length === 5 ? m : c.slice(0, 5);
|
|
245
251
|
}
|
|
246
|
-
if (
|
|
247
|
-
const
|
|
248
|
-
(
|
|
249
|
-
),
|
|
252
|
+
if (f.length < 5) return {};
|
|
253
|
+
const y = u ? e.map((g) => String(g[u] ?? "")) : void 0, b = e.map(
|
|
254
|
+
(g) => f.map((m) => Number(g[m] ?? 0))
|
|
255
|
+
), p = {
|
|
250
256
|
tooltip: { trigger: "item" },
|
|
251
257
|
series: [{
|
|
252
258
|
type: "boxplot",
|
|
253
|
-
data:
|
|
259
|
+
data: b
|
|
254
260
|
}]
|
|
255
261
|
};
|
|
256
|
-
return
|
|
262
|
+
return y ? (p.xAxis = { type: "category", data: y }, p.yAxis = { type: "value" }) : (p.xAxis = { type: "category" }, p.yAxis = { type: "value" }), p;
|
|
257
263
|
}
|
|
258
264
|
function C(e) {
|
|
259
265
|
if (e.length === 0) return;
|
|
@@ -289,11 +295,11 @@ function fe(e, t, i) {
|
|
|
289
295
|
if (!Array.isArray(e)) return {};
|
|
290
296
|
const r = e, n = t?.x ?? C(r), s = (t?.y ?? [k(r)])[0];
|
|
291
297
|
if (!n || !s) return {};
|
|
292
|
-
const c = [], u = [],
|
|
293
|
-
let
|
|
294
|
-
for (const
|
|
295
|
-
const
|
|
296
|
-
c.push(
|
|
298
|
+
const c = [], u = [], f = [], y = [];
|
|
299
|
+
let b = 0;
|
|
300
|
+
for (const p of r) {
|
|
301
|
+
const g = String(p[n] ?? ""), m = Number(p[s] ?? 0);
|
|
302
|
+
c.push(g), m >= 0 ? (u.push(b), f.push(m), y.push(null)) : (u.push(b + m), f.push(null), y.push(Math.abs(m))), b += m;
|
|
297
303
|
}
|
|
298
304
|
return {
|
|
299
305
|
tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
|
|
@@ -312,20 +318,20 @@ function fe(e, t, i) {
|
|
|
312
318
|
name: "Positive",
|
|
313
319
|
type: "bar",
|
|
314
320
|
stack: "waterfall",
|
|
315
|
-
data:
|
|
321
|
+
data: f
|
|
316
322
|
},
|
|
317
323
|
{
|
|
318
324
|
name: "Negative",
|
|
319
325
|
type: "bar",
|
|
320
326
|
stack: "waterfall",
|
|
321
|
-
data:
|
|
327
|
+
data: y
|
|
322
328
|
}
|
|
323
329
|
]
|
|
324
330
|
};
|
|
325
331
|
}
|
|
326
332
|
function he(e, t) {
|
|
327
333
|
if (!Array.isArray(e)) return {};
|
|
328
|
-
const i = e.map((r) =>
|
|
334
|
+
const i = e.map((r) => z(r));
|
|
329
335
|
return {
|
|
330
336
|
tooltip: { trigger: "item" },
|
|
331
337
|
series: [{
|
|
@@ -337,12 +343,12 @@ function he(e, t) {
|
|
|
337
343
|
}]
|
|
338
344
|
};
|
|
339
345
|
}
|
|
340
|
-
function
|
|
346
|
+
function z(e) {
|
|
341
347
|
const t = {
|
|
342
348
|
name: String(e.name ?? ""),
|
|
343
349
|
value: Number(e.value ?? 0)
|
|
344
350
|
};
|
|
345
|
-
return Array.isArray(e.children) && (t.children = e.children.map((i) =>
|
|
351
|
+
return Array.isArray(e.children) && (t.children = e.children.map((i) => z(i))), t;
|
|
346
352
|
}
|
|
347
353
|
function j(e) {
|
|
348
354
|
if (e.length === 0) return [];
|
|
@@ -365,7 +371,7 @@ var ye = Object.defineProperty, de = Object.getOwnPropertyDescriptor, M = (e, t,
|
|
|
365
371
|
(c = e[s]) && (n = (r ? c(t, i, n) : c(n)) || n);
|
|
366
372
|
return r && n && ye(t, i, n), n;
|
|
367
373
|
};
|
|
368
|
-
|
|
374
|
+
N.use([
|
|
369
375
|
B,
|
|
370
376
|
q,
|
|
371
377
|
G,
|
|
@@ -401,7 +407,7 @@ let _ = class extends I {
|
|
|
401
407
|
_initChart() {
|
|
402
408
|
if (!(!this._container || !this.spec))
|
|
403
409
|
try {
|
|
404
|
-
this._chart =
|
|
410
|
+
this._chart = N.init(this._container), this._chart.on("click", (e) => {
|
|
405
411
|
this._onChartClick(e);
|
|
406
412
|
}), this._updateChart();
|
|
407
413
|
} catch (e) {
|