@antv/gpt-vis 1.0.0 → 1.0.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.
Files changed (92) hide show
  1. package/README.md +66 -1
  2. package/README.zh-CN.md +66 -1
  3. package/dist/cjs/types/index.d.ts +2 -1
  4. package/dist/cjs/util/animation.d.ts +2 -0
  5. package/dist/cjs/util/animation.js +38 -0
  6. package/dist/cjs/util/components.d.ts +15 -0
  7. package/dist/cjs/util/components.js +94 -0
  8. package/dist/cjs/util/crosshair-axis-labels.d.ts +9 -0
  9. package/dist/cjs/util/crosshair-axis-labels.js +304 -0
  10. package/dist/cjs/util/index.d.ts +6 -0
  11. package/dist/cjs/util/index.js +33 -0
  12. package/dist/cjs/util/interaction.d.ts +14 -0
  13. package/dist/cjs/util/interaction.js +89 -0
  14. package/dist/cjs/util/theme.d.ts +18 -24
  15. package/dist/cjs/util/theme.js +303 -120
  16. package/dist/cjs/util/tokens.d.ts +31 -0
  17. package/dist/cjs/util/tokens.js +98 -0
  18. package/dist/cjs/vis/area/index.d.ts +2 -2
  19. package/dist/cjs/vis/area/index.js +76 -31
  20. package/dist/cjs/vis/bar/index.d.ts +2 -2
  21. package/dist/cjs/vis/bar/index.js +22 -19
  22. package/dist/cjs/vis/boxplot/index.js +1 -4
  23. package/dist/cjs/vis/column/index.d.ts +2 -2
  24. package/dist/cjs/vis/column/index.js +28 -18
  25. package/dist/cjs/vis/dual-axes/index.d.ts +2 -2
  26. package/dist/cjs/vis/dual-axes/index.js +89 -34
  27. package/dist/cjs/vis/funnel/index.d.ts +4 -2
  28. package/dist/cjs/vis/funnel/index.js +171 -92
  29. package/dist/cjs/vis/histogram/index.js +1 -4
  30. package/dist/cjs/vis/line/index.d.ts +2 -2
  31. package/dist/cjs/vis/line/index.js +71 -31
  32. package/dist/cjs/vis/liquid/index.d.ts +2 -2
  33. package/dist/cjs/vis/liquid/index.js +41 -16
  34. package/dist/cjs/vis/pie/index.d.ts +2 -2
  35. package/dist/cjs/vis/pie/index.js +26 -16
  36. package/dist/cjs/vis/radar/index.d.ts +2 -2
  37. package/dist/cjs/vis/radar/index.js +21 -29
  38. package/dist/cjs/vis/sankey/index.js +1 -4
  39. package/dist/cjs/vis/scatter/index.d.ts +2 -2
  40. package/dist/cjs/vis/scatter/index.js +40 -17
  41. package/dist/cjs/vis/treemap/index.js +1 -4
  42. package/dist/cjs/vis/venn/index.js +1 -4
  43. package/dist/cjs/vis/violin/index.js +1 -1
  44. package/dist/cjs/vis/waterfall/index.js +1 -1
  45. package/dist/cjs/vis/word-cloud/index.d.ts +3 -2
  46. package/dist/cjs/vis/word-cloud/index.js +125 -10
  47. package/dist/esm/types/index.d.ts +2 -1
  48. package/dist/esm/util/animation.d.ts +2 -0
  49. package/dist/esm/util/animation.js +17 -0
  50. package/dist/esm/util/components.d.ts +15 -0
  51. package/dist/esm/util/components.js +67 -0
  52. package/dist/esm/util/crosshair-axis-labels.d.ts +9 -0
  53. package/dist/esm/util/crosshair-axis-labels.js +328 -0
  54. package/dist/esm/util/index.d.ts +6 -0
  55. package/dist/esm/util/index.js +6 -0
  56. package/dist/esm/util/interaction.d.ts +14 -0
  57. package/dist/esm/util/interaction.js +73 -0
  58. package/dist/esm/util/theme.d.ts +18 -24
  59. package/dist/esm/util/theme.js +302 -126
  60. package/dist/esm/util/tokens.d.ts +31 -0
  61. package/dist/esm/util/tokens.js +64 -0
  62. package/dist/esm/vis/area/index.d.ts +2 -2
  63. package/dist/esm/vis/area/index.js +91 -41
  64. package/dist/esm/vis/bar/index.d.ts +2 -2
  65. package/dist/esm/vis/bar/index.js +28 -29
  66. package/dist/esm/vis/boxplot/index.js +4 -5
  67. package/dist/esm/vis/column/index.d.ts +2 -2
  68. package/dist/esm/vis/column/index.js +36 -29
  69. package/dist/esm/vis/dual-axes/index.d.ts +2 -2
  70. package/dist/esm/vis/dual-axes/index.js +115 -42
  71. package/dist/esm/vis/funnel/index.d.ts +4 -2
  72. package/dist/esm/vis/funnel/index.js +156 -83
  73. package/dist/esm/vis/histogram/index.js +4 -5
  74. package/dist/esm/vis/line/index.d.ts +2 -2
  75. package/dist/esm/vis/line/index.js +80 -37
  76. package/dist/esm/vis/liquid/index.d.ts +2 -2
  77. package/dist/esm/vis/liquid/index.js +41 -14
  78. package/dist/esm/vis/pie/index.d.ts +2 -2
  79. package/dist/esm/vis/pie/index.js +36 -16
  80. package/dist/esm/vis/radar/index.d.ts +2 -2
  81. package/dist/esm/vis/radar/index.js +21 -34
  82. package/dist/esm/vis/sankey/index.js +4 -5
  83. package/dist/esm/vis/scatter/index.d.ts +2 -2
  84. package/dist/esm/vis/scatter/index.js +41 -25
  85. package/dist/esm/vis/treemap/index.js +4 -5
  86. package/dist/esm/vis/venn/index.js +4 -5
  87. package/dist/esm/vis/violin/index.js +5 -13
  88. package/dist/esm/vis/waterfall/index.js +5 -7
  89. package/dist/esm/vis/word-cloud/index.d.ts +3 -2
  90. package/dist/esm/vis/word-cloud/index.js +158 -10
  91. package/dist/umd/index.min.js +1 -1
  92. package/package.json +18 -15
