@squadbase/vantage 0.6.2-dev1.01caa72 → 0.6.2-dev1.02aab78

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 (167) hide show
  1. package/dist/{build-X5NVCQKT.js → build-YOPOGPQB.js} +7 -7
  2. package/dist/{build-X5NVCQKT.js.map → build-YOPOGPQB.js.map} +1 -1
  3. package/dist/{check-ZBIH422T.js → check-FBHT6W6J.js} +5 -5
  4. package/dist/{check-ZBIH422T.js.map → check-FBHT6W6J.js.map} +1 -1
  5. package/dist/chunk-2IAPIOPS.js +152 -0
  6. package/dist/chunk-2IAPIOPS.js.map +1 -0
  7. package/dist/chunk-57GHR5LN.js +163 -0
  8. package/dist/chunk-57GHR5LN.js.map +1 -0
  9. package/dist/{chunk-7DZGJQ3P.js → chunk-5C2SEDPH.js} +21 -4
  10. package/dist/chunk-5C2SEDPH.js.map +1 -0
  11. package/dist/chunk-6OTTGAPO.js +44 -0
  12. package/dist/chunk-6OTTGAPO.js.map +1 -0
  13. package/dist/{chunk-2ICNHUG6.js → chunk-7652CGJJ.js} +10 -3
  14. package/dist/{chunk-2ICNHUG6.js.map → chunk-7652CGJJ.js.map} +1 -1
  15. package/dist/chunk-JXFCSF3K.js +673 -0
  16. package/dist/chunk-JXFCSF3K.js.map +1 -0
  17. package/dist/{chunk-IUPSBD6W.js → chunk-QOXXOFGL.js} +23 -886
  18. package/dist/chunk-QOXXOFGL.js.map +1 -0
  19. package/dist/{chunk-WAMZWZJB.js → chunk-R6MTJAHX.js} +6 -6
  20. package/dist/chunk-R6MTJAHX.js.map +1 -0
  21. package/dist/{chunk-CEXAQQ5W.js → chunk-S5MDTHH7.js} +180 -18
  22. package/dist/chunk-S5MDTHH7.js.map +1 -0
  23. package/dist/{chunk-JKLLFVEU.js → chunk-UWSQUHX6.js} +4 -99
  24. package/dist/chunk-UWSQUHX6.js.map +1 -0
  25. package/dist/cli.js +6 -6
  26. package/dist/components/index.d.ts +11 -247
  27. package/dist/components/index.js +4 -1
  28. package/dist/delta-text-CvwBGJ95.d.ts +15 -0
  29. package/dist/{dev-4XEDTELV.js → dev-GUKQT6U6.js} +7 -7
  30. package/dist/{dev-4XEDTELV.js.map → dev-GUKQT6U6.js.map} +1 -1
  31. package/dist/doc/index.d.ts +215 -2
  32. package/dist/doc/index.js +307 -3
  33. package/dist/doc/index.js.map +1 -1
  34. package/dist/{doctor-5E2VEZPK.js → doctor-B2O3GJDU.js} +5 -5
  35. package/dist/{doctor-5E2VEZPK.js.map → doctor-B2O3GJDU.js.map} +1 -1
  36. package/dist/format-U0cQl069.d.ts +243 -0
  37. package/dist/{routes-3SGAFDMC.js → routes-PVKNT777.js} +4 -4
  38. package/dist/{routes-3SGAFDMC.js.map → routes-PVKNT777.js.map} +1 -1
  39. package/dist/slide/index.d.ts +272 -1
  40. package/dist/slide/index.js +972 -2
  41. package/dist/slide/index.js.map +1 -1
  42. package/dist/table/index.js +4 -1
  43. package/dist/table/index.js.map +1 -1
  44. package/dist/{upgrade-JHXZBGQS.js → upgrade-7ZXMCTTR.js} +4 -4
  45. package/dist/{upgrade-JHXZBGQS.js.map → upgrade-7ZXMCTTR.js.map} +1 -1
  46. package/dist/vite/index.js +3 -3
  47. package/docs/en/changelog.md +2 -0
  48. package/docs/en/components.md +13 -2
  49. package/docs/en/doc/delta-text.md +40 -0
  50. package/docs/en/doc/doc-action-items.md +49 -0
  51. package/docs/en/doc/doc-callout.md +38 -0
  52. package/docs/en/doc/doc-data-table.md +60 -0
  53. package/docs/en/doc/doc-executive-summary.md +64 -0
  54. package/docs/en/doc/doc-figure.md +56 -0
  55. package/docs/en/doc/doc-key-findings.md +61 -0
  56. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  57. package/docs/en/doc/doc-notes-and-sources.md +43 -0
  58. package/docs/en/doc/doc-report-header.md +46 -0
  59. package/docs/en/pages-and-metadata.md +15 -0
  60. package/docs/en/parts/area-chart.md +99 -0
  61. package/docs/en/parts/bar-chart.md +91 -0
  62. package/docs/en/parts/bar-list.md +50 -0
  63. package/docs/en/parts/category-bar.md +37 -0
  64. package/docs/en/parts/chart-frame.md +39 -0
  65. package/docs/en/parts/delta.md +4 -3
  66. package/docs/en/parts/donut-chart.md +72 -0
  67. package/docs/en/parts/funnel-steps.md +2 -1
  68. package/docs/en/parts/heatmap.md +53 -0
  69. package/docs/en/parts/kpi-card.md +2 -1
  70. package/docs/en/parts/legend.md +35 -0
  71. package/docs/en/parts/line-chart.md +94 -0
  72. package/docs/en/parts/progress-circle.md +33 -0
  73. package/docs/en/parts/sample-data.md +39 -0
  74. package/docs/en/parts/scatter-chart.md +56 -0
  75. package/docs/en/parts/tracker.md +36 -0
  76. package/docs/en/parts/updated-at.md +30 -0
  77. package/docs/en/parts/waterfall-chart.md +56 -0
  78. package/docs/en/slide/slide-chart-full.md +48 -0
  79. package/docs/en/slide/slide-chart-insight.md +52 -0
  80. package/docs/en/slide/slide-columns.md +46 -0
  81. package/docs/en/slide/slide-comparison.md +68 -0
  82. package/docs/en/slide/slide-cover.md +39 -0
  83. package/docs/en/slide/slide-exec-summary.md +47 -0
  84. package/docs/en/slide/slide-heading.md +38 -0
  85. package/docs/en/slide/slide-kpi-grid.md +55 -0
  86. package/docs/en/slide/slide-kpi-hero.md +58 -0
  87. package/docs/en/slide/slide-next-actions.md +49 -0
  88. package/docs/en/slide/slide-scorecard-table.md +54 -0
  89. package/docs/en/slide/slide-section.md +44 -0
  90. package/docs/en/slide/slide-source-line.md +34 -0
  91. package/docs/en/ui/alert-dialog.md +42 -0
  92. package/docs/en/ui/avatar.md +31 -0
  93. package/docs/en/ui/combobox.md +74 -0
  94. package/docs/en/ui/drawer.md +41 -0
  95. package/docs/en/ui/empty.md +1 -1
  96. package/docs/en/ui/error-state.md +4 -3
  97. package/docs/en/ui/field.md +42 -0
  98. package/docs/en/ui/hover-card.md +21 -0
  99. package/docs/en/ui/kbd.md +17 -0
  100. package/docs/en/ui/loading.md +1 -1
  101. package/docs/en/ui/pagination.md +36 -0
  102. package/docs/en/ui/radio-group.md +21 -0
  103. package/docs/en/ui/toast.md +44 -0
  104. package/docs/en/ui/toggle-group.md +4 -3
  105. package/docs/index.json +857 -77
  106. package/docs/ja/changelog.md +2 -0
  107. package/docs/ja/components.md +12 -1
  108. package/docs/ja/doc/delta-text.md +40 -0
  109. package/docs/ja/doc/doc-action-items.md +49 -0
  110. package/docs/ja/doc/doc-callout.md +38 -0
  111. package/docs/ja/doc/doc-data-table.md +60 -0
  112. package/docs/ja/doc/doc-executive-summary.md +64 -0
  113. package/docs/ja/doc/doc-figure.md +56 -0
  114. package/docs/ja/doc/doc-key-findings.md +61 -0
  115. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  116. package/docs/ja/doc/doc-notes-and-sources.md +43 -0
  117. package/docs/ja/doc/doc-report-header.md +46 -0
  118. package/docs/ja/page-types/slide.md +1 -0
  119. package/docs/ja/pages-and-metadata.md +15 -0
  120. package/docs/ja/parts/area-chart.md +49 -25
  121. package/docs/ja/parts/bar-chart.md +50 -24
  122. package/docs/ja/parts/bar-list.md +31 -8
  123. package/docs/ja/parts/chart-frame.md +36 -0
  124. package/docs/ja/parts/delta.md +5 -4
  125. package/docs/ja/parts/donut-chart.md +45 -26
  126. package/docs/ja/parts/funnel-steps.md +27 -8
  127. package/docs/ja/parts/heatmap.md +45 -0
  128. package/docs/ja/parts/kpi-card.md +2 -1
  129. package/docs/ja/parts/legend.md +36 -0
  130. package/docs/ja/parts/line-chart.md +48 -22
  131. package/docs/ja/parts/sample-data.md +61 -0
  132. package/docs/ja/parts/scatter-chart.md +69 -0
  133. package/docs/ja/parts/updated-at.md +27 -0
  134. package/docs/ja/parts/waterfall-chart.md +61 -0
  135. package/docs/ja/slide/slide-chart-full.md +48 -0
  136. package/docs/ja/slide/slide-chart-insight.md +52 -0
  137. package/docs/ja/slide/slide-columns.md +46 -0
  138. package/docs/ja/slide/slide-comparison.md +68 -0
  139. package/docs/ja/slide/slide-cover.md +39 -0
  140. package/docs/ja/slide/slide-exec-summary.md +47 -0
  141. package/docs/ja/slide/slide-heading.md +38 -0
  142. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  143. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  144. package/docs/ja/slide/slide-next-actions.md +49 -0
  145. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  146. package/docs/ja/slide/slide-section.md +44 -0
  147. package/docs/ja/slide/slide-source-line.md +34 -0
  148. package/docs/ja/ui/empty.md +1 -1
  149. package/docs/ja/ui/error-state.md +4 -3
  150. package/docs/ja/ui/loading.md +1 -1
  151. package/docs/ja/ui/toggle-group.md +4 -3
  152. package/package.json +2 -2
  153. package/registry/ui/delta.tsx +7 -4
  154. package/registry/ui/echart.tsx +123 -1
  155. package/registry/ui/kpi-card.tsx +9 -4
  156. package/skills/vantage-pitfalls/SKILL.md +5 -0
  157. package/skills/vantage-slide/SKILL.md +54 -36
  158. package/templates/AGENTS.md +4 -2
  159. package/templates/agents/doc.md +48 -0
  160. package/templates/agents/page.md +22 -1
  161. package/templates/agents/slide.md +70 -2
  162. package/theme.css +10 -7
  163. package/dist/chunk-7DZGJQ3P.js.map +0 -1
  164. package/dist/chunk-CEXAQQ5W.js.map +0 -1
  165. package/dist/chunk-IUPSBD6W.js.map +0 -1
  166. package/dist/chunk-JKLLFVEU.js.map +0 -1
  167. package/dist/chunk-WAMZWZJB.js.map +0 -1
