@tsingroc/tsingroc-components 5.0.0-alpha.12 → 5.0.0-alpha.14

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.
@@ -15,7 +15,5 @@ export declare const withAutoResize: EChartsHOCType;
15
15
  *
16
16
  * @see {@linkcode withAutoResize}
17
17
  */
18
- declare const AutoResizedECharts: import("./ECharts").EChartsComponentType<{}> & {
19
- displayName: string;
20
- };
18
+ declare const AutoResizedECharts: import("./ECharts").EChartsComponentType<{}>;
21
19
  export default AutoResizedECharts;
@@ -14,7 +14,7 @@ import EChartsInstance from "./ECharts";
14
14
  * `minmax(..., ...fr)` 而不可直接使用 `fr`。不这么做会导致图像只能放大而无法缩小。
15
15
  */
16
16
  import { jsx as _jsx } from "react/jsx-runtime";
17
- export const withAutoResize = ECharts => props => {
17
+ export const withAutoResize = ECharts => function AutoResizedECharts(props) {
18
18
  "use memo";
19
19
 
20
20
  const $ = _c(9);
@@ -92,7 +92,5 @@ export const withAutoResize = ECharts => props => {
92
92
  *
93
93
  * @see {@linkcode withAutoResize}
94
94
  */
95
- const AutoResizedECharts = Object.assign(withAutoResize(EChartsInstance), {
96
- displayName: "AutoResizedECharts"
97
- });
95
+ const AutoResizedECharts = withAutoResize(EChartsInstance);
98
96
  export default AutoResizedECharts;
@@ -1,6 +1,5 @@
1
- import * as echarts from "echarts/core";
2
1
  import { type ReactNode } from "react";
3
- import type { EChartsHOCType, EChartsProps } from "./ECharts";
2
+ import type { EChartsHOCType } from "./ECharts";
4
3
  /**
5
4
  * 为 {@linkcode ConnectedECharts}/{@linkcode withConnector | withConnector(ECharts)}
6
5
  * 提供联动上下文,只有同一个上下文内的 ECharts 会联动。
@@ -23,9 +22,7 @@ export declare const withConnector: EChartsHOCType<{
23
22
  * @see {@linkcode withConnector}
24
23
  * @see {@linkcode withAutoResize}
25
24
  */
26
- declare const ConnectedECharts: import("./ECharts").EChartsComponentType<EChartsProps<echarts.EChartsCoreOption> & {
25
+ declare const ConnectedECharts: import("./ECharts").EChartsComponentType<{
27
26
  group?: string;
28
- }> & {
29
- displayName: string;
30
- };
27
+ }>;
31
28
  export default ConnectedECharts;
@@ -36,7 +36,7 @@ export function EChartsConnector(t0) {
36
36
  * 可以使用 {@linkcode EChartsConnector} 将同一个页面上的 ECharts
37
37
  * 划分为多个组,不同组的 ECharts 不会联动。也可以使用 `group` 属性手动指定联动组。
38
38
  */
39
- export const withConnector = ECharts => props => {
39
+ export const withConnector = ECharts => function ConnectedECharts(props) {
40
40
  "use memo";
41
41
 
42
42
  const $ = _c(10);
@@ -94,7 +94,5 @@ export const withConnector = ECharts => props => {
94
94
  * @see {@linkcode withConnector}
95
95
  * @see {@linkcode withAutoResize}
96
96
  */
97
- const ConnectedECharts = Object.assign(withConnector(AutoResizedECharts), {
98
- displayName: "ConnectedECharts"
99
- });
97
+ const ConnectedECharts = withConnector(AutoResizedECharts);
100
98
  export default ConnectedECharts;
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
- import type { EChartsHOCType, EChartsProps } from "./ECharts";
2
+ import type { EChartsHOCType } from "./ECharts";
3
3
  /**
4
4
  * 为 {@linkcode LeftAlignedECharts} 和
5
5
  * {@linkcode withLeftAlign | withLeftAlign(ECharts)}
@@ -34,9 +34,7 @@ export declare const withLeftAlign: EChartsHOCType;
34
34
  * @see {@linkcode withConnector}
35
35
  * @see {@linkcode withAutoResize}
36
36
  */
37
- declare const LeftAlignedECharts: import("./ECharts").EChartsComponentType<EChartsProps<import("echarts/core").EChartsCoreOption> & {
37
+ declare const LeftAlignedECharts: import("./ECharts").EChartsComponentType<{
38
38
  group?: string;
39
- }> & {
40
- displayName: string;
41
- };
39
+ }>;
42
40
  export default LeftAlignedECharts;
@@ -116,7 +116,7 @@ function getLabelsWidth(instance) {
116
116
  * - grid 坐标系的 `left` 属性会被该组件覆盖,最终效果总是会使得纵轴标签最宽的坐标系的标签紧贴容器左边缘(即 `left === 0`)。
117
117
  * - 左对齐时原本的过渡动画会被打断。
118
118
  */
119
- export const withLeftAlign = ECharts => props => {
119
+ export const withLeftAlign = ECharts => function LeftAlignedECharts(props) {
120
120
  "use memo";
121
121
 
122
122
  const $ = _c(27);
@@ -264,7 +264,5 @@ export const withLeftAlign = ECharts => props => {
264
264
  * @see {@linkcode withConnector}
265
265
  * @see {@linkcode withAutoResize}
266
266
  */
267
- const LeftAlignedECharts = Object.assign(withLeftAlign(ConnectedECharts), {
268
- displayName: "LeftAlignedECharts"
269
- });
267
+ const LeftAlignedECharts = withLeftAlign(ConnectedECharts);
270
268
  export default LeftAlignedECharts;
@@ -0,0 +1,22 @@
1
+ import type { MarkAreaComponentOption } from "echarts";
2
+ import type { ZRStyleProps } from "echarts/types/src/util/types.js";
3
+ import { type EChartsHOCType } from "./ECharts";
4
+ export interface SelectableEChartsProps {
5
+ /** 编辑器的选中方式。 @default "add" */
6
+ mode?: "add" | "subtract";
7
+ /** 可选中的系列名,若为 `undefined` 则均不可选中。(如果需要选中多个系列,可以嵌套多层 `withSelectable`) */
8
+ seriesName?: string;
9
+ /** 选中的数据点下标集合。 @default new Set() */
10
+ selectedIndices?: Set<number>;
11
+ /** 选中区域变化时的回调。 */
12
+ onSelectedIndicesChange?: (selectedIndices: Set<number>) => void;
13
+ /** 选框的样式,可使用 `fill` 和 `stroke` 修改颜色。 */
14
+ selectionBoxStyle?: Partial<ZRStyleProps>;
15
+ /** 是否用有色背景高亮选中点在 x 轴上的投影区域。只有 x 轴数值为 `number` 类型的点才能被高亮。 */
16
+ markArea?: boolean;
17
+ /** 每个点高亮背景的宽度。如果不填,默认为取相邻两点间距的最小值(x 轴数值必须为 `number` 类型)。 */
18
+ markAreaWidth?: number;
19
+ /** 高亮区域的样式,可使用 `color` 修改颜色。 */
20
+ markAreaStyle?: MarkAreaComponentOption["itemStyle"];
21
+ }
22
+ export declare const withSelectable: EChartsHOCType<SelectableEChartsProps>;
@@ -0,0 +1,402 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { GraphicComponent, MarkAreaComponent } from "echarts/components";
3
+ import * as echarts from "echarts/core";
4
+ import { useEffectEvent, useState } from "react";
5
+ import { debugAssert } from "../utils";
6
+ import { destructureLineDataItem } from "../utils/destructureLineDataItem";
7
+ import { normalizeIntoArray } from "../utils/normalizeIntoArray";
8
+ import "./ECharts";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const DEFAULT_SELECTED_INDICES = new Set();
11
+ const DEFAULT_SELECTION_BOX_STYLE = {
12
+ fill: "#000",
13
+ fillOpacity: 16 / 255,
14
+ stroke: "#000",
15
+ strokeOpacity: 176 / 255,
16
+ lineWidth: 1
17
+ };
18
+ const DEFAULT_MARK_AREA_STYLE = {
19
+ color: "#000",
20
+ opacity: 16 / 255
21
+ };
22
+ export const withSelectable = ECharts => function SelectableECharts(props) {
23
+ "use memo";
24
+
25
+ const $ = _c(31);
26
+ let inputMarkAreaWidth;
27
+ let inputOption;
28
+ let markArea;
29
+ let markAreaStyle;
30
+ let onInit;
31
+ let onSelectedIndicesChange;
32
+ let rest;
33
+ let selectionBoxStyle;
34
+ let seriesName;
35
+ let t0;
36
+ let t1;
37
+ if ($[0] !== props) {
38
+ ({
39
+ option: inputOption,
40
+ onInit,
41
+ mode: t0,
42
+ seriesName,
43
+ selectedIndices: t1,
44
+ onSelectedIndicesChange,
45
+ selectionBoxStyle,
46
+ markArea,
47
+ markAreaStyle,
48
+ markAreaWidth: inputMarkAreaWidth,
49
+ ...rest
50
+ } = props);
51
+ $[0] = props;
52
+ $[1] = inputMarkAreaWidth;
53
+ $[2] = inputOption;
54
+ $[3] = markArea;
55
+ $[4] = markAreaStyle;
56
+ $[5] = onInit;
57
+ $[6] = onSelectedIndicesChange;
58
+ $[7] = rest;
59
+ $[8] = selectionBoxStyle;
60
+ $[9] = seriesName;
61
+ $[10] = t0;
62
+ $[11] = t1;
63
+ } else {
64
+ inputMarkAreaWidth = $[1];
65
+ inputOption = $[2];
66
+ markArea = $[3];
67
+ markAreaStyle = $[4];
68
+ onInit = $[5];
69
+ onSelectedIndicesChange = $[6];
70
+ rest = $[7];
71
+ selectionBoxStyle = $[8];
72
+ seriesName = $[9];
73
+ t0 = $[10];
74
+ t1 = $[11];
75
+ }
76
+ const mode = t0 === undefined ? "add" : t0;
77
+ const selectedIndices = t1 === undefined ? DEFAULT_SELECTED_INDICES : t1;
78
+ echarts.use(GraphicComponent);
79
+ echarts.use(MarkAreaComponent);
80
+ const inputSeriesArray = normalizeIntoArray(inputOption?.series);
81
+ let t2;
82
+ if ($[12] !== seriesName) {
83
+ t2 = it => it.name === seriesName;
84
+ $[12] = seriesName;
85
+ $[13] = t2;
86
+ } else {
87
+ t2 = $[13];
88
+ }
89
+ const inputSeries = inputSeriesArray.find(t2);
90
+ if (inputSeries && inputSeries.type !== "line") {
91
+ throw new Error("only line series is supported");
92
+ }
93
+ const inputTooltip = normalizeIntoArray(inputOption?.tooltip);
94
+ let markAreaWidth = inputMarkAreaWidth;
95
+ if (inputSeries?.data && markArea && !markAreaWidth) {
96
+ markAreaWidth = Infinity;
97
+ const xValues = inputSeries.data.map(_temp);
98
+ for (let i = 1; i < xValues.length; i++) {
99
+ const prevX = xValues[i - 1];
100
+ const thisX = xValues[i];
101
+ if (typeof prevX === "number" && typeof thisX === "number") {
102
+ markAreaWidth = Math.min(markAreaWidth, thisX - prevX);
103
+ }
104
+ }
105
+ if (markAreaWidth === Infinity) {
106
+ throw new Error("failed to automatically determine the width of mark area; please ensure the x axis value of the data points are number-typed, or provide the width manually");
107
+ }
108
+ }
109
+ const modelMatcher = inputSeries && ((inputSeries.xAxisId || inputSeries.xAxisIndex) && (inputSeries.yAxisId || inputSeries.yAxisIndex) || inputSeries.polarId || inputSeries.polarIndex) ? inputSeries : {
110
+ gridIndex: 0
111
+ };
112
+ const convertToPixel = (instance, t3) => {
113
+ const [px, py] = t3;
114
+ return px != null && py != null ? instance.convertToPixel(modelMatcher, [px, py]) : undefined;
115
+ };
116
+ const [mouseState, setMouseState] = useState();
117
+ let t4;
118
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
119
+ t4 = (instance_0, params) => setMouseState({
120
+ instance: instance_0,
121
+ start: [params.offsetX, params.offsetY]
122
+ });
123
+ $[14] = t4;
124
+ } else {
125
+ t4 = $[14];
126
+ }
127
+ const onMouseDown = useEffectEvent(t4);
128
+ let t5;
129
+ if ($[15] !== mouseState) {
130
+ t5 = params_0 => {
131
+ if (!mouseState) {
132
+ return;
133
+ }
134
+ setMouseState({
135
+ ...mouseState,
136
+ end: [params_0.offsetX, params_0.offsetY]
137
+ });
138
+ };
139
+ $[15] = mouseState;
140
+ $[16] = t5;
141
+ } else {
142
+ t5 = $[16];
143
+ }
144
+ const onMouseMove = useEffectEvent(t5);
145
+ const onMouseUp = useEffectEvent((instance_1, params_1) => {
146
+ if (!mouseState) {
147
+ return;
148
+ }
149
+ let eventTriggered = false;
150
+ if (onSelectedIndicesChange && inputSeries?.data) {
151
+ if (mouseState.end) {
152
+ const [startX, startY] = mouseState.start;
153
+ const {
154
+ offsetX,
155
+ offsetY
156
+ } = params_1;
157
+ const [minX, maxX] = [startX, offsetX].sort(_temp2);
158
+ const [minY, maxY] = [startY, offsetY].sort(_temp3);
159
+ const newSelectedIndices = new Set(selectedIndices);
160
+ inputSeries.data.forEach((point, i_0) => {
161
+ const destructured = destructureLineDataItem(point, i_0);
162
+ if (destructured == null) {
163
+ return;
164
+ }
165
+ const pixelValue = convertToPixel(instance_1, destructured[0]);
166
+ if (pixelValue === undefined) {
167
+ return;
168
+ }
169
+ const [x, y] = pixelValue;
170
+ const selected = minX <= x && x <= maxX && minY <= y && y <= maxY;
171
+ if (selected) {
172
+ if (mode === "add") {
173
+ newSelectedIndices.add(i_0);
174
+ } else {
175
+ newSelectedIndices.delete(i_0);
176
+ }
177
+ }
178
+ });
179
+ onSelectedIndicesChange(newSelectedIndices);
180
+ eventTriggered = true;
181
+ } else {
182
+ if (instance_1.containPixel(modelMatcher, mouseState.start)) {
183
+ let minDist = Infinity;
184
+ let minIdx = -1;
185
+ inputSeries.data.forEach((point_0, i_1) => {
186
+ const destructured_0 = destructureLineDataItem(point_0, i_1);
187
+ if (destructured_0 == null) {
188
+ return;
189
+ }
190
+ const pixelValue_0 = convertToPixel(instance_1, destructured_0[0]);
191
+ if (pixelValue_0 === undefined) {
192
+ return;
193
+ }
194
+ const [x_0] = pixelValue_0;
195
+ const dist = Math.abs(mouseState.start[0] - x_0);
196
+ if (dist < minDist) {
197
+ minDist = dist;
198
+ minIdx = i_1;
199
+ }
200
+ });
201
+ if (minIdx > 0) {
202
+ const newSelectedIndices_0 = new Set(selectedIndices);
203
+ if (mode === "add") {
204
+ newSelectedIndices_0.add(minIdx);
205
+ } else {
206
+ newSelectedIndices_0.delete(minIdx);
207
+ }
208
+ onSelectedIndicesChange(newSelectedIndices_0);
209
+ eventTriggered = true;
210
+ }
211
+ }
212
+ }
213
+ }
214
+ if (!eventTriggered) {
215
+ for (let elem = params_1.target; elem; elem = elem.parent) {
216
+ if (elem._$handlers?.click) {
217
+ elem._$handlers?.click.forEach(_temp4);
218
+ }
219
+ }
220
+ }
221
+ setMouseState(undefined);
222
+ });
223
+ const option = {
224
+ ...inputOption
225
+ };
226
+ if (inputSeries) {
227
+ if (selectedIndices.size > 0 || mode === "add" && mouseState?.end) {
228
+ const series = {
229
+ ...inputSeries,
230
+ showSymbol: true
231
+ };
232
+ const allSelectedIndices = new Set();
233
+ series.data = inputSeries.data?.map((point_1, i_2) => {
234
+ const destructured_1 = destructureLineDataItem(point_1, i_2);
235
+ if (destructured_1 == null) {
236
+ return point_1;
237
+ }
238
+ const [value, option_0] = destructured_1;
239
+ const stateSelected = selectedIndices.has(i_2);
240
+ let tempSelected = false;
241
+ if (mouseState?.end) {
242
+ const [minX_0, maxX_0] = [mouseState.start[0], mouseState.end[0]].sort(_temp5);
243
+ const [minY_0, maxY_0] = [mouseState.start[1], mouseState.end[1]].sort(_temp6);
244
+ const pixelValue_1 = convertToPixel(mouseState.instance, value);
245
+ if (pixelValue_1 !== undefined) {
246
+ const [x_1, y_0] = pixelValue_1;
247
+ tempSelected = minX_0 <= x_1 && x_1 <= maxX_0 && minY_0 <= y_0 && y_0 <= maxY_0;
248
+ }
249
+ }
250
+ if (mode === "add" ? stateSelected || tempSelected : stateSelected && !tempSelected) {
251
+ allSelectedIndices.add(i_2);
252
+ return {
253
+ value,
254
+ ...option_0,
255
+ symbol: "emptyCircle",
256
+ symbolSize: 6
257
+ };
258
+ } else {
259
+ return {
260
+ value,
261
+ symbol: "none",
262
+ ...option_0
263
+ };
264
+ }
265
+ });
266
+ if (markArea) {
267
+ debugAssert(markAreaWidth !== undefined, "when markArea === true, markAreaWidth is guaranteed to be defined at the beginning of this function");
268
+ const markAreas = [];
269
+ if (inputSeries.data) {
270
+ for (const i_3 of allSelectedIndices) {
271
+ const destructured_2 = destructureLineDataItem(inputSeries.data[i_3], i_3);
272
+ if (destructured_2 == null) {
273
+ continue;
274
+ }
275
+ const [t6] = destructured_2;
276
+ const [xValue] = t6;
277
+ if (typeof xValue !== "number") {
278
+ continue;
279
+ }
280
+ markAreas.push([{
281
+ coord: [xValue - markAreaWidth / 2]
282
+ }, {
283
+ coord: [xValue + markAreaWidth / 2]
284
+ }]);
285
+ }
286
+ }
287
+ series.markArea = {
288
+ itemStyle: {
289
+ ...DEFAULT_MARK_AREA_STYLE,
290
+ ...markAreaStyle
291
+ },
292
+ emphasis: {
293
+ disabled: true
294
+ },
295
+ data: markAreas
296
+ };
297
+ }
298
+ const seriesArray = [...inputSeriesArray];
299
+ seriesArray[seriesArray.indexOf(inputSeries)] = series;
300
+ option.series = seriesArray;
301
+ }
302
+ }
303
+ let t6;
304
+ if ($[17] !== selectionBoxStyle) {
305
+ t6 = {
306
+ ...DEFAULT_SELECTION_BOX_STYLE,
307
+ ...selectionBoxStyle
308
+ };
309
+ $[17] = selectionBoxStyle;
310
+ $[18] = t6;
311
+ } else {
312
+ t6 = $[18];
313
+ }
314
+ let t7;
315
+ if ($[19] !== mouseState) {
316
+ t7 = mouseState?.end ? {
317
+ ignore: false,
318
+ shape: {
319
+ x: mouseState.start[0],
320
+ y: mouseState.start[1],
321
+ width: mouseState.end[0] - mouseState.start[0],
322
+ height: mouseState.end[1] - mouseState.start[1]
323
+ }
324
+ } : {
325
+ ignore: true
326
+ };
327
+ $[19] = mouseState;
328
+ $[20] = t7;
329
+ } else {
330
+ t7 = $[20];
331
+ }
332
+ let t8;
333
+ if ($[21] !== t6 || $[22] !== t7) {
334
+ t8 = {
335
+ id: "selectionBox",
336
+ type: "rect",
337
+ z: 1000,
338
+ style: t6,
339
+ ...t7
340
+ };
341
+ $[21] = t6;
342
+ $[22] = t7;
343
+ $[23] = t8;
344
+ } else {
345
+ t8 = $[23];
346
+ }
347
+ option.graphic = [...normalizeIntoArray(option.graphic), t8];
348
+ if (inputTooltip.length) {
349
+ let t9;
350
+ if ($[24] !== mouseState?.end) {
351
+ t9 = it_1 => ({
352
+ ...it_1,
353
+ show: mouseState?.end === undefined
354
+ });
355
+ $[24] = mouseState?.end;
356
+ $[25] = t9;
357
+ } else {
358
+ t9 = $[25];
359
+ }
360
+ option.tooltip = inputTooltip.map(t9);
361
+ }
362
+ let t9;
363
+ if ($[26] !== onInit || $[27] !== onMouseDown || $[28] !== onMouseMove || $[29] !== onMouseUp) {
364
+ t9 = instance_2 => {
365
+ const zr = instance_2.getZr();
366
+ zr.on("mousedown", params_2 => onMouseDown(instance_2, params_2));
367
+ zr.on("mousemove", onMouseMove);
368
+ zr.on("mouseup", params_3 => onMouseUp(instance_2, params_3));
369
+ return onInit?.(instance_2);
370
+ };
371
+ $[26] = onInit;
372
+ $[27] = onMouseDown;
373
+ $[28] = onMouseMove;
374
+ $[29] = onMouseUp;
375
+ $[30] = t9;
376
+ } else {
377
+ t9 = $[30];
378
+ }
379
+ return /*#__PURE__*/_jsx(ECharts, {
380
+ option: option,
381
+ onInit: t9,
382
+ ...rest
383
+ });
384
+ };
385
+ function _temp(item, idx) {
386
+ return destructureLineDataItem(item, idx)?.[0][0];
387
+ }
388
+ function _temp2(a, b) {
389
+ return a - b;
390
+ }
391
+ function _temp3(a_0, b_0) {
392
+ return a_0 - b_0;
393
+ }
394
+ function _temp4(it_0) {
395
+ return it_0.h();
396
+ }
397
+ function _temp5(a_1, b_1) {
398
+ return a_1 - b_1;
399
+ }
400
+ function _temp6(a_2, b_2) {
401
+ return a_2 - b_2;
402
+ }
@@ -9,10 +9,11 @@ export function grid(option) {
9
9
  echarts.use(GridComponent);
10
10
  const grid = {
11
11
  left: 0,
12
- right: 0,
13
- top: 24,
12
+ right: 1,
13
+ top: 1,
14
14
  bottom: 0,
15
- containLabel: true,
15
+ outerBoundsContain: "all",
16
+ outerBoundsMode: "same",
16
17
  ...option.option
17
18
  };
18
19
  const xAxis = {
@@ -5,7 +5,7 @@ export function legend(option) {
5
5
  echarts.use(LegendComponent);
6
6
  return {
7
7
  legend: [{
8
- top: 0,
8
+ top: 1,
9
9
  right: 0,
10
10
  padding: 0,
11
11
  data: option.data,
@@ -10,9 +10,13 @@ import * as echarts from "echarts/core";
10
10
  *
11
11
  * [1]: https://echarts.apache.org/zh/option.html#tooltip
12
12
  */
13
- export function tooltip(option = {}) {
13
+ export function tooltip(option) {
14
14
  echarts.use(TooltipComponent);
15
15
  return {
16
- tooltip: [option]
16
+ tooltip: [{
17
+ trigger: "axis",
18
+ transitionDuration: 0,
19
+ ...option
20
+ }]
17
21
  };
18
22
  }
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export { default as LineChartTable, type LineChartTableProps, } from "./componen
13
13
  export { default as LinkedLineChart, LineChartLinkProvider, type LinkedLineChartProps, type LineChartLinkProviderProps, } from "./components/LinkedLineChart";
14
14
  export { default as QuickDateRangePicker, type QuickDateRangePickerProps, } from "./components/QuickDateRangePicker";
15
15
  export { default as SegmentedButtons, TimeUnitSwitcher, type TimeUnitSwitcherProps, } from "./components/SegmentedButtons";
16
+ export { withSelectable, type SelectableEChartsProps, } from "./components/SelectableECharts";
16
17
  export { default as Sidebar, type SidebarProps } from "./components/Sidebar";
17
18
  export { default as TsingrocDatePicker, type DatePickerProps, } from "./components/TsingrocDatePicker";
18
19
  export { default as TsingrocTheme, type TsingrocThemeProps, } from "./components/TsingrocTheme";
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ export { default as LineChartTable } from "./components/LineChartTable";
13
13
  export { default as LinkedLineChart, LineChartLinkProvider } from "./components/LinkedLineChart";
14
14
  export { default as QuickDateRangePicker } from "./components/QuickDateRangePicker";
15
15
  export { default as SegmentedButtons, TimeUnitSwitcher } from "./components/SegmentedButtons";
16
+ export { withSelectable } from "./components/SelectableECharts";
16
17
  export { default as Sidebar } from "./components/Sidebar";
17
18
  export { default as TsingrocDatePicker } from "./components/TsingrocDatePicker";
18
19
  export { default as TsingrocTheme } from "./components/TsingrocTheme";
@@ -0,0 +1,6 @@
1
+ import type { LineSeriesOption } from "echarts";
2
+ import type { OptionDataValue } from "echarts/types/src/util/types.js";
3
+ export type LineDataItem = LineSeriesOption["data"] extends (infer T)[] | undefined ? T : never;
4
+ export type LineDataValue = OptionDataValue | OptionDataValue[];
5
+ export type LineDataItemOption = LineDataItem extends LineDataValue | infer T ? T : never;
6
+ export declare function destructureLineDataItem(value: LineDataItem, i: number): [OptionDataValue[], LineDataItemOption | undefined] | null | undefined;
@@ -0,0 +1,17 @@
1
+ export function destructureLineDataItem(value, i) {
2
+ if (value == null) return value;
3
+ let rawValue,
4
+ option = undefined;
5
+ if (typeof value === "object" && !(value instanceof Date) && !Array.isArray(value)) {
6
+ ({
7
+ value: rawValue,
8
+ ...option
9
+ } = value);
10
+ } else {
11
+ rawValue = value;
12
+ }
13
+ if (!Array.isArray(rawValue)) {
14
+ rawValue = [i, rawValue];
15
+ }
16
+ return [rawValue, option];
17
+ }
@@ -0,0 +1 @@
1
+ export declare function filterMap<T, R>(array: T[], func: (elem: T, index: number, array: T[]) => R): NonNullable<R>[];
@@ -0,0 +1,11 @@
1
+ export function filterMap(array, func) {
2
+ const result = [];
3
+ for (let i = 0; i < array.length; i++) {
4
+ const elem = array[i];
5
+ const resultElem = func(elem, i, array);
6
+ if (resultElem != null) {
7
+ result.push(resultElem);
8
+ }
9
+ }
10
+ return result;
11
+ }
@@ -1,4 +1,8 @@
1
1
  export * from "./debug";
2
+ export * from "./destructureLineDataItem";
3
+ export * from "./filterMap";
2
4
  export * from "./math";
3
5
  export * from "./mock";
6
+ export * from "./normalizeIntoArray";
4
7
  export * from "./startOfQuarter";
8
+ export * from "./timeAxisLabel";
@@ -1,4 +1,8 @@
1
1
  export * from "./debug";
2
+ export * from "./destructureLineDataItem";
3
+ export * from "./filterMap";
2
4
  export * from "./math";
3
5
  export * from "./mock";
4
- export * from "./startOfQuarter";
6
+ export * from "./normalizeIntoArray";
7
+ export * from "./startOfQuarter";
8
+ export * from "./timeAxisLabel";
@@ -0,0 +1 @@
1
+ export declare function normalizeIntoArray<T extends object>(value: T | T[] | undefined): T[];
@@ -0,0 +1,3 @@
1
+ export function normalizeIntoArray(value) {
2
+ return value === undefined ? [] : Array.isArray(value) ? value : [value];
3
+ }
@@ -0,0 +1,5 @@
1
+ import { type Dayjs } from "dayjs";
2
+ import type { XAXisComponentOption } from "echarts";
3
+ export default function timeAxisLabel(startTime: Dayjs, endTime: Dayjs): (XAXisComponentOption & {
4
+ type: "time";
5
+ })["axisLabel"];
@@ -0,0 +1,18 @@
1
+ import dayjs from "dayjs";
2
+ export default function timeAxisLabel(startTime, endTime) {
3
+ return {
4
+ formatter: endTime.diff(startTime, "day", true) <= 1 ? value => dayjs(value).isSame(endTime) && endTime.hour() === 0 ? "24:00" : "{HH}:{mm}" : value => {
5
+ const time = dayjs(value);
6
+ if (time.hour() === 0 && time.minute() === 0) {
7
+ return "{date|{MM}-{dd}}";
8
+ } else {
9
+ return "{HH}:{mm}";
10
+ }
11
+ },
12
+ rich: {
13
+ date: {
14
+ fontWeight: "bold"
15
+ }
16
+ }
17
+ };
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsingroc/tsingroc-components",
3
- "version": "5.0.0-alpha.12",
3
+ "version": "5.0.0-alpha.14",
4
4
  "author": "",
5
5
  "license": "ISC",
6
6
  "description": "",