package/README.md CHANGED
@@ -24,7 +24,7 @@ AI-native visualization library for the LLM era. Framework-agnostic, ready to us
24
24
  </div>
25
25
 
26
26
  <div align="center">
27
- <img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*k21VQY6NgAwAAAAAWAAAAAgAemJ7AQ/fmt.avif" width="100%" />
27
+ <img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*yNtZT47dH1kAAAAAgBAAAAgAemJ7AQ/fmt.webp" width="100%" alt="GPT-Vis Hero Image" />
28
28
  </div>
29
29
 
30
30
  <br/>
@@ -391,6 +391,71 @@ document.getElementById('content').innerHTML = marked.parse(markdown);
391
391
 
392
392
  </details>
393
393
 
394
+ ## 🧩 Shadcn/ui
395
+
396
+ Copy GPT-Vis React components directly into your project via shadcn CLI — full source control, fully customizable.
397
+
398
+ ### Base Component
399
+
400
+ The universal `GPTVis` component accepts vis syntax strings or config objects for all 26 chart types:
401
+
402
+ ```bash
403
+ npx shadcn@latest add @gpt-vis/gpt-vis
404
+ ```
405
+
406
+ ```tsx
407
+ import { GPTVis } from '@/components/ui/gpt-vis';
408
+
409
+ <GPTVis
410
+ content="vis line
411
+ data
412
+ - time 2020
413
+ value 100
414
+ - time 2021
415
+ value 120
416
+ - time 2022
417
+ value 150
418
+ title Sales Trend"
419
+ theme="academy"
420
+ />;
421
+ ```
422
+
423
+ ### Typed Chart Components
424
+
425
+ Each chart type has its own component with a typed `config` prop — JSON only, chart-specific TypeScript validation:
426
+
427
+ ```bash
428
+ npx shadcn@latest add @gpt-vis/line
429
+ ```
430
+
431
+ ```tsx
432
+ import { Line } from '@/components/ui/line';
433
+
434
+ <Line
435
+ config={{
436
+ data: [
437
+ { time: '2020', value: 100 },
438
+ { time: '2021', value: 120 },
439
+ { time: '2022', value: 150 },
440
+ ],
441
+ title: 'Sales Trend',
442
+ axisXTitle: 'Year',
443
+ }}
444
+ height={400}
445
+ />;
446
+ ```
447
+
448
+ All 26 chart types are available. Install any by name:
449
+
450
+ ```bash
451
+ npx shadcn@latest add @gpt-vis/pie
452
+ npx shadcn@latest add @gpt-vis/bar
453
+ npx shadcn@latest add @gpt-vis/mindmap
454
+ # ...and more
455
+ ```
456
+
457
+ Each typed component automatically bundles the base `GPTVis` component as a dependency. Props like `width`, `height`, `theme`, `wrapper`, `locale`, `className`, and `containerStyle` are the same across all components.
458
+
394
459
  ## 🤖 AI Ecosystem