@@ -1,14 +1,16 @@
1
+ import { ChartFrameContext, useChartSurface, resolveChartColors, CHART_OTHER_COLOR, EChart, resolveFillColors } from './chunk-JXFCSF3K.js';
2
+ import { Sparkline } from './chunk-2IAPIOPS.js';
3
+ import { formatDateRange, EMPTY_VALUE, DEFAULT_LOCALE, formatDate, toValueFormatter, formatValue, formatPoints, formatKind, formatDelta, MINUS_SIGN, formatDatesInText } from './chunk-57GHR5LN.js';
1
4
  import { Tooltip, TooltipTrigger, TooltipContent, Badge, SidebarProvider, Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Separator, Input, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Skeleton, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, useIsMobile, Popover, PopoverTrigger, PopoverContent, Calendar, ToggleGroup, ToggleGroupItem, SelectGroup, SelectLabel, Collapsible, CollapsibleTrigger, SidebarMenuButton, SidebarMenuBadge, CollapsibleContent, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, SidebarMenuItem, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Checkbox, Card, CardHeader, CardDescription, CardTitle, CardAction, CardFooter } from './chunk-7S52M2SL.js';
2
5
  import { Button } from './chunk-PDOBHMUQ.js';
3
6
  import { cn } from './chunk-U736PVHY.js';
4
- import { forwardRef, useState, useEffect, createContext, useId, useRef, useMemo, useCallback, useContext, Fragment as Fragment$1 } from 'react';
7
+ import { forwardRef, useState, useEffect, createContext, useId, useMemo, useRef, useCallback, Fragment as Fragment$1, useContext } from 'react';
5
8
  import { cva } from 'class-variance-authority';
6
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { Check, Copy, Download, Search, Columns3, CalendarIcon, ChevronDownIcon, ArrowUp, ArrowDown, ArrowRight, Minus, ChevronRight, ArrowUpDown, XIcon, LoaderIcon, CheckIcon, ChevronDown, X, CircleX, TriangleAlert, CircleCheck } from 'lucide-react';
8
- import { use, init } from 'echarts/core';
9
- import { BarChart, CustomChart, LineChart, PieChart, ScatterChart as ScatterChart$1, HeatmapChart } from 'echarts/charts';
10
- import { GridComponent, LegendComponent, MarkAreaComponent, MarkLineComponent, MarkPointComponent, TooltipComponent, GraphicComponent, VisualMapComponent } from 'echarts/components';
11
- import { CanvasRenderer } from 'echarts/renderers';
10
+ import { Search, Columns3, CalendarIcon, ChevronDownIcon, ArrowUp, ArrowDown, ArrowRight, Minus, ChevronRight, ArrowUpDown, XIcon, LoaderIcon, CheckIcon, Download, ChevronDown, X, CircleX, TriangleAlert, CircleCheck } from 'lucide-react';
11
+ import { use } from 'echarts/core';
12
+ import { GraphicComponent, VisualMapComponent } from 'echarts/components';
13
+ import { ScatterChart as ScatterChart$1, HeatmapChart } from 'echarts/charts';
12
14
  import 'echarts';
13
15
  import { flexRender, useReactTable, getPaginationRowModel, getFilteredRowModel, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
14
16
  import { subMonths, subDays, endOfDay, startOfDay, startOfWeek, subWeeks, endOfWeek, startOfMonth, endOfMonth, isSameDay, format, addMonths } from 'date-fns';
@@ -16,164 +18,6 @@ import { ja } from 'date-fns/locale';
16
18
 
17
19
  // @squadbase/vantage — generated build. Do not edit.
18
20
 
19
- // ../squadkit/registry/lib/format.ts
20
- var DEFAULT_LOCALE = "ja-JP";
21
- var EMPTY_VALUE = "\u2014";
22
- var MINUS_SIGN = "\u2212";
23
- var PERCENT_DIGITS = 1;
24
- var DEFAULT_CURRENCY = "JPY";
25
- var MULTIPLE_SUFFIX = "\xD7";
26
- var POINTS_SUFFIX = "pt";
27
- function normalize(format2) {
28
- if (format2 === void 0) return { type: "compact" };
29
- return typeof format2 === "string" ? { type: format2 } : format2;
30
- }
31
- function formatKind(format2) {
32
- return normalize(format2).type;
33
- }
34
- function digitOptions(digits, defaultMax, significantDigits) {
35
- if (significantDigits !== void 0) return { maximumSignificantDigits: significantDigits };
36
- if (digits !== void 0) return { minimumFractionDigits: digits, maximumFractionDigits: digits };
37
- return defaultMax === void 0 ? {} : { maximumFractionDigits: defaultMax };
38
- }
39
- function formatParts(locale, options, value) {
40
- if (options.notation === "compact") {
41
- const compact = new Intl.NumberFormat(locale, {
42
- ...options,
43
- useGrouping: "always"
44
- }).formatToParts(value);
45
- if (!compact.some((p) => p.type === "compact")) return formatParts(locale, { ...options, notation: "standard" }, value);
46
- return joinParts(compact);
47
- }
48
- return joinParts(new Intl.NumberFormat(locale, options).formatToParts(value));
49
- }
50
- var joinParts = (parts) => parts.map((p) => p.type === "currency" ? p.value.normalize("NFKC") : p.type === "minusSign" ? MINUS_SIGN : p.value).join("");
51
- function formatValue(value, format2, locale = DEFAULT_LOCALE, options) {
52
- if (value === null || value === void 0 || Number.isNaN(value)) return EMPTY_VALUE;
53
- const { type, digits, currency, notation, unit, divisor, durationUnit } = normalize(format2);
54
- if (divisor !== void 0 && Number.isFinite(divisor) && divisor !== 0) value = value / divisor;
55
- const signDisplay = options?.signDisplay ?? "auto";
56
- const sig = options?.significantDigits;
57
- const withUnit = (s) => unit ? `${s}${unit}` : s;
58
- switch (type) {
59
- case "number":
60
- return withUnit(formatParts(locale, { ...digitOptions(digits, 2, sig), signDisplay }, value));
61
- case "percent":
62
- return formatParts(locale, { style: "percent", ...digitOptions(digits ?? PERCENT_DIGITS, void 0, sig), signDisplay }, value);
63
- case "currency":
64
- return withUnit(
65
- formatParts(
66
- locale,
67
- {
68
- style: "currency",
69
- currency: currency ?? DEFAULT_CURRENCY,
70
- notation: notation ?? "compact",
71
- ...digitOptions(digits, notation === "standard" ? void 0 : 1, sig),
72
- signDisplay
73
- },
74
- value
75
- )
76
- );
77
- case "multiple":
78
- return `${formatParts(locale, { ...digitOptions(digits, 2, sig), signDisplay }, value)}${unit || MULTIPLE_SUFFIX}`;
79
- case "compact":
80
- return withUnit(formatParts(locale, { ...digitOptions(digits, 1, sig), signDisplay, notation: "compact" }, value));
81
- case "duration":
82
- return formatDuration(value, durationUnit ?? "second", locale, digits, signDisplay);
83
- }
84
- }
85
- var SECONDS_PER = { second: 1, minute: 60, hour: 3600, day: 86400 };
86
- function durationWords(locale) {
87
- return locale.toLowerCase().startsWith("ja") ? { day: "\u65E5", hour: "\u6642\u9593", minute: "\u5206", second: "\u79D2", sep: "" } : { day: "d", hour: "h", minute: "min", second: "s", sep: " " };
88
- }
89
- function formatDuration(value, unit, locale, digits, signDisplay) {
90
- const w = durationWords(locale);
91
- const abs = Math.round(Math.abs(value) * SECONDS_PER[unit]);
92
- const join = (...parts) => parts.filter(([n]) => n !== 0).map(([n, u]) => `${n}${w.sep}${u}`).join(w.sep) || `0${w.sep}${parts.at(-1)?.[1] ?? w.second}`;
93
- let body;
94
- let zero = false;
95
- if (abs >= 86400) {
96
- const days = new Intl.NumberFormat(locale, { maximumFractionDigits: digits ?? 1, minimumFractionDigits: digits ?? 0 });
97
- body = `${days.format(abs / 86400)}${w.sep}${w.day}`;
98
- } else if (abs >= 3600) {
99
- const minutes = Math.round(abs / 60);
100
- body = join([Math.floor(minutes / 60), w.hour], [minutes % 60, w.minute]);
101
- } else if (abs >= 60) {
102
- body = join([Math.floor(abs / 60), w.minute], [abs % 60, w.second]);
103
- } else {
104
- zero = abs === 0;
105
- body = `${abs}${w.sep}${w.second}`;
106
- }
107
- const sign = zero ? "" : value < 0 ? MINUS_SIGN : signDisplay === "exceptZero" ? "+" : "";
108
- return `${sign}${body}`;
109
- }
110
- function formatDelta(value, format2, locale = DEFAULT_LOCALE) {
111
- return formatValue(value, format2, locale, { signDisplay: "exceptZero" });
112
- }
113
- function formatPoints(difference, locale = DEFAULT_LOCALE, options) {
114
- if (difference === null || difference === void 0 || Number.isNaN(difference)) return EMPTY_VALUE;
115
- const digits = options?.digits ?? PERCENT_DIGITS;
116
- const number = formatParts(
117
- locale,
118
- { minimumFractionDigits: digits, maximumFractionDigits: digits, signDisplay: options?.signDisplay ?? "exceptZero" },
119
- difference * 100
120
- );
121
- return `${number}${POINTS_SUFFIX}`;
122
- }
123
- function toValueFormatter(format2, locale = DEFAULT_LOCALE) {
124
- return (value) => formatValue(value, format2, locale);
125
- }
126
- var DATE_STYLE_OPTIONS = {
127
- date: { year: "numeric", month: "2-digit", day: "2-digit" },
128
- datetime: { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hourCycle: "h23" },
129
- month: { month: "short" },
130
- "year-month": { year: "numeric", month: "long" },
131
- year: { year: "numeric" }
132
- };
133
- var CALENDAR_DATE = /^\d{4}-\d{2}(-\d{2})?$/;
134
- function formatDate(value, style = "date", locale = DEFAULT_LOCALE, options) {
135
- if (value === null || value === void 0 || value === "") return EMPTY_VALUE;
136
- const calendar = typeof value === "string" && CALENDAR_DATE.test(value);
137
- const date = value instanceof Date ? value : new Date(value);
138
- if (!Number.isFinite(date.getTime())) return EMPTY_VALUE;
139
- return new Intl.DateTimeFormat(locale, {
140
- ...DATE_STYLE_OPTIONS[style],
141
- timeZone: calendar ? "UTC" : options?.timeZone
142
- }).format(date);
143
- }
144
- function formatDateRange(start, end, options) {
145
- const locale = options?.locale ?? DEFAULT_LOCALE;
146
- const parse = (value) => {
147
- if (value === null || value === void 0 || value === "") return null;
148
- const calendar = typeof value === "string" && CALENDAR_DATE.test(value);
149
- const date = value instanceof Date ? value : new Date(value);
150
- if (!Number.isFinite(date.getTime())) return null;
151
- return { date, timeZone: calendar ? "UTC" : options?.timeZone };
152
- };
153
- const a = parse(start);
154
- const b = parse(end);
155
- if (!a || !b) return EMPTY_VALUE;
156
- const full = (x, withYear) => new Intl.DateTimeFormat(locale, {
157
- ...withYear ? { year: "numeric" } : {},
158
- month: "numeric",
159
- day: "numeric",
160
- timeZone: x.timeZone
161
- }).format(x.date);
162
- const year = (x) => new Intl.DateTimeFormat("en-US", { year: "numeric", timeZone: x.timeZone }).format(x.date);
163
- const startText = full(a, true);
164
- const sameYear = year(a) === year(b);
165
- const endFull = full(b, true);
166
- if (startText === endFull) return startText;
167
- const separator = locale.toLowerCase().startsWith("ja") ? "\u301C" : " \u2013 ";
168
- return `${startText}${separator}${sameYear ? full(b, false) : endFull}`;
169
- }
170
- function formatDatesInText(text, locale = DEFAULT_LOCALE) {
171
- return text.replace(
172
- /(?<![\d-])(\d{4})-(0[1-9]|1[0-2])(-(0[1-9]|[12]\d|3[01]))?(?![\d-])/g,
173
- (match, _y, _m, day) => formatDate(match, day ? "date" : "year-month", locale)
174
- );
175
- }
176
-
177
21
  // ../squadkit/registry/lib/relative-time.ts
178
22
  var SECOND = 1e3;
179
23
  var MINUTE = 60 * SECOND;
@@ -807,245 +651,6 @@ function DashboardCardPreset({
807
651
  footer && /* @__PURE__ */ jsx(DashboardCardFooter, { className: cn(subgrid === 3 && "row-start-3", footerClassName), children: footer })
808
652
  ] }) });
809
653
  }