395
460
 
396
461
  GPT-Vis provides a complete AI integration solution:
package/README.zh-CN.md CHANGED
@@ -24,7 +24,7 @@
24
24
  </div>
25
25
 
26
26
  <div align="center">
27
- <img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*k21VQY6NgAwAAAAAWAAAAAgAemJ7AQ/fmt.avif" width="100%" />
27
+ <img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*yNtZT47dH1kAAAAAgBAAAAgAemJ7AQ/fmt.webp" width="100%" alt="GPT-Vis Hero Image" />
28
28
  </div>
29
29
 
30
30
  <br/>
@@ -391,6 +391,71 @@ document.getElementById('content').innerHTML = marked.parse(markdown);
391
391
 
392
392
  </details>
393
393
 
394
+ ## 🧩 Shadcn/ui
395
+
396
+ 通过 shadcn CLI 将 GPT-Vis React 组件直接复制到你的项目中 — 完全源代码控制,高度可定制。
397
+
398
+ ### 基础组件
399
+
400
+ 通用的 `GPTVis` 组件,支持全部 26 种图表类型的 vis 语法字符串或 JSON 配置对象:
401
+
402
+ ```bash
403
+ npx shadcn@latest add @gpt-vis/gpt-vis
404
+ ```
405
+
406
+ ```tsx
407
+ import { GPTVis } from '@/components/ui/gpt-vis';
408
+
409
+ <GPTVis
410
+ content="vis line
411
+ data
412
+ - time 2020
413
+ value 100
414
+ - time 2021
415
+ value 120
416
+ - time 2022
417
+ value 150
418
+ title 销售趋势"
419
+ theme="academy"
420
+ />;
421
+ ```
422
+
423
+ ### 类型化图表组件
424
+
425
+ 每种图表类型都有独立的组件,提供类型安全的 `config` 属性 — 仅支持 JSON,带 TypeScript 类型校验:
426
+
427
+ ```bash
428
+ npx shadcn@latest add @gpt-vis/line
429
+ ```
430
+
431
+ ```tsx
432
+ import { Line } from '@/components/ui/line';
433
+
434
+ <Line
435
+ config={{
436
+ data: [
437
+ { time: '2020', value: 100 },
438
+ { time: '2021', value: 120 },
439
+ { time: '2022', value: 150 },
440
+ ],
441
+ title: '销售趋势',
442
+ axisXTitle: '年份',
443
+ }}
444
+ height={400}
445
+ />;
446
+ ```
447
+
448
+ 全部 26 种图表类型均可用,按名称安装即可:
449
+
450
+ ```bash
451
+ npx shadcn@latest add @gpt-vis/pie
452
+ npx shadcn@latest add @gpt-vis/bar
453
+ npx shadcn@latest add @gpt-vis/mindmap
454
+ # ...等等
455
+ ```
456
+
457
+ 每个类型化组件自动将基础 `GPTVis` 组件作为依赖安装。`width`、`height`、`theme`、`wrapper`、`locale`、`className`、`containerStyle` 等属性在所有组件中保持一致。
458
+
394
459
  ## 🤖 AI 生态
395
460
 
396
461
  GPT-Vis 提供完整的 AI 集成方案:
@@ -2,11 +2,12 @@
2
2
  * Common visualization options for all chart components.
3
3
  * Defines the container and dimensions for rendering visualizations.
4
4
  */
5
+ export type VisualizationTheme = 'default' | 'light' | 'dark' | 'academy';
5
6
  export interface VisualizationOptions {
6
7
  container: string | HTMLElement;
7
8
  width?: number;
8
9
  height?: number;
9
- theme?: 'default' | 'light' | 'dark' | 'academy';
10
+ theme?: VisualizationTheme;
10
11
  wrapper?: boolean;
11
12
  locale?: string;
12
13
  }