810
- var CHART_OTHER_COLOR = "color-mix(in oklab, var(--neutral) 50%, var(--background))";
811
- var ChartFrameContext = createContext(false);
812
- var SERIES_TOKENS = ["--chart-1", "--chart-2", "--chart-3", "--chart-4", "--chart-5"];
813
- var tokenScopes = /* @__PURE__ */ new WeakMap();
814
- var OPTION_COLOR_TOKENS = [
815
- "--background",
816
- "--card",
817
- "--muted",
818
- "--primary",
819
- "--destructive",
820
- ...["positive", "negative", "warning", "neutral", "info"].flatMap((tone) => ["", "-fill", "-subtle"].map((suffix) => `--${tone}${suffix}`))
821
- ];
822
- var normalizeContext;
823
- var ZRENDER_COLOR_RE = /^(?:#[0-9a-f]{6}|rgba?\()/i;
824
- function toCanvasColor(value) {
825
- const raw = value.trim();
826
- if (!raw) return null;
827
- if (normalizeContext === void 0) {
828
- const canvas = document.createElement("canvas");
829
- canvas.width = 1;
830
- canvas.height = 1;
831
- normalizeContext = canvas.getContext("2d", { willReadFrequently: true });
832
- }
833
- const ctx = normalizeContext;
834
- if (!ctx) return raw;
835
- ctx.fillStyle = "#000000";
836
- ctx.fillStyle = raw;
837
- const onBlack = ctx.fillStyle;
838
- ctx.fillStyle = "#ffffff";
839
- ctx.fillStyle = raw;
840
- if (onBlack !== ctx.fillStyle || typeof onBlack !== "string") return null;
841
- if (ZRENDER_COLOR_RE.test(onBlack)) return onBlack;
842
- ctx.clearRect(0, 0, 1, 1);
843
- ctx.fillRect(0, 0, 1, 1);
844
- const [r = 0, g = 0, b = 0, a = 0] = ctx.getImageData(0, 0, 1, 1).data;
845
- return a === 255 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${Math.round(a / 255 * 1e3) / 1e3})`;
846
- }
847
- function readChartTokens(el) {
848
- if (typeof document === "undefined") return null;
849
- const target = el ?? document.documentElement;
850
- if (!target) return null;
851
- const styles = getComputedStyle(target);
852
- const read = (name) => toCanvasColor(styles.getPropertyValue(name));
853
- const series = [];
854
- for (const token of SERIES_TOKENS) {
855
- const color = read(token);
856
- if (color) series.push(color);
857
- }
858
- const tokens = {
859
- series,
860
- colors: Object.fromEntries(OPTION_COLOR_TOKENS.map((name) => [name, styles.getPropertyValue(name).trim()])),
861
- surface: readChartSurface(target),
862
- ...styles.fontFamily ? { fontFamily: styles.fontFamily } : {},
863
- foreground: read("--foreground"),
864
- mutedForeground: read("--muted-foreground"),
865
- border: read("--border"),
866
- popover: read("--popover"),
867
- popoverForeground: read("--popover-foreground")
868
- };
869
- tokenScopes.set(tokens, target);
870
- return tokens;
871
- }
872
- function sameChartTokens(a, b) {
873
- if (a === b) return true;
874
- if (!a || !b) return false;
875
- return tokenScopes.get(a) === tokenScopes.get(b) && a.surface === b.surface && Object.keys(a.colors ?? {}).length === Object.keys(b.colors ?? {}).length && Object.entries(a.colors ?? {}).every(([name, value]) => b.colors?.[name] === value) && a.series.length === b.series.length && a.series.every((color, i) => color === b.series[i]) && a.fontFamily === b.fontFamily && a.foreground === b.foreground && a.mutedForeground === b.mutedForeground && a.border === b.border && a.popover === b.popover && a.popoverForeground === b.popoverForeground;
876
- }
877
- function watchChartTokens(onChange, scope) {
878
- if (typeof document === "undefined") return () => {
879
- };
880
- let frame = 0;
881
- const schedule = () => {
882
- if (frame) return;
883
- frame = requestAnimationFrame(() => {
884
- frame = 0;
885
- onChange();
886
- });
887
- };
888
- const themeObserver = new MutationObserver(schedule);
889
- const attributeFilter = ["class", "style", "data-theme"];
890
- for (let node = scope ?? document.body ?? document.documentElement; node; node = node.parentElement) {
891
- themeObserver.observe(node, { attributes: true, attributeFilter });
892
- }
893
- const styleObserver = new MutationObserver(schedule);
894
- if (document.head) {
895
- styleObserver.observe(document.head, {
896
- childList: true,
897
- subtree: true,
898
- characterData: true,
899
- attributes: true,
900
- attributeFilter: ["href", "media", "disabled"]
901
- });
902
- }
903
- const onLoad = (event) => {
904
- if (event.target instanceof HTMLLinkElement) schedule();
905
- };
906
- document.addEventListener("load", onLoad, true);
907
- const media = window.matchMedia("(prefers-color-scheme: dark)");
908
- media.addEventListener("change", schedule);
909
- return () => {
910
- if (frame) cancelAnimationFrame(frame);
911
- themeObserver.disconnect();
912
- styleObserver.disconnect();
913
- document.removeEventListener("load", onLoad, true);
914
- media.removeEventListener("change", schedule);
915
- };
916
- }
917
- function axisTheme(tokens, splitLine) {
918
- const line = tokens.border ?? void 0;
919
- return {
920
- axisLine: { show: false },
921
- axisTick: { show: false },
922
- axisLabel: { show: true, color: tokens.mutedForeground ?? void 0, fontSize: 12 },
923
- // Faint horizontal rules only: the border colour at low opacity.
924
- splitLine: { show: splitLine, lineStyle: { color: line ? [line] : void 0, opacity: 0.5, width: 1 } },
925
- splitArea: { show: false }
926
- };
927
- }
928
- function buildChartTheme(tokens) {
929
- const text = tokens.foreground ?? void 0;
930
- const muted = tokens.mutedForeground ?? void 0;
931
- const line = tokens.border ?? void 0;
932
- return {
933
- // Let the page background show through: charts sit on cards, not on a canvas.
934
- backgroundColor: "transparent",
935
- ...tokens.series.length > 0 ? { color: tokens.series } : {},
936
- textStyle: { color: text, ...tokens.fontFamily ? { fontFamily: tokens.fontFamily } : {} },
937
- title: { textStyle: { color: text }, subtextStyle: { color: muted } },
938
- legend: { textStyle: { color: muted } },
939
- categoryAxis: axisTheme(tokens, false),
940
- valueAxis: axisTheme(tokens, true),
941
- logAxis: axisTheme(tokens, true),
942
- timeAxis: axisTheme(tokens, true),
943
- tooltip: {
944
- // ECharts' default 0.4s transform lags the tooltip ~300ms behind the cursor.
945
- transitionDuration: 0,
946
- backgroundColor: tokens.popover ?? void 0,
947
- borderColor: line,
948
- borderWidth: 1,
949
- padding: [8, 12],
950
- // Rounded card with a soft shadow; in dark mode the shadow barely shows, so the border carries the edge.
951
- extraCssText: "border-radius:8px;box-shadow:var(--shadow-card, 0 4px 12px rgb(0 0 0 / 0.08));",
952
- textStyle: {
953
- color: tokens.popoverForeground ?? void 0,
954
- fontSize: 12,
955
- ...tokens.fontFamily ? { fontFamily: tokens.fontFamily } : {}
956
- },
957
- axisPointer: { lineStyle: { color: line }, crossStyle: { color: line } }
958
- }
959
- };
960
- }
961
- function useChartTokens(scope) {
962
- const [tokens, setTokens] = useState(() => readChartTokens());
963
- const tokensRef = useRef(tokens);
964
- useEffect(() => {
965
- const target = scope && "current" in scope ? scope.current : scope;
966
- const sync = () => {
967
- const next = readChartTokens(target);
968
- if (sameChartTokens(tokensRef.current, next)) return;
969
- tokensRef.current = next;
970
- setTokens(next);
971
- };
972
- sync();
973
- return watchChartTokens(sync, target);
974
- }, [scope]);
975
- return tokens;
976
- }
977
- var SERIES_TOKEN_NAME_RE = /^chart-([1-5])$/;
978
- var TONE_NAME_RE = /^(?:positive|warning|negative|neutral|info)(?:-fill)?$/;
979
- var CSS_VAR_RE = /^var\(\s*(--[\w-]+)\s*(?:,\s*(.+))?\)$/;
980
- var EMBEDDED_VAR_RE = /var\(\s*(--[\w-]+)\s*\)/g;
981
- function resolveChartColors(colors, tokens) {
982
- return colors.map((color) => {
983
- const token = SERIES_TOKEN_NAME_RE.exec(color.trim());
984
- if (token) return tokens?.series[Number(token[1]) - 1] ?? "";
985
- if (TONE_NAME_RE.test(color.trim())) {
986
- if (typeof document === "undefined") return "";
987
- const target = (tokens && tokenScopes.get(tokens)) ?? document.documentElement;
988
- return toCanvasColor(getComputedStyle(target).getPropertyValue(`--${color.trim()}`)) ?? "";
989
- }
990
- if (typeof document === "undefined") return color;
991
- let value = color.trim();
992
- const cssVar = CSS_VAR_RE.exec(value);
993
- const styles = getComputedStyle((tokens && tokenScopes.get(tokens)) ?? document.documentElement);
994
- if (cssVar) {
995
- value = styles.getPropertyValue(cssVar[1]).trim() || (cssVar[2] ?? "").trim();
996
- } else if (value.includes("var(")) {
997
- value = value.replace(EMBEDDED_VAR_RE, (_, name) => styles.getPropertyValue(name).trim());
998
- }
999
- return toCanvasColor(value) ?? "";
1000
- });
1001
- }
1002
- function resolveFillColors(tokens) {
1003
- const [positive = "", warning = "", negative = "", neutral = ""] = resolveChartColors(
1004
- ["positive-fill", "warning-fill", "negative-fill", "neutral-fill"],
1005
- tokens
1006
- );
1007
- return { positive, warning, negative, neutral };
1008
- }
1009
- var TRANSPARENT_RE = /^(?:transparent|rgba\([^)]*,\s*0(?:\.0+)?\))$/i;
1010
- function readChartSurface(el) {
1011
- if (typeof document === "undefined") return null;
1012
- for (let node = el; node; node = node.parentElement) {
1013
- const bg = getComputedStyle(node).backgroundColor.trim();
1014
- if (bg && !TRANSPARENT_RE.test(bg)) {
1015
- const color = toCanvasColor(bg);
1016
- if (color) return color;
1017
- }
1018
- }
1019
- return toCanvasColor(getComputedStyle(el ?? document.documentElement).getPropertyValue("--background"));
1020
- }
1021
- var WIDTH_BUCKET = 40;
1022
- function useChartSurface(forwarded, tokens) {
1023
- const [node, setNode] = useState(null);
1024
- const scopedTokens = useChartTokens(node);
1025
- const [surface, setSurface] = useState(void 0);
1026
- const [width, setWidth] = useState(void 0);
1027
- const ref = useCallback(
1028
- (el) => {
1029
- setNode(el);
1030
- if (typeof forwarded === "function") forwarded(el);
1031
- else if (forwarded) forwarded.current = el;
1032
- },
1033
- [forwarded]
1034
- );
1035
- useEffect(() => {
1036
- if (!node) return;
1037
- setSurface(readChartSurface(node) ?? void 0);
1038
- }, [node, tokens, scopedTokens]);
1039
- useEffect(() => {
1040
- if (!node || typeof ResizeObserver === "undefined") return;
1041
- const update = (w) => setWidth(Math.floor(w / WIDTH_BUCKET) * WIDTH_BUCKET);
1042
- update(node.getBoundingClientRect().width);
1043
- const observer = new ResizeObserver((entries) => update(entries[0]?.contentRect.width ?? 0));
1044
- observer.observe(node);
1045
- return () => observer.disconnect();
1046
- }, [node]);
1047
- return { ref, surface, width, tokens: scopedTokens };
1048
- }
1049
654
  var DEFAULT_CHART_HEIGHT = 288;
1050
655
  var DEFAULT_EMPTY_TITLE = "\u8868\u793A\u3067\u304D\u308B\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093";
1051
656
  var ChartFrame = forwardRef(function ChartFrame2({
@@ -1129,334 +734,6 @@ function ChartEmpty({ title, description, action }) {
1129
734
  }
1130
735
  );
1131
736
  }
1132
- use([
1133
- BarChart,
1134
- CustomChart,
1135
- LineChart,
1136
- PieChart,
1137
- GridComponent,
1138
- LegendComponent,
1139
- MarkAreaComponent,
1140
- MarkLineComponent,
1141
- MarkPointComponent,
1142
- TooltipComponent,
1143
- CanvasRenderer
1144
- ]);
1145
- var HEADER_PAD_X = 16;
1146
- var HEADER_PAD_TOP = 16;
1147
- var HEADER_PAD_BOTTOM = 12;
1148
- var HEADER_LINE_HEIGHT = 20;
1149
- var HEADER_GAP = 4;
1150
- var HEADER_FONT_SIZE = 14;
1151
- function wrapChartText(text, maxWidth, measure) {
1152
- const lines = [];
1153
- let line = "";
1154
- for (const ch of text) {
1155
- if (ch === "\n") {
1156
- lines.push(line);
1157
- line = "";
1158
- continue;
1159
- }
1160
- if (line !== "" && measure(line + ch) > maxWidth) {
1161
- lines.push(line);
1162
- line = ch.trim() === "" ? "" : ch;
1163
- } else {
1164
- line += ch;
1165
- }
1166
- }
1167
- if (line !== "" || lines.length === 0) lines.push(line);
1168
- return lines.filter((l, i) => l !== "" || i < lines.length - 1);
1169
- }
1170
- function chartExportHeaderLayout(header, width, measure) {
1171
- const title = header?.title?.trim();
1172
- const summary = header?.summary?.trim();
1173
- if (!title && !summary) return { lines: [], height: 0 };
1174
- const room = Math.max(40, width - HEADER_PAD_X * 2);
1175
- const lines = [
1176
- ...title ? wrapChartText(title, room, (t) => measure(t, "title")).map((text) => ({ text, kind: "title" })) : [],
1177
- ...summary ? wrapChartText(summary, room, (t) => measure(t, "summary")).map((text) => ({ text, kind: "summary" })) : []
1178
- ];
1179
- const gap = title && summary ? HEADER_GAP : 0;
1180
- return { lines, height: HEADER_PAD_TOP + lines.length * HEADER_LINE_HEIGHT + gap + HEADER_PAD_BOTTOM };
1181
- }
1182
- function loadImage(src) {
1183
- return new Promise((resolve, reject) => {
1184
- const image = new Image();
1185
- image.onload = () => resolve(image);
1186
- image.onerror = () => reject(new Error("PNG \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F"));
1187
- image.src = src;
1188
- });
1189
- }
1190
- async function pngWithHeader(dataUrl, header, look, pixelRatio) {
1191
- const image = await loadImage(dataUrl);
1192
- const width = image.width / pixelRatio;
1193
- const plotHeight = image.height / pixelRatio;
1194
- const canvas = document.createElement("canvas");
1195
- const ctx = canvas.getContext("2d");
1196
- if (!ctx) return dataUrl;
1197
- const font = (kind) => `${kind === "title" ? 500 : 400} ${HEADER_FONT_SIZE}px ${look.fontFamily}`;
1198
- ctx.font = font("title");
1199
- const layout = chartExportHeaderLayout(header, width, (text, kind) => {
1200
- ctx.font = font(kind);
1201
- return ctx.measureText(text).width;
1202
- });
1203
- if (layout.height === 0) return dataUrl;
1204
- canvas.width = Math.round(image.width);
1205
- canvas.height = Math.round((layout.height + plotHeight) * pixelRatio);
1206
- ctx.scale(pixelRatio, pixelRatio);
1207
- ctx.fillStyle = look.background;
1208
- ctx.fillRect(0, 0, width, layout.height + plotHeight);
1209
- ctx.textBaseline = "middle";
1210
- let y = HEADER_PAD_TOP;
1211
- let previous = null;
1212
- for (const line of layout.lines) {
1213
- if (previous === "title" && line.kind === "summary") y += HEADER_GAP;
1214
- ctx.font = font(line.kind);
1215
- ctx.fillStyle = line.kind === "title" ? look.color : look.mutedColor;
1216
- ctx.fillText(line.text, HEADER_PAD_X, y + HEADER_LINE_HEIGHT / 2);
1217
- y += HEADER_LINE_HEIGHT;
1218
- previous = line.kind;
1219
- }
1220
- ctx.drawImage(image, 0, layout.height, width, plotHeight);
1221
- return canvas.toDataURL("image/png");
1222
- }
1223
- function useResolvedChartColors(colors) {
1224
- const tokens = useChartTokens();
1225
- const key = colors.join("\0");
1226
- return useMemo(() => resolveChartColors(colors, tokens), [key, tokens]);
1227
- }
1228
- var COMPONENT_MAIN_TYPES = /* @__PURE__ */ new Set([
1229
- "title",
1230
- "legend",
1231
- "grid",
1232
- "xAxis",
1233
- "yAxis",
1234
- "polar",
1235
- "radiusAxis",
1236
- "angleAxis",
1237
- "radar",
1238
- "dataZoom",
1239
- "visualMap",
1240
- "tooltip",
1241
- "axisPointer",
1242
- "toolbox",
1243
- "brush",
1244
- "geo",
1245
- "parallel",
1246
- "parallelAxis",
1247
- "singleAxis",
1248
- "graphic",
1249
- "calendar",
1250
- "dataset",
1251
- "series",
1252
- "matrix",
1253
- "thumbnail"
1254
- ]);
1255
- function echartSetOptionOpts(prev, next) {
1256
- const special = (o) => "timeline" in o || "baseOption" in o || "options" in o || "media" in o;
1257
- if (!prev || special(prev) || special(next)) return { notMerge: true, lazyUpdate: true };
1258
- const types = /* @__PURE__ */ new Set();
1259
- for (const key of [...Object.keys(prev), ...Object.keys(next)]) if (COMPONENT_MAIN_TYPES.has(key)) types.add(key);
1260
- return { notMerge: false, replaceMerge: [...types], lazyUpdate: true };
1261
- }
1262
- function withGraphicFont(option, fontFamily) {
1263
- const graphic = option.graphic;
1264
- if (!fontFamily || !Array.isArray(graphic)) return option;
1265
- return {
1266
- ...option,
1267
- graphic: graphic.map(
1268
- (g) => g && g.type === "text" && g.style && !g.style.fontFamily ? { ...g, style: { ...g.style, fontFamily } } : g
1269
- )
1270
- };
1271
- }
1272
- function withMotionPreference(option, reducedMotion) {
1273
- return { ...option, animation: reducedMotion ? false : option.animation ?? true };
1274
- }
1275
- var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
1276
- function usePrefersReducedMotion() {
1277
- const [reduced, setReduced] = useState(
1278
- () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(REDUCED_MOTION_QUERY).matches
1279
- );
1280
- useEffect(() => {
1281
- if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1282
- const media = window.matchMedia(REDUCED_MOTION_QUERY);
1283
- const sync = () => setReduced(media.matches);
1284
- sync();
1285
- media.addEventListener("change", sync);
1286
- return () => media.removeEventListener("change", sync);
1287
- }, []);
1288
- return reduced;
1289
- }
1290
- var EChart = forwardRef(function EChart2({
1291
- option,
1292
- height,
1293
- loading = false,
1294
- theme,
1295
- onEvents,
1296
- ariaLabel,
1297
- className,
1298
- actions = false,
1299
- fileName = "chart.png",
1300
- exportHeader
1301
- }, ref) {
1302
- const containerRef = useRef(null);
1303
- const [instance, setInstance] = useState(null);
1304
- const [copied, setCopied] = useState(false);
1305
- const tokens = useChartTokens(containerRef);
1306
- const reducedMotion = usePrefersReducedMotion();
1307
- const appliedRef = useRef(null);
1308
- const autoTheme = useMemo(() => tokens ? buildChartTheme(tokens) : void 0, [tokens]);
1309
- const resolvedTheme = theme ?? autoTheme;
1310
- useEffect(() => {
1311
- const container = containerRef.current;
1312
- if (!container) return;
1313
- const inst = init(container, resolvedTheme, { renderer: "canvas" });
1314
- appliedRef.current = null;
1315
- container.dataset.rendering = "";
1316
- inst.on("finished", () => {
1317
- delete container.dataset.rendering;
1318
- });
1319
- setInstance(inst);
1320
- let frame = 0;
1321
- const observer = new ResizeObserver(() => {
1322
- cancelAnimationFrame(frame);
1323
- frame = requestAnimationFrame(() => {
1324
- if (!inst.isDisposed()) inst.resize();
1325
- });
1326
- });
1327
- observer.observe(container);
1328
- return () => {
1329
- observer.disconnect();
1330
- cancelAnimationFrame(frame);
1331
- inst.dispose();
1332
- };
1333
- }, [resolvedTheme]);
1334
- useEffect(() => {
1335
- if (!instance || instance.isDisposed()) return;
1336
- if (containerRef.current) containerRef.current.dataset.rendering = "";
1337
- const next = withGraphicFont(withMotionPreference(option, reducedMotion), theme === void 0 ? tokens?.fontFamily : void 0);
1338
- instance.setOption(next, echartSetOptionOpts(appliedRef.current, next));
1339
- appliedRef.current = next;
1340
- }, [instance, option, reducedMotion, theme, tokens?.fontFamily]);
1341
- useEffect(() => {
1342
- if (!instance || instance.isDisposed()) return;
1343
- if (loading) instance.showLoading();
1344
- else instance.hideLoading();
1345
- }, [instance, loading]);
1346
- useEffect(() => {
1347
- if (!instance || instance.isDisposed() || !onEvents) return;
1348
- const entries = Object.entries(onEvents);
1349
- for (const [event, handler] of entries) {
1350
- instance.on(event, handler);
1351
- }
1352
- return () => {
1353
- if (instance.isDisposed()) return;
1354
- for (const [event, handler] of entries) {
1355
- instance.off(event, handler);
1356
- }
1357
- };
1358
- }, [instance, onEvents]);
1359
- const includeTitle = typeof actions === "object" ? actions.includeTitle ?? true : true;
1360
- const getPngDataUrl = useCallback(async () => {
1361
- if (!instance) return null;
1362
- let backgroundColor = "#ffffff";
1363
- for (let el = containerRef.current; el; el = el.parentElement) {
1364
- const bg = getComputedStyle(el).backgroundColor;
1365
- if (bg && bg !== "rgba(0, 0, 0, 0)" && bg !== "transparent") {
1366
- backgroundColor = bg;
1367
- break;
1368
- }
1369
- }
1370
- const pixelRatio = 2;
1371
- const dataUrl = instance.getDataURL({ type: "png", pixelRatio, backgroundColor });
1372
- if (!includeTitle || !exportHeader || !(exportHeader.title || exportHeader.summary) || !containerRef.current) return dataUrl;
1373
- try {
1374
- const style = getComputedStyle(containerRef.current);
1375
- return await pngWithHeader(
1376
- dataUrl,
1377
- exportHeader,
1378
- { background: backgroundColor, color: style.color, mutedColor: tokens?.mutedForeground ?? style.color, fontFamily: style.fontFamily },
1379
- pixelRatio
1380
- );
1381
- } catch {
1382
- return dataUrl;
1383
- }
1384
- }, [instance, includeTitle, exportHeader, tokens]);
1385
- const handleCopy = useCallback(async () => {
1386
- const dataUrl = await getPngDataUrl();
1387
- if (!dataUrl) return;
1388
- try {
1389
- const blob = await (await fetch(dataUrl)).blob();
1390
- await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
1391
- setCopied(true);
1392
- setTimeout(() => setCopied(false), 2e3);
1393
- } catch {
1394
- }
1395
- }, [getPngDataUrl]);
1396
- const handleDownload = useCallback(async () => {
1397
- const dataUrl = await getPngDataUrl();
1398
- if (!dataUrl) return;
1399
- const link = document.createElement("a");
1400
- link.href = dataUrl;
1401
- link.download = fileName;
1402
- link.click();
1403
- }, [getPngDataUrl, fileName]);
1404
- const inFrame = useContext(ChartFrameContext);
1405
- const styleHeight = height == null ? void 0 : typeof height === "number" ? `${height}px` : height;
1406
- return /* @__PURE__ */ jsxs(
1407
- "div",
1408
- {
1409
- ref,
1410
- "data-slot": "echart",
1411
- className: cn("group relative w-full", height == null && "h-[400px]", className),
1412
- style: styleHeight != null ? { height: styleHeight } : void 0,
1413
- children: [
1414
- /* @__PURE__ */ jsx(
1415
- "div",
1416
- {
1417
- ref: containerRef,
1418
- "data-slot": "echart-canvas",
1419
- className: "h-full w-full",
1420
- role: inFrame ? void 0 : "img",
1421
- "aria-label": inFrame ? void 0 : ariaLabel ?? "\u30C1\u30E3\u30FC\u30C8"
1422
- }
1423
- ),
1424
- actions && /* @__PURE__ */ jsxs(
1425
- "div",
1426
- {
1427
- "data-slot": "echart-actions",
1428
- className: "absolute top-2 right-2 z-10 flex gap-1 pointer-events-none opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100 focus-within:pointer-events-auto focus-within:opacity-100 [@media(hover:none)]:pointer-events-auto [@media(hover:none)]:opacity-100",
1429
- children: [
1430
- /* @__PURE__ */ jsx(
1431
- Button,
1432
- {
1433
- type: "button",
1434
- variant: "ghost",
1435
- size: "icon-sm",
1436
- onClick: handleCopy,
1437
- "aria-label": copied ? "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F" : "PNG \u3092\u30AF\u30EA\u30C3\u30D7\u30DC\u30FC\u30C9\u306B\u30B3\u30D4\u30FC",
1438
- children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" })
1439
- }
1440
- ),
1441
- /* @__PURE__ */ jsx(
1442
- Button,
1443
- {
1444
- type: "button",
1445
- variant: "ghost",
1446
- size: "icon-sm",
1447
- onClick: handleDownload,
1448
- "aria-label": "PNG \u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9",
1449
- children: /* @__PURE__ */ jsx(Download, { className: "size-4" })
1450
- }
1451
- )
1452
- ]
1453
- }
1454
- )
1455
- ]
1456
- }
1457
- );
1458
- });
1459
- EChart.displayName = "EChart";
1460
737
 
1461
738
  // ../squadkit/registry/lib/chart-utils.ts
1462
739
  var ROOT_PROP_KEYS = /* @__PURE__ */ new Set(["id", "style", "role", "tabIndex", "lang", "hidden"]);
@@ -3564,8 +2841,8 @@ function BarChartImpl({
3564
2841
  }
3565
2842
  );
3566
2843
  }
3567
- var BarChart2 = forwardRef(BarChartImpl);
3568
- BarChart2.displayName = "BarChart";
2844
+ var BarChart = forwardRef(BarChartImpl);
2845
+ BarChart.displayName = "BarChart";
3569
2846
  var NO_ROWS3 = [];
3570
2847
  function LineChartImpl({
3571
2848
  data = NO_ROWS3,
@@ -3750,8 +3027,8 @@ function LineChartImpl({
3750
3027
  }
3751
3028
  );
3752
3029
  }
3753
- var LineChart2 = forwardRef(LineChartImpl);
3754
- LineChart2.displayName = "LineChart";
3030
+ var LineChart = forwardRef(LineChartImpl);
3031
+ LineChart.displayName = "LineChart";
3755
3032
  function useElementWidth() {
3756
3033
  const [node, setNode] = useState(null);
3757
3034
  const [width, setWidth] = useState(null);
@@ -5753,149 +5030,6 @@ function HeatmapLegend({
5753
5030
  }
5754
5031
  var Heatmap = forwardRef(HeatmapImpl);
5755
5032
  Heatmap.displayName = "Heatmap";
5756
- var VB_WIDTH = 100;
5757
- function normalizeData(values, height, vPad = 2) {
5758
- const min = Math.min(...values);
5759
- const max = Math.max(...values);
5760
- const range = max - min;
5761
- const drawHeight = height - vPad * 2;
5762
- if (range === 0) return values.map(() => vPad + drawHeight / 2);
5763
- return values.map((v) => height - vPad - (v - min) / range * drawHeight);
5764
- }
5765
- function buildLinePath(ys) {
5766
- if (ys.length === 0) return "";
5767
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
5768
- return ys.map((y, i) => `${i === 0 ? "M" : "L"}${(i * step).toFixed(2)},${y.toFixed(2)}`).join(" ");
5769
- }
5770
- function buildAreaPath(ys, height) {
5771
- if (ys.length === 0) return "";
5772
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
5773
- const lastX = ((ys.length - 1) * step).toFixed(2);
5774
- return `${buildLinePath(ys)} L${lastX},${height} L0,${height} Z`;
5775
- }
5776
- function sparklineHighlightPoints(values) {
5777
- if (values.length === 0) return [];
5778
- const last = values.length - 1;
5779
- const points = [{ kind: "latest", index: last }];
5780
- let maxI = 0;
5781
- let minI = 0;
5782
- let max = values[0];
5783
- let min = max;
5784
- values.forEach((v, i) => {
5785
- if (v >= max) [max, maxI] = [v, i];
5786
- if (v <= min) [min, minI] = [v, i];
5787
- });
5788
- const latest = values[last];
5789
- if (max === min) return points;
5790
- if (max !== latest) points.push({ kind: "max", index: maxI });
5791
- if (min !== latest) points.push({ kind: "min", index: minI });
5792
- return points;
5793
- }
5794
- function buildBarRects(ys, height, gap = 1) {
5795
- const barW = Math.max(1, VB_WIDTH / ys.length - gap);
5796
- return ys.map((y, i) => ({ x: i * (barW + gap), y, w: barW, h: height - y }));
5797
- }
5798
- var NO_ROWS12 = [];
5799
- var Sparkline = forwardRef(function Sparkline2({
5800
- data = NO_ROWS12,
5801
- variant = "line",
5802
- height = 40,
5803
- color = "text-chart-1",
5804
- area = false,
5805
- animate = false,
5806
- highlight = "auto",
5807
- "aria-label": ariaLabel,
5808
- className,
5809
- ...props
5810
- }, ref) {
5811
- const [mounted, setMounted] = useState(false);
5812
- useEffect(() => {
5813
- if (animate) setMounted(true);
5814
- }, [animate]);
5815
- if (data.length === 0) return null;
5816
- const values = data.map((d) => d.value);
5817
- const ys = normalizeData(values, height);
5818
- const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
5819
- const points = variant !== "line" ? [] : highlight === "auto" ? sparklineHighlightPoints(values) : highlight === "latest" ? [{ kind: "latest", index: values.length - 1 }] : [];
5820
- return /* @__PURE__ */ jsxs(
5821
- "svg",
5822
- {
5823
- ref,
5824
- "data-slot": "sparkline",
5825
- viewBox: `0 0 ${VB_WIDTH} ${height}`,
5826
- preserveAspectRatio: "none",
5827
- width: "100%",
5828
- height,
5829
- role: ariaLabel ? "img" : void 0,
5830
- "aria-label": ariaLabel,
5831
- "aria-hidden": ariaLabel ? void 0 : true,
5832
- className: cn("overflow-visible", className),
5833
- ...props,
5834
- children: [
5835
- variant === "line" && /* @__PURE__ */ jsxs(Fragment, { children: [
5836
- area && /* @__PURE__ */ jsx(
5837
- "path",
5838
- {
5839
- d: buildAreaPath(ys, height),
5840
- strokeWidth: 0,
5841
- className: cn("fill-current opacity-15", color)
5842
- }
5843
- ),
5844
- /* @__PURE__ */ jsx(
5845
- "path",
5846
- {
5847
- d: buildLinePath(ys),
5848
- fill: "none",
5849
- strokeWidth: 1.5,
5850
- strokeLinecap: "round",
5851
- strokeLinejoin: "round",
5852
- vectorEffect: "non-scaling-stroke",
5853
- pathLength: animate ? 1 : void 0,
5854
- strokeDasharray: animate ? 1 : void 0,
5855
- strokeDashoffset: animate ? mounted ? 0 : 1 : void 0,
5856
- className: cn("stroke-current", animate && "motion-reduce:transition-none!", color),
5857
- style: animate ? { transition: "stroke-dashoffset 0.6s ease-in-out" } : void 0
5858
- }
5859
- ),
5860
- points.map((p) => {
5861
- const x = (p.index * step).toFixed(2);
5862
- const y = (ys[p.index] ?? 0).toFixed(2);
5863
- return /* @__PURE__ */ jsx(
5864
- "path",
5865
- {
5866
- "data-slot": "sparkline-point",
5867
- "data-point": p.kind,
5868
- d: `M${x},${y} L${x},${y}`,
5869
- fill: "none",
5870
- strokeWidth: p.kind === "latest" ? 5 : 4,
5871
- strokeLinecap: "round",
5872
- vectorEffect: "non-scaling-stroke",
5873
- className: cn("stroke-current", p.kind === "latest" ? color : "text-muted-foreground")
5874
- },
5875
- p.kind
5876
- );
5877
- })
5878
- ] }),
5879
- variant === "bar" && buildBarRects(ys, height).map((rect, i) => /* @__PURE__ */ jsx(
5880
- "rect",
5881
- {
5882
- x: rect.x,
5883
- y: animate ? mounted ? rect.y : height : rect.y,
5884
- width: rect.w,
5885
- height: animate ? mounted ? rect.h : 0 : rect.h,
5886
- rx: 0.5,
5887
- className: cn("fill-current", animate && "motion-reduce:transition-none!", color),
5888
- style: animate ? {
5889
- transition: `height 0.4s ease-out ${i * 0.02}s, y 0.4s ease-out ${i * 0.02}s`
5890
- } : void 0
5891
- },
5892
- i
5893
- ))
5894
- ]
5895
- }
5896
- );
5897
- });
5898
- Sparkline.displayName = "Sparkline";
5899
5033
  function resolveFormat(format2, row) {
5900
5034
  return typeof format2 === "function" ? format2(row) : format2;
5901
5035
  }
@@ -5960,10 +5094,10 @@ function useDataTable() {
5960
5094
  if (!ctx) throw new Error("useDataTable must be used inside <DataTable>");
5961
5095
  return ctx;
5962
5096
  }
5963
- var NO_ROWS13 = [];
5097
+ var NO_ROWS12 = [];
5964
5098
  function DataTable({
5965
- columns = NO_ROWS13,
5966
- data = NO_ROWS13,
5099
+ columns = NO_ROWS12,
5100
+ data = NO_ROWS12,
5967
5101
  enableSorting = true,
5968
5102
  sorting: sortingProp,
5969
5103
  onSortingChange,
@@ -7432,6 +6566,7 @@ var Delta = forwardRef(
7432
6566
  ({
7433
6567
  value,
7434
6568
  comparison,
6569
+ betterWhen,
7435
6570
  polarity,
7436
6571
  neutralBand,
7437
6572
  format: format2,
@@ -7444,7 +6579,7 @@ var Delta = forwardRef(
7444
6579
  ...props
7445
6580
  }, ref) => {
7446
6581
  if (!comparison) return null;
7447
- const result = computeComparison(value, comparison, { polarity, neutralBand });
6582
+ const result = computeComparison(value, comparison, { polarity: betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarity, neutralBand });
7448
6583
  const display = change ?? defaultChangeDisplay(format2);
7449
6584
  const formatDigits = typeof format2 === "object" && format2 !== null && "digits" in format2 ? format2.digits : void 0;
7450
6585
  const changeDigits = display === "points" ? digits ?? formatDigits : digits;
@@ -7530,7 +6665,8 @@ function KpiCard({
7530
6665
  comparison: comparisonProp,
7531
6666
  comparisons,
7532
6667
  provisional,
7533
- polarity,
6668
+ betterWhen,
6669
+ polarity: polarityProp,
7534
6670
  change,
7535
6671
  neutralBand,
7536
6672
  showPrevious = true,
@@ -7557,6 +6693,7 @@ function KpiCard({
7557
6693
  const isProvisional = provisional !== void 0 && provisional !== false;
7558
6694
  const provisionalLabel = typeof provisional === "object" && provisional.label ? provisional.label : "\u901F\u5831";
7559
6695
  const sample = useSampleMark();
6696
+ const polarity = betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarityProp;
7560
6697
  const neutral = polarity === "neutral";
7561
6698
  const hasPrevious = comparison !== void 0 && showPrevious;
7562
6699
  const stacked = allComparisons.length > 1;
@@ -7909,6 +7046,6 @@ var Placeholder = forwardRef(function Placeholder2({ className, ...props }, ref)
7909
7046
  });
7910
7047
  Placeholder.displayName = "Placeholder";
7911
7048
 
7912
- export { AppShell, AreaChart, BarChart2 as BarChart, BarList, COMPARISON_LABELS, CategoryBar, ChartFrame, DEFAULT_LOCALE, DEFAULT_SAMPLE_LABEL, DELTA_NOT_COMPARABLE, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTableExport, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, Delta, DonutChart, EChart, EMPTY_VALUE, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, Heatmap, KpiCard, Legend, LineChart2 as LineChart, MINUS_SIGN, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, ProgressCircle, RECORD_MIN_POINTS, SampleBadge, SampleClaim, SampleData, ScatterChart, SearchableSelect, SectionHeader, SegmentedControl, Sparkline, StatusBadge, Tracker, TrendIndicator, UpdatedAt, WaterfallChart, comparisonBaseline, comparisonLabel, computeComparison, computeTargetProgress, defaultChangeDisplay, defaultPresets, deltaVariants, detectRecord, fillKpiTemplate, flattenOptions, formatChange, formatChangeAmount, formatDate, formatDateRange, formatDatesInText, formatDelta, formatKind, formatPoints, formatRelativeTime, formatValue, funnelStepsVariants, inferPeriodGrain, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, tableToCsv, toCsv, toValueFormatter, toneForValue, useDataTable, useResolvedChartColors, useSampleMark };
7913
- //# sourceMappingURL=chunk-IUPSBD6W.js.map
7914
- //# sourceMappingURL=chunk-IUPSBD6W.js.map
7049
+ export { AppShell, AreaChart, BarChart, BarList, COMPARISON_LABELS, CategoryBar, ChartFrame, DEFAULT_SAMPLE_LABEL, DELTA_NOT_COMPARABLE, DashboardCard, DashboardCardAction, DashboardCardContent, DashboardCardDescription, DashboardCardFooter, DashboardCardHeader, DashboardCardPreset, DashboardCardSkeleton, DashboardCardTitle, DataTable, DataTableColumnVisibility, DataTableContent, DataTableExport, DataTablePagination, DataTablePreset, DataTableToolbar, DateRangePicker, Delta, DonutChart, FilterBar, FilterBarActiveChips, FilterBarClearButton, FilterBarMultiSelect, FilterBarPreset, FilterBarSelect, FunnelSteps, Heatmap, KpiCard, Legend, LineChart, MetricUnit, MetricValue, MultiSelect, PageShell, PageShellActions, PageShellContent, PageShellDescription, PageShellHeader, PageShellHeaderEnd, PageShellHeading, PageShellMeta, PageShellSummary, PageShellSummaryCard, PageShellTitle, Placeholder, ProgressCircle, RECORD_MIN_POINTS, SampleBadge, SampleClaim, SampleData, ScatterChart, SearchableSelect, SectionHeader, SegmentedControl, StatusBadge, Tracker, TrendIndicator, UpdatedAt, WaterfallChart, comparisonBaseline, comparisonLabel, computeComparison, computeTargetProgress, defaultChangeDisplay, defaultPresets, deltaVariants, detectRecord, fillKpiTemplate, flattenOptions, formatChange, formatChangeAmount, formatRelativeTime, funnelStepsVariants, inferPeriodGrain, isGroupedOptions, metricValueVariants, pageShellSummaryCardVariants, tableToCsv, toCsv, toneForValue, useDataTable, useSampleMark };
7050
+ //# sourceMappingURL=chunk-QOXXOFGL.js.map
7051
+ //# sourceMappingURL=chunk-QOXXOFGL.js.map