@@ -0,0 +1,2 @@
1
+ export type ChartEnterAnimation = 'fadeIn' | 'pathIn' | 'growInX' | 'growInY' | 'waveIn';
2
+ export declare const getChartAnimation: (hasRendered: boolean, enterType?: ChartEnterAnimation) => false | Record<string, unknown>;
@@ -0,0 +1,38 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/util/animation.ts
20
+ var animation_exports = {};
21
+ __export(animation_exports, {
22
+ getChartAnimation: () => getChartAnimation
23
+ });
24
+ module.exports = __toCommonJS(animation_exports);
25
+ var prefersReducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
26
+ var getChartAnimation = (hasRendered, enterType) => {
27
+ if (hasRendered || prefersReducedMotion())
28
+ return false;
29
+ return {
30
+ enter: enterType ? { type: enterType } : {},
31
+ update: { type: null },
32
+ exit: { type: null }
33
+ };
34
+ };
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ getChartAnimation
38
+ });
@@ -0,0 +1,15 @@
1
+ export type ChartLocale = 'en-US' | 'zh-CN';
2
+ export type CartesianXAxisOptions = {
3
+ xLabels?: unknown[];
4
+ chartWidth?: number;
5
+ };
6
+ export type CartesianAxisOptions = CartesianXAxisOptions & {
7
+ axisXTitle?: string | false;
8
+ axisYTitle?: string | false;
9
+ };
10
+ export declare const resolveChartLocale: (locale?: string) => ChartLocale;
11
+ export declare const getCartesianLayout: ({ xLabels, chartWidth, }: CartesianXAxisOptions) => Record<string, number>;
12
+ export declare const getCartesianAxis: ({ axisXTitle, axisYTitle, xLabels, chartWidth, }: CartesianAxisOptions) => Record<'x' | 'y', Record<string, unknown>>;
13
+ export declare const getColorLegend: (visible: boolean) => false | {
14
+ color: Record<string, never>;
15
+ };
@@ -0,0 +1,94 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/util/components.ts
20
+ var components_exports = {};
21
+ __export(components_exports, {
22
+ getCartesianAxis: () => getCartesianAxis,
23
+ getCartesianLayout: () => getCartesianLayout,
24
+ getColorLegend: () => getColorLegend,
25
+ resolveChartLocale: () => resolveChartLocale
26
+ });
27
+ module.exports = __toCommonJS(components_exports);
28
+ var DEFAULT_CHART_WIDTH = 640;
29
+ var AXIS_HORIZONTAL_PADDING = 96;
30
+ var ANGLED_LABEL_MARGIN_RIGHT_MIN = 32;
31
+ var ANGLED_LABEL_MARGIN_RIGHT_MAX = 64;
32
+ var ANGLED_LABEL_EDGE_GAP = 8;
33
+ var estimateLabelWidth = (value) => Array.from(String(value ?? "")).reduce(
34
+ (width, character) => width + ((character.codePointAt(0) ?? 0) > 255 ? 12 : 7),
35
+ 0
36
+ );
37
+ var shouldUseAngledXAxisLabels = (labels, chartWidth = DEFAULT_CHART_WIDTH) => {
38
+ if (!(labels == null ? void 0 : labels.length))
39
+ return false;
40
+ const uniqueLabels = Array.from(new Set(labels.map((label) => String(label ?? ""))));
41
+ if (uniqueLabels.length <= 1)
42
+ return false;
43
+ const availableWidth = Math.max(chartWidth - AXIS_HORIZONTAL_PADDING, 240);
44
+ const estimatedWidth = uniqueLabels.reduce(
45
+ (total, label) => total + Math.max(28, estimateLabelWidth(label) + 16),
46
+ 0
47
+ );
48
+ return estimatedWidth > availableWidth;
49
+ };
50
+ var resolveChartLocale = (locale) => (locale == null ? void 0 : locale.toLowerCase().startsWith("zh")) ? "zh-CN" : "en-US";
51
+ var getCartesianLayout = ({
52
+ xLabels,
53
+ chartWidth
54
+ }) => {
55
+ if (!shouldUseAngledXAxisLabels(xLabels, chartWidth))
56
+ return {};
57
+ const tailLabel = xLabels == null ? void 0 : xLabels[xLabels.length - 1];
58
+ const labelWidth = estimateLabelWidth(tailLabel);
59
+ const projectedHalfWidth = (labelWidth + 12) * Math.SQRT1_2 / 2;
60
+ return {
61
+ marginRight: Math.min(
62
+ ANGLED_LABEL_MARGIN_RIGHT_MAX,
63
+ Math.max(
64
+ ANGLED_LABEL_MARGIN_RIGHT_MIN,
65
+ Math.ceil(projectedHalfWidth + ANGLED_LABEL_EDGE_GAP)
66
+ )
67
+ )
68
+ };
69
+ };
70
+ var getCartesianAxis = ({
71
+ axisXTitle,
72
+ axisYTitle,
73
+ xLabels,
74
+ chartWidth
75
+ }) => {
76
+ const useAngledXAxisLabels = shouldUseAngledXAxisLabels(xLabels, chartWidth);
77
+ return {
78
+ x: {
79
+ title: axisXTitle || false,
80
+ ...useAngledXAxisLabels ? { labelTransform: "rotate(45)", labelAutoRotate: false } : {}
81
+ },
82
+ y: {
83
+ title: axisYTitle || false
84
+ }
85
+ };
86
+ };
87
+ var getColorLegend = (visible) => visible ? { color: {} } : false;
88
+ // Annotate the CommonJS export names for ESM import in node:
89
+ 0 && (module.exports = {
90
+ getCartesianAxis,
91
+ getCartesianLayout,
92
+ getColorLegend,
93
+ resolveChartLocale
94
+ });
@@ -0,0 +1,9 @@
1
+ import { type Chart } from '@antv/g2';
2
+ import type { VisualizationTheme } from '../types';
3
+ /**
4
+ * Bridges G2 tooltip crosshairs to axis value tags.
5
+ *
6
+ * G2 does not currently expose axis tags for tooltip crosshairs, so this adapter
7
+ * reads the rule geometry created by G2 5.4 and renders labels with LineCrosshair.
8
+ */
9
+ export declare const bindCrosshairAxisLabels: (chart: Chart, theme: VisualizationTheme) => (() => void);
@@ -0,0 +1,304 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/util/crosshair-axis-labels.ts
20
+ var crosshair_axis_labels_exports = {};
21
+ __export(crosshair_axis_labels_exports, {
22
+ bindCrosshairAxisLabels: () => bindCrosshairAxisLabels
23
+ });
24
+ module.exports = __toCommonJS(crosshair_axis_labels_exports);
25
+ var import_component = require("@antv/component");
26
+ var import_g2 = require("@antv/g2");
27
+ var import_tokens = require("./tokens");
28
+ var formatCrosshairAxisValue = (value, formatter, precision) => {
29
+ if (value === void 0 || value === null || value === "")
30
+ return "";
31
+ try {
32
+ const formatted = formatter == null ? void 0 : formatter(value);
33
+ if (formatted !== void 0 && formatted !== null)
34
+ return String(formatted);
35
+ } catch {
36
+ }
37
+ if (value instanceof Date)
38
+ return value.toLocaleString();
39
+ if (typeof value === "number" && Number.isFinite(value) && precision !== void 0) {
40
+ return value.toFixed(precision);
41
+ }
42
+ return String(value);
43
+ };
44
+ var getNumberPrecision = (value) => {
45
+ var _a;
46
+ if (!Number.isFinite(value) || value === 0)
47
+ return 0;
48
+ const [coefficient, exponentText = "0"] = Math.abs(value).toExponential().split("e");
49
+ const coefficientPrecision = ((_a = coefficient.split(".")[1]) == null ? void 0 : _a.length) || 0;
50
+ return Math.max(0, coefficientPrecision - Number(exponentText));
51
+ };
52
+ var getCrosshairScalePrecision = (scale) => {
53
+ var _a;
54
+ const ticks = (_a = scale == null ? void 0 : scale.getTicks) == null ? void 0 : _a.call(scale);
55
+ if (!Array.isArray(ticks) || ticks.length < 2)
56
+ return void 0;
57
+ let interval = Number.POSITIVE_INFINITY;
58
+ for (let index = 1; index < ticks.length; index += 1) {
59
+ const current = Number(ticks[index]);
60
+ const previous = Number(ticks[index - 1]);
61
+ const difference = Math.abs(current - previous);
62
+ if (Number.isFinite(difference) && difference > 0)
63
+ interval = Math.min(interval, difference);
64
+ }
65
+ if (!Number.isFinite(interval))
66
+ return void 0;
67
+ return Math.min(getNumberPrecision(interval) + 2, 20);
68
+ };
69
+ var getCrosshairTagStyle = (theme, tokens) => ({
70
+ lineLineWidth: 0,
71
+ lineStrokeOpacity: 0,
72
+ linePointerEvents: "none",
73
+ tagPadding: [4, 7],
74
+ tagRadius: 6,
75
+ tagBackgroundFill: tokens.textPrimary,
76
+ tagBackgroundStroke: "transparent",
77
+ tagBackgroundLineWidth: 0,
78
+ tagBackgroundShadowColor: theme === "dark" ? "rgba(0, 0, 0, 0.38)" : "rgba(15, 23, 42, 0.18)",
79
+ tagBackgroundShadowBlur: 8,
80
+ tagBackgroundShadowOffsetY: 2,
81
+ tagLabelFill: tokens.background,
82
+ tagLabelFillOpacity: 1,
83
+ tagLabelFontFamily: import_tokens.CHART_FONT_FAMILY,
84
+ tagLabelFontSize: 11,
85
+ tagLabelFontWeight: 500,
86
+ tagLabelLineWidth: 0,
87
+ tagPointerEvents: "none"
88
+ });
89
+ var clamp = (value, min, max) => Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max));
90
+ var invertCrosshairValue = (scale, value) => {
91
+ var _a, _b, _c;
92
+ if (!scale || typeof scale.invert !== "function" || value === void 0)
93
+ return void 0;
94
+ if (typeof scale.getBandWidth === "function") {
95
+ const domain = (_b = (_a = scale.getOptions) == null ? void 0 : _a.call(scale)) == null ? void 0 : _b.domain;
96
+ if (!Array.isArray(domain) || domain.length === 0 || !Number.isFinite(Number(value))) {
97
+ return void 0;
98
+ }
99
+ let nearestValue = domain[0];
100
+ let nearestDistance = Number.POSITIVE_INFINITY;
101
+ for (const domainValue of domain) {
102
+ const start = Number((_c = scale.map) == null ? void 0 : _c.call(scale, domainValue));
103
+ const bandWidth = Number(scale.getBandWidth(domainValue)) || 0;
104
+ const distance = Math.abs(start + bandWidth / 2 - Number(value));
105
+ if (Number.isFinite(distance) && distance < nearestDistance) {
106
+ nearestValue = domainValue;
107
+ nearestDistance = distance;
108
+ }
109
+ }
110
+ return nearestValue;
111
+ }
112
+ try {
113
+ return scale.invert(value);
114
+ } catch {
115
+ return void 0;
116
+ }
117
+ };
118
+ var getTooltipPlot = (context) => {
119
+ var _a;
120
+ const root = (_a = context.canvas) == null ? void 0 : _a.getRoot();
121
+ if (!root)
122
+ return void 0;
123
+ return (0, import_g2.selectPlotArea)(root);
124
+ };
125
+ var getCartesianView = (context) => {
126
+ var _a;
127
+ return (_a = context.views) == null ? void 0 : _a.find(
128
+ ({ coordinate, scale }) => Boolean((scale == null ? void 0 : scale.x) && (scale == null ? void 0 : scale.y)) && typeof (coordinate == null ? void 0 : coordinate.invert) === "function"
129
+ );
130
+ };
131
+ var getRuleLine = (rule) => {
132
+ var _a, _b, _c, _d;
133
+ const x1 = Number((_a = rule == null ? void 0 : rule.style) == null ? void 0 : _a.x1);
134
+ const x2 = Number((_b = rule == null ? void 0 : rule.style) == null ? void 0 : _b.x2);
135
+ const y1 = Number((_c = rule == null ? void 0 : rule.style) == null ? void 0 : _c.y1);
136
+ const y2 = Number((_d = rule == null ? void 0 : rule.style) == null ? void 0 : _d.y2);
137
+ if (![x1, x2, y1, y2].every(Number.isFinite))
138
+ return void 0;
139
+ return { x1, x2, y1, y2 };
140
+ };
141
+ var getPlotOffset = (plot) => {
142
+ var _a;
143
+ const [x = 0, y = 0] = ((_a = plot.getLocalPosition) == null ? void 0 : _a.call(plot)) || [];
144
+ return [Number.isFinite(Number(x)) ? Number(x) : 0, Number.isFinite(Number(y)) ? Number(y) : 0];
145
+ };
146
+ var invertCoordinate = (view, point) => {
147
+ try {
148
+ const inverted = view.coordinate.invert(point);
149
+ if (!Array.isArray(inverted) || inverted.length < 2)
150
+ return void 0;
151
+ const x = Number(inverted[0]);
152
+ const y = Number(inverted[1]);
153
+ return Number.isFinite(x) && Number.isFinite(y) ? [x, y] : void 0;
154
+ } catch {
155
+ return void 0;
156
+ }
157
+ };
158
+ var bindCrosshairAxisLabels = (chart, theme) => {
159
+ if (!chart || typeof chart.on !== "function")
160
+ return () => void 0;
161
+ const tagStyle = getCrosshairTagStyle(theme, (0, import_tokens.getChartVisualTokens)(theme));
162
+ let boundPlot = null;
163
+ let xCrosshair = null;
164
+ let yCrosshair = null;
165
+ let latestPointerY = null;
166
+ let latestXValue;
167
+ const destroyCrosshairs = () => {
168
+ xCrosshair == null ? void 0 : xCrosshair.destroy();
169
+ yCrosshair == null ? void 0 : yCrosshair.destroy();
170
+ xCrosshair = null;
171
+ yCrosshair = null;
172
+ boundPlot = null;
173
+ };
174
+ const hideCrosshairs = () => {
175
+ for (const crosshair of [xCrosshair, yCrosshair]) {
176
+ if (crosshair)
177
+ crosshair.style.visibility = "hidden";
178
+ }
179
+ };
180
+ const resetCrosshairs = () => {
181
+ latestPointerY = null;
182
+ latestXValue = void 0;
183
+ hideCrosshairs();
184
+ };
185
+ const ensureCrosshairs = (plot, xLine, yLine, xText, yText) => {
186
+ if (boundPlot !== plot)
187
+ destroyCrosshairs();
188
+ if (xCrosshair && yCrosshair)
189
+ return;
190
+ const layer = plot.parentNode || plot;
191
+ const [plotX, plotY] = getPlotOffset(plot);
192
+ const xStart = [xLine.x1 + plotX, xLine.y1 + plotY];
193
+ const xEnd = [xLine.x2 + plotX, xLine.y2 + plotY];
194
+ const yStart = [yLine.x1 + plotX, yLine.y1 + plotY];
195
+ const yEnd = [yLine.x2 + plotX, yLine.y2 + plotY];
196
+ if (!xCrosshair) {
197
+ xCrosshair = new import_component.LineCrosshair({
198
+ style: { ...tagStyle, startPos: xStart, endPos: xEnd, tagText: xText, tagPosition: "end" }
199
+ });
200
+ xCrosshair.style.zIndex = 7;
201
+ xCrosshair.style.pointerEvents = "none";
202
+ layer.appendChild(xCrosshair);
203
+ }
204
+ if (!yCrosshair) {
205
+ yCrosshair = new import_component.LineCrosshair({
206
+ style: {
207
+ ...tagStyle,
208
+ startPos: yStart,
209
+ endPos: yEnd,
210
+ tagText: yText,
211
+ tagPosition: "start"
212
+ }
213
+ });
214
+ yCrosshair.style.zIndex = 7;
215
+ yCrosshair.style.pointerEvents = "none";
216
+ layer.appendChild(yCrosshair);
217
+ }
218
+ boundPlot = plot;
219
+ };
220
+ const updateCrosshairs = (event) => {
221
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
222
+ const context = chart.getContext();
223
+ const plot = getTooltipPlot(context);
224
+ const view = getCartesianView(context);
225
+ if (!plot || !view) {
226
+ hideCrosshairs();
227
+ return;
228
+ }
229
+ const verticalRule = getRuleLine(plot.ruleY);
230
+ const horizontalRule = getRuleLine(plot.ruleX);
231
+ if (!verticalRule || !horizontalRule) {
232
+ hideCrosshairs();
233
+ return;
234
+ }
235
+ const [plotX, plotY] = getPlotOffset(plot);
236
+ const eventY = Number(event.offsetY ?? event.canvasY);
237
+ const globalY = Number.isFinite(eventY) ? eventY : latestPointerY;
238
+ const pointerY = Number.isFinite(globalY) ? Number(globalY) - plotY : horizontalRule.y1;
239
+ const x = clamp(verticalRule.x1, horizontalRule.x1, horizontalRule.x2);
240
+ const y = clamp(pointerY, verticalRule.y1, verticalRule.y2);
241
+ const invertedPosition = invertCoordinate(view, [x, y]);
242
+ const xValue = latestXValue ?? invertCrosshairValue(view.scale.x, invertedPosition == null ? void 0 : invertedPosition[0]);
243
+ const yValue = invertCrosshairValue(view.scale.y, invertedPosition == null ? void 0 : invertedPosition[1]) ?? ((_c = (_b = (_a = event.data) == null ? void 0 : _a.items) == null ? void 0 : _b[0]) == null ? void 0 : _c.value);
244
+ const xText = formatCrosshairAxisValue(xValue, (_e = (_d = view.scale.x).getFormatter) == null ? void 0 : _e.call(_d));
245
+ const yText = formatCrosshairAxisValue(
246
+ yValue,
247
+ (_g = (_f = view.scale.y).getFormatter) == null ? void 0 : _g.call(_f),
248
+ getCrosshairScalePrecision(view.scale.y)
249
+ );
250
+ if (!xText || !yText) {
251
+ hideCrosshairs();
252
+ return;
253
+ }
254
+ if ((_h = plot.ruleY) == null ? void 0 : _h.style) {
255
+ plot.ruleY.style.x1 = x;
256
+ plot.ruleY.style.x2 = x;
257
+ }
258
+ if ((_i = plot.ruleX) == null ? void 0 : _i.style) {
259
+ plot.ruleX.style.y1 = y;
260
+ plot.ruleX.style.y2 = y;
261
+ }
262
+ const displayVerticalRule = { ...verticalRule, x1: x, x2: x };
263
+ const displayHorizontalRule = { ...horizontalRule, y1: y, y2: y };
264
+ ensureCrosshairs(plot, displayVerticalRule, displayHorizontalRule, xText, yText);
265
+ if (!xCrosshair || !yCrosshair)
266
+ return;
267
+ xCrosshair.setText(xText);
268
+ xCrosshair.setPointer([x + plotX, verticalRule.y2 + plotY]);
269
+ xCrosshair.style.visibility = "visible";
270
+ yCrosshair.setText(yText);
271
+ yCrosshair.setPointer([horizontalRule.x1 + plotX, y + plotY]);
272
+ yCrosshair.style.visibility = "visible";
273
+ };
274
+ const onPointerMove = (event) => {
275
+ const y = Number(event.offsetY ?? event.canvasY);
276
+ if (Number.isFinite(y))
277
+ latestPointerY = y;
278
+ updateCrosshairs(event);
279
+ };
280
+ const onTooltipShow = (event) => {
281
+ var _a, _b;
282
+ if (!event.nativeEvent)
283
+ return;
284
+ if (((_b = (_a = event.data) == null ? void 0 : _a.data) == null ? void 0 : _b.x) !== void 0)
285
+ latestXValue = event.data.data.x;
286
+ updateCrosshairs(event);
287
+ };
288
+ chart.on("tooltip:show", onTooltipShow);
289
+ chart.on("tooltip:hide", resetCrosshairs);
290
+ chart.on("plot:pointermove", onPointerMove);
291
+ chart.on("plot:pointerleave", resetCrosshairs);
292
+ return () => {
293
+ var _a, _b, _c, _d;
294
+ (_a = chart.off) == null ? void 0 : _a.call(chart, "tooltip:show", onTooltipShow);
295
+ (_b = chart.off) == null ? void 0 : _b.call(chart, "tooltip:hide", resetCrosshairs);
296
+ (_c = chart.off) == null ? void 0 : _c.call(chart, "plot:pointermove", onPointerMove);
297
+ (_d = chart.off) == null ? void 0 : _d.call(chart, "plot:pointerleave", resetCrosshairs);
298
+ destroyCrosshairs();
299
+ };
300
+ };
301
+ // Annotate the CommonJS export names for ESM import in node:
302
+ 0 && (module.exports = {
303
+ bindCrosshairAxisLabels
304
+ });
@@ -0,0 +1,6 @@
1
+ export * from './animation';
2
+ export * from './components';
3
+ export * from './crosshair-axis-labels';
4
+ export * from './interaction';
5
+ export * from './theme';
6
+ export * from './tokens';
@@ -0,0 +1,33 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/util/index.ts
17
+ var util_exports = {};
18
+ module.exports = __toCommonJS(util_exports);
19
+ __reExport(util_exports, require("./animation"), module.exports);
20
+ __reExport(util_exports, require("./components"), module.exports);
21
+ __reExport(util_exports, require("./crosshair-axis-labels"), module.exports);
22
+ __reExport(util_exports, require("./interaction"), module.exports);
23
+ __reExport(util_exports, require("./theme"), module.exports);
24
+ __reExport(util_exports, require("./tokens"), module.exports);
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ ...require("./animation"),
28
+ ...require("./components"),
29
+ ...require("./crosshair-axis-labels"),
30
+ ...require("./interaction"),
31
+ ...require("./theme"),
32
+ ...require("./tokens")
33
+ });