@squadbase/vantage 0.6.2-dev1.d7c0911 → 0.6.2-dev1.e85faec
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-2IAPIOPS.js +152 -0
- package/dist/chunk-2IAPIOPS.js.map +1 -0
- package/dist/chunk-57GHR5LN.js +163 -0
- package/dist/chunk-57GHR5LN.js.map +1 -0
- package/dist/chunk-6OTTGAPO.js +44 -0
- package/dist/chunk-6OTTGAPO.js.map +1 -0
- package/dist/{chunk-XPQSTZUU.js → chunk-7S52M2SL.js} +4 -3
- package/dist/chunk-7S52M2SL.js.map +1 -0
- package/dist/chunk-JXFCSF3K.js +673 -0
- package/dist/chunk-JXFCSF3K.js.map +1 -0
- package/dist/{chunk-WRSX2MDK.js → chunk-QOXXOFGL.js} +115 -930
- package/dist/chunk-QOXXOFGL.js.map +1 -0
- package/dist/components/index.d.ts +13 -249
- package/dist/components/index.js +5 -2
- package/dist/delta-text-CvwBGJ95.d.ts +15 -0
- package/dist/doc/index.d.ts +215 -2
- package/dist/doc/index.js +300 -3
- package/dist/doc/index.js.map +1 -1
- package/dist/format-U0cQl069.d.ts +243 -0
- package/dist/slide/index.d.ts +272 -1
- package/dist/slide/index.js +968 -3
- package/dist/slide/index.js.map +1 -1
- package/dist/table/index.js +6 -3
- package/dist/table/index.js.map +1 -1
- package/dist/ui/index.d.ts +4 -1
- package/dist/ui/index.js +3 -3
- package/dist/ui/index.js.map +1 -1
- package/docs/en/components.md +13 -2
- package/docs/en/doc/delta-text.md +40 -0
- package/docs/en/doc/doc-action-items.md +49 -0
- package/docs/en/doc/doc-callout.md +38 -0
- package/docs/en/doc/doc-data-table.md +60 -0
- package/docs/en/doc/doc-executive-summary.md +64 -0
- package/docs/en/doc/doc-figure.md +56 -0
- package/docs/en/doc/doc-key-findings.md +61 -0
- package/docs/en/doc/doc-kpi-scorecard.md +80 -0
- package/docs/en/doc/doc-notes-and-sources.md +43 -0
- package/docs/en/doc/doc-report-header.md +46 -0
- package/docs/en/parts/area-chart.md +99 -0
- package/docs/en/parts/bar-chart.md +91 -0
- package/docs/en/parts/bar-list.md +50 -0
- package/docs/en/parts/category-bar.md +37 -0
- package/docs/en/parts/chart-frame.md +39 -0
- package/docs/en/parts/delta.md +4 -3
- package/docs/en/parts/donut-chart.md +72 -0
- package/docs/en/parts/funnel-steps.md +2 -1
- package/docs/en/parts/heatmap.md +53 -0
- package/docs/en/parts/kpi-card.md +2 -1
- package/docs/en/parts/legend.md +35 -0
- package/docs/en/parts/line-chart.md +94 -0
- package/docs/en/parts/progress-circle.md +33 -0
- package/docs/en/parts/sample-data.md +39 -0
- package/docs/en/parts/scatter-chart.md +56 -0
- package/docs/en/parts/tracker.md +36 -0
- package/docs/en/parts/updated-at.md +30 -0
- package/docs/en/parts/waterfall-chart.md +56 -0
- package/docs/en/slide/slide-chart-full.md +48 -0
- package/docs/en/slide/slide-chart-insight.md +52 -0
- package/docs/en/slide/slide-columns.md +46 -0
- package/docs/en/slide/slide-comparison.md +68 -0
- package/docs/en/slide/slide-cover.md +39 -0
- package/docs/en/slide/slide-exec-summary.md +47 -0
- package/docs/en/slide/slide-heading.md +38 -0
- package/docs/en/slide/slide-kpi-grid.md +55 -0
- package/docs/en/slide/slide-kpi-hero.md +58 -0
- package/docs/en/slide/slide-next-actions.md +49 -0
- package/docs/en/slide/slide-scorecard-table.md +54 -0
- package/docs/en/slide/slide-section.md +44 -0
- package/docs/en/slide/slide-source-line.md +34 -0
- package/docs/en/ui/alert-dialog.md +42 -0
- package/docs/en/ui/avatar.md +31 -0
- package/docs/en/ui/combobox.md +74 -0
- package/docs/en/ui/drawer.md +41 -0
- package/docs/en/ui/empty.md +1 -1
- package/docs/en/ui/error-state.md +4 -3
- package/docs/en/ui/field.md +42 -0
- package/docs/en/ui/hover-card.md +21 -0
- package/docs/en/ui/kbd.md +17 -0
- package/docs/en/ui/loading.md +1 -1
- package/docs/en/ui/pagination.md +36 -0
- package/docs/en/ui/radio-group.md +21 -0
- package/docs/en/ui/toast.md +44 -0
- package/docs/en/ui/toggle-group.md +4 -3
- package/docs/index.json +857 -77
- package/docs/ja/components.md +12 -1
- package/docs/ja/doc/delta-text.md +40 -0
- package/docs/ja/doc/doc-action-items.md +49 -0
- package/docs/ja/doc/doc-callout.md +38 -0
- package/docs/ja/doc/doc-data-table.md +60 -0
- package/docs/ja/doc/doc-executive-summary.md +64 -0
- package/docs/ja/doc/doc-figure.md +56 -0
- package/docs/ja/doc/doc-key-findings.md +61 -0
- package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
- package/docs/ja/doc/doc-notes-and-sources.md +43 -0
- package/docs/ja/doc/doc-report-header.md +46 -0
- package/docs/ja/parts/area-chart.md +49 -25
- package/docs/ja/parts/bar-chart.md +50 -24
- package/docs/ja/parts/bar-list.md +31 -8
- package/docs/ja/parts/chart-frame.md +36 -0
- package/docs/ja/parts/delta.md +5 -4
- package/docs/ja/parts/donut-chart.md +45 -26
- package/docs/ja/parts/funnel-steps.md +27 -8
- package/docs/ja/parts/heatmap.md +45 -0
- package/docs/ja/parts/kpi-card.md +2 -1
- package/docs/ja/parts/legend.md +36 -0
- package/docs/ja/parts/line-chart.md +48 -22
- package/docs/ja/parts/sample-data.md +61 -0
- package/docs/ja/parts/scatter-chart.md +69 -0
- package/docs/ja/parts/updated-at.md +27 -0
- package/docs/ja/parts/waterfall-chart.md +61 -0
- package/docs/ja/slide/slide-chart-full.md +48 -0
- package/docs/ja/slide/slide-chart-insight.md +52 -0
- package/docs/ja/slide/slide-columns.md +46 -0
- package/docs/ja/slide/slide-comparison.md +68 -0
- package/docs/ja/slide/slide-cover.md +39 -0
- package/docs/ja/slide/slide-exec-summary.md +47 -0
- package/docs/ja/slide/slide-heading.md +38 -0
- package/docs/ja/slide/slide-kpi-grid.md +55 -0
- package/docs/ja/slide/slide-kpi-hero.md +58 -0
- package/docs/ja/slide/slide-next-actions.md +49 -0
- package/docs/ja/slide/slide-scorecard-table.md +54 -0
- package/docs/ja/slide/slide-section.md +44 -0
- package/docs/ja/slide/slide-source-line.md +34 -0
- package/docs/ja/ui/empty.md +1 -1
- package/docs/ja/ui/error-state.md +4 -3
- package/docs/ja/ui/loading.md +1 -1
- package/docs/ja/ui/toggle-group.md +4 -3
- package/package.json +26 -25
- package/registry/ui/accordion.tsx +1 -1
- package/registry/ui/alert-dialog.tsx +1 -1
- package/registry/ui/alert.tsx +1 -1
- package/registry/ui/app-shell.tsx +1 -1
- package/registry/ui/area-chart.tsx +89 -27
- package/registry/ui/attention-list.tsx +303 -0
- package/registry/ui/avatar.tsx +1 -1
- package/registry/ui/badge.tsx +1 -1
- package/registry/ui/bar-chart.tsx +89 -27
- package/registry/ui/bar-list.tsx +88 -25
- package/registry/ui/box-plot-chart.tsx +3906 -0
- package/registry/ui/breadcrumb.tsx +1 -1
- package/registry/ui/button.tsx +1 -1
- package/registry/ui/calendar.tsx +1 -1
- package/registry/ui/card.tsx +1 -1
- package/registry/ui/category-bar.tsx +55 -20
- package/registry/ui/chart-frame.tsx +57 -22
- package/registry/ui/checkbox.tsx +1 -1
- package/registry/ui/collapsible.tsx +1 -1
- package/registry/ui/combobox.tsx +1 -1
- package/registry/ui/command.tsx +1 -1
- package/registry/ui/dashboard-card.tsx +5 -5
- package/registry/ui/data-table.tsx +1 -1
- package/registry/ui/date-range-picker.tsx +1 -1
- package/registry/ui/delta.tsx +12 -9
- package/registry/ui/dialog.tsx +1 -1
- package/registry/ui/donut-chart.tsx +90 -27
- package/registry/ui/drawer.tsx +1 -1
- package/registry/ui/dropdown-menu.tsx +1 -1
- package/registry/ui/echart.tsx +195 -45
- package/registry/ui/field.tsx +1 -1
- package/registry/ui/filter-bar.tsx +1 -1
- package/registry/ui/funnel-steps.tsx +34 -6
- package/registry/ui/heatmap.tsx +56 -22
- package/registry/ui/histogram-chart.tsx +3986 -0
- package/registry/ui/hover-card.tsx +1 -1
- package/registry/ui/input-group.tsx +1 -1
- package/registry/ui/input.tsx +1 -1
- package/registry/ui/kbd.tsx +1 -1
- package/registry/ui/kpi-card.tsx +42 -15
- package/registry/ui/label.tsx +1 -1
- package/registry/ui/legend.tsx +88 -25
- package/registry/ui/line-chart.tsx +89 -27
- package/registry/ui/metric-value.tsx +1 -1
- package/registry/ui/multi-select.tsx +1 -1
- package/registry/ui/page-shell.tsx +11 -11
- package/registry/ui/pagination.tsx +1 -1
- package/registry/ui/paired-chart.tsx +3827 -0
- package/registry/ui/placeholder.tsx +1 -1
- package/registry/ui/popover.tsx +1 -1
- package/registry/ui/progress-circle.tsx +1 -1
- package/registry/ui/progress.tsx +1 -1
- package/registry/ui/radio-group.tsx +1 -1
- package/registry/ui/sample-data.tsx +2 -2
- package/registry/ui/scatter-chart.tsx +89 -27
- package/registry/ui/scroll-area.tsx +1 -1
- package/registry/ui/searchable-select.tsx +1 -1
- package/registry/ui/section-header.tsx +3 -3
- package/registry/ui/segmented-control.tsx +1 -1
- package/registry/ui/select.tsx +1 -1
- package/registry/ui/separator.tsx +1 -1
- package/registry/ui/sheet.tsx +1 -1
- package/registry/ui/sidebar.tsx +1 -1
- package/registry/ui/skeleton.tsx +1 -1
- package/registry/ui/slider.tsx +2 -2
- package/registry/ui/sparkline.tsx +1 -1
- package/registry/ui/spinner.tsx +1 -1
- package/registry/ui/states.tsx +1 -1
- package/registry/ui/status-badge.tsx +9 -9
- package/registry/ui/switch.tsx +1 -1
- package/registry/ui/table.tsx +1 -1
- package/registry/ui/tabs.tsx +1 -1
- package/registry/ui/textarea.tsx +1 -1
- package/registry/ui/toast.tsx +1 -1
- package/registry/ui/toggle-group.tsx +1 -1
- package/registry/ui/toggle.tsx +1 -1
- package/registry/ui/tooltip.tsx +7 -3
- package/registry/ui/tracker.tsx +10 -4
- package/registry/ui/trend-indicator.tsx +3 -3
- package/registry/ui/updated-at.tsx +1 -1
- package/registry/ui/waterfall-chart.tsx +89 -27
- package/skills/vantage-design/SKILL.md +34 -24
- package/skills/vantage-design/references/extract.md +16 -14
- package/skills/vantage-design/references/format.md +6 -5
- package/skills/vantage-design/references/presets.md +60 -110
- package/skills/vantage-slide/SKILL.md +54 -36
- package/templates/AGENTS.md +2 -2
- package/templates/agents/doc.md +48 -0
- package/templates/agents/page.md +32 -1
- package/templates/agents/slide.md +70 -2
- package/theme.css +25 -20
- package/dist/chunk-WRSX2MDK.js.map +0 -1
- package/dist/chunk-XPQSTZUU.js.map +0 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
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';
|
|
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,
|
|
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 {
|
|
8
|
-
import { use
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
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;
|
|
@@ -282,17 +126,17 @@ var PageShellHeader = forwardRef(
|
|
|
282
126
|
{
|
|
283
127
|
ref,
|
|
284
128
|
"data-slot": "page-shell-header",
|
|
285
|
-
className: cn("flex flex-wrap items-start gap-x-4 gap-y-
|
|
129
|
+
className: cn("flex flex-wrap items-start gap-x-4 gap-y-4 px-6 pt-8", className),
|
|
286
130
|
...props,
|
|
287
131
|
children: [
|
|
288
132
|
children,
|
|
289
133
|
updatedAt !== void 0 && updatedAt !== null ? /* @__PURE__ */ jsx("div", { "data-slot": "page-shell-updated-at", className: "ml-auto max-w-full shrink-0 text-right", children: /* @__PURE__ */ jsx(UpdatedAt, { at: updatedAt, variant: updatedAtVariant, timeZone }) }) : null,
|
|
290
134
|
hasChips ? /* @__PURE__ */ jsxs("div", { "data-slot": "page-shell-chips", className: "order-1 flex basis-full flex-wrap gap-1.5", children: [
|
|
291
|
-
source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal", children: [
|
|
135
|
+
source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal text-muted-foreground", children: [
|
|
292
136
|
"\u51FA\u5178\uFF1A",
|
|
293
137
|
source
|
|
294
138
|
] }) : null,
|
|
295
|
-
periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums", children: periodText }) : null
|
|
139
|
+
periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums text-muted-foreground", children: periodText }) : null
|
|
296
140
|
] }) : null,
|
|
297
141
|
hasStatus ? /* @__PURE__ */ jsx("div", { "data-slot": "page-shell-status", className: "order-2 min-w-0 basis-full", children: status }) : null
|
|
298
142
|
]
|
|
@@ -319,7 +163,7 @@ var PageShellTitle = forwardRef(
|
|
|
319
163
|
{
|
|
320
164
|
ref,
|
|
321
165
|
"data-slot": "page-shell-title",
|
|
322
|
-
className: cn("text-2xl font-
|
|
166
|
+
className: cn("text-2xl font-semibold tracking-tight text-foreground", className),
|
|
323
167
|
...props
|
|
324
168
|
}
|
|
325
169
|
)
|
|
@@ -389,11 +233,11 @@ var PageShellSummary = forwardRef(
|
|
|
389
233
|
);
|
|
390
234
|
PageShellSummary.displayName = "PageShellSummary";
|
|
391
235
|
var summaryCardTones = {
|
|
392
|
-
positive: "border-positive/
|
|
393
|
-
negative: "border-negative/
|
|
394
|
-
warning: "border-warning/
|
|
395
|
-
info: "border-info/
|
|
396
|
-
neutral: "border-neutral/
|
|
236
|
+
positive: "border-positive/20 dark:border-positive/25 bg-positive-subtle [&>svg]:text-positive",
|
|
237
|
+
negative: "border-negative/20 dark:border-negative/25 bg-negative-subtle [&>svg]:text-negative",
|
|
238
|
+
warning: "border-warning/20 dark:border-warning/25 bg-warning-subtle [&>svg]:text-warning",
|
|
239
|
+
info: "border-info/20 dark:border-info/25 bg-info-subtle [&>svg]:text-info",
|
|
240
|
+
neutral: "border-neutral/20 dark:border-neutral/25 bg-neutral-subtle [&>svg]:text-neutral",
|
|
397
241
|
violet: "border-chart-4/30 bg-chart-4/5 [&>svg]:text-chart-4",
|
|
398
242
|
pink: "border-chart-5/30 bg-chart-5/5 [&>svg]:text-chart-5"
|
|
399
243
|
};
|
|
@@ -451,7 +295,7 @@ var PageShellContent = forwardRef(
|
|
|
451
295
|
{
|
|
452
296
|
ref,
|
|
453
297
|
"data-slot": "page-shell-content",
|
|
454
|
-
className: cn("flex-1 p-6", className),
|
|
298
|
+
className: cn("flex min-w-0 flex-1 flex-col gap-6 p-6", className),
|
|
455
299
|
...props
|
|
456
300
|
}
|
|
457
301
|
)
|
|
@@ -630,8 +474,8 @@ var AppShell = forwardRef((props, ref) => {
|
|
|
630
474
|
AppShell.displayName = "AppShell";
|
|
631
475
|
var headingStyles = {
|
|
632
476
|
h1: "text-3xl font-bold tracking-tight",
|
|
633
|
-
h2: "text-
|
|
634
|
-
h3: "text-
|
|
477
|
+
h2: "text-base font-semibold tracking-tight",
|
|
478
|
+
h3: "text-base font-semibold",
|
|
635
479
|
h4: "text-lg font-semibold"
|
|
636
480
|
};
|
|
637
481
|
var SectionHeader = forwardRef(
|
|
@@ -667,7 +511,7 @@ function SampleBadge({ label: label2 = DEFAULT_SAMPLE_LABEL, className, ...props
|
|
|
667
511
|
{
|
|
668
512
|
"data-slot": "sample-badge",
|
|
669
513
|
title: SAMPLE_TITLE,
|
|
670
|
-
className: cn("border-warning/
|
|
514
|
+
className: cn("border-warning/20 dark:border-warning/25 bg-warning-subtle text-warning align-middle", className),
|
|
671
515
|
...props,
|
|
672
516
|
children: label2
|
|
673
517
|
}
|
|
@@ -678,8 +522,8 @@ function SampleData({ label: label2 = DEFAULT_SAMPLE_LABEL, children }) {
|
|
|
678
522
|
return /* @__PURE__ */ jsx("div", { "data-slot": "sample-data", style: { display: "contents" }, children: /* @__PURE__ */ jsx(SampleContext.Provider, { value: state, children }) });
|
|
679
523
|
}
|
|
680
524
|
var SUBGRID_CLASS = {
|
|
681
|
-
2: "row-span-2 grid content-start grid-rows-subgrid",
|
|
682
|
-
3: "row-span-3 grid content-start grid-rows-subgrid"
|
|
525
|
+
2: "row-span-2 grid min-w-0 grid-cols-1 content-start grid-rows-subgrid",
|
|
526
|
+
3: "row-span-3 grid min-w-0 grid-cols-1 content-start grid-rows-subgrid"
|
|
683
527
|
};
|
|
684
528
|
var DashboardCard = forwardRef(
|
|
685
529
|
({ className, subgrid, size = "default", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
@@ -716,7 +560,7 @@ var DashboardCardTitle = forwardRef(
|
|
|
716
560
|
{
|
|
717
561
|
ref,
|
|
718
562
|
"data-slot": "dashboard-card-title",
|
|
719
|
-
className: cn("text-sm leading-
|
|
563
|
+
className: cn("text-sm leading-snug font-semibold tracking-tight", className),
|
|
720
564
|
...props
|
|
721
565
|
}
|
|
722
566
|
)
|
|
@@ -727,7 +571,7 @@ var DashboardCardDescription = forwardRef(({ className, ...props }, ref) => /* @
|
|
|
727
571
|
{
|
|
728
572
|
ref,
|
|
729
573
|
"data-slot": "dashboard-card-description",
|
|
730
|
-
className: cn("text-xs text-muted-foreground", className),
|
|
574
|
+
className: cn("text-xs leading-normal text-muted-foreground", className),
|
|
731
575
|
...props
|
|
732
576
|
}
|
|
733
577
|
));
|
|
@@ -807,223 +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 normalizeContext;
|
|
814
|
-
var ZRENDER_COLOR_RE = /^(?:#[0-9a-f]{6}|rgba?\()/i;
|
|
815
|
-
function toCanvasColor(value) {
|
|
816
|
-
const raw = value.trim();
|
|
817
|
-
if (!raw) return null;
|
|
818
|
-
if (normalizeContext === void 0) {
|
|
819
|
-
const canvas = document.createElement("canvas");
|
|
820
|
-
canvas.width = 1;
|
|
821
|
-
canvas.height = 1;
|
|
822
|
-
normalizeContext = canvas.getContext("2d", { willReadFrequently: true });
|
|
823
|
-
}
|
|
824
|
-
const ctx = normalizeContext;
|
|
825
|
-
if (!ctx) return raw;
|
|
826
|
-
ctx.fillStyle = "#000000";
|
|
827
|
-
ctx.fillStyle = raw;
|
|
828
|
-
const onBlack = ctx.fillStyle;
|
|
829
|
-
ctx.fillStyle = "#ffffff";
|
|
830
|
-
ctx.fillStyle = raw;
|
|
831
|
-
if (onBlack !== ctx.fillStyle || typeof onBlack !== "string") return null;
|
|
832
|
-
if (ZRENDER_COLOR_RE.test(onBlack)) return onBlack;
|
|
833
|
-
ctx.clearRect(0, 0, 1, 1);
|
|
834
|
-
ctx.fillRect(0, 0, 1, 1);
|
|
835
|
-
const [r = 0, g = 0, b = 0, a = 0] = ctx.getImageData(0, 0, 1, 1).data;
|
|
836
|
-
return a === 255 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${Math.round(a / 255 * 1e3) / 1e3})`;
|
|
837
|
-
}
|
|
838
|
-
function readChartTokens(el) {
|
|
839
|
-
if (typeof document === "undefined") return null;
|
|
840
|
-
const target = document.documentElement;
|
|
841
|
-
if (!target) return null;
|
|
842
|
-
const styles = getComputedStyle(target);
|
|
843
|
-
const read = (name) => toCanvasColor(styles.getPropertyValue(name));
|
|
844
|
-
const series = [];
|
|
845
|
-
for (const token of SERIES_TOKENS) {
|
|
846
|
-
const color = read(token);
|
|
847
|
-
if (color) series.push(color);
|
|
848
|
-
}
|
|
849
|
-
return {
|
|
850
|
-
series,
|
|
851
|
-
foreground: read("--foreground"),
|
|
852
|
-
mutedForeground: read("--muted-foreground"),
|
|
853
|
-
border: read("--border"),
|
|
854
|
-
popover: read("--popover"),
|
|
855
|
-
popoverForeground: read("--popover-foreground")
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
function sameChartTokens(a, b) {
|
|
859
|
-
if (a === b) return true;
|
|
860
|
-
if (!a || !b) return false;
|
|
861
|
-
return a.series.length === b.series.length && a.series.every((color, i) => color === b.series[i]) && a.foreground === b.foreground && a.mutedForeground === b.mutedForeground && a.border === b.border && a.popover === b.popover && a.popoverForeground === b.popoverForeground;
|
|
862
|
-
}
|
|
863
|
-
function watchChartTokens(onChange) {
|
|
864
|
-
if (typeof document === "undefined") return () => {
|
|
865
|
-
};
|
|
866
|
-
let frame = 0;
|
|
867
|
-
const schedule = () => {
|
|
868
|
-
if (frame) return;
|
|
869
|
-
frame = requestAnimationFrame(() => {
|
|
870
|
-
frame = 0;
|
|
871
|
-
onChange();
|
|
872
|
-
});
|
|
873
|
-
};
|
|
874
|
-
const themeObserver = new MutationObserver(schedule);
|
|
875
|
-
const attributeFilter = ["class", "style", "data-theme"];
|
|
876
|
-
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter });
|
|
877
|
-
if (document.body) themeObserver.observe(document.body, { attributes: true, attributeFilter });
|
|
878
|
-
const styleObserver = new MutationObserver(schedule);
|
|
879
|
-
if (document.head) {
|
|
880
|
-
styleObserver.observe(document.head, {
|
|
881
|
-
childList: true,
|
|
882
|
-
subtree: true,
|
|
883
|
-
characterData: true,
|
|
884
|
-
attributes: true,
|
|
885
|
-
attributeFilter: ["href", "media", "disabled"]
|
|
886
|
-
});
|
|
887
|
-
}
|
|
888
|
-
const onLoad = (event) => {
|
|
889
|
-
if (event.target instanceof HTMLLinkElement) schedule();
|
|
890
|
-
};
|
|
891
|
-
document.addEventListener("load", onLoad, true);
|
|
892
|
-
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
|
893
|
-
media.addEventListener("change", schedule);
|
|
894
|
-
return () => {
|
|
895
|
-
if (frame) cancelAnimationFrame(frame);
|
|
896
|
-
themeObserver.disconnect();
|
|
897
|
-
styleObserver.disconnect();
|
|
898
|
-
document.removeEventListener("load", onLoad, true);
|
|
899
|
-
media.removeEventListener("change", schedule);
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
function axisTheme(tokens, splitLine) {
|
|
903
|
-
const line = tokens.border ?? void 0;
|
|
904
|
-
return {
|
|
905
|
-
axisLine: { show: false },
|
|
906
|
-
axisTick: { show: false },
|
|
907
|
-
axisLabel: { show: true, color: tokens.mutedForeground ?? void 0, fontSize: 12 },
|
|
908
|
-
// Faint horizontal rules only: the border colour at low opacity.
|
|
909
|
-
splitLine: { show: splitLine, lineStyle: { color: line ? [line] : void 0, opacity: 0.5, width: 1 } },
|
|
910
|
-
splitArea: { show: false }
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
function buildChartTheme(tokens) {
|
|
914
|
-
const text = tokens.foreground ?? void 0;
|
|
915
|
-
const muted = tokens.mutedForeground ?? void 0;
|
|
916
|
-
const line = tokens.border ?? void 0;
|
|
917
|
-
return {
|
|
918
|
-
// Let the page background show through: charts sit on cards, not on a canvas.
|
|
919
|
-
backgroundColor: "transparent",
|
|
920
|
-
...tokens.series.length > 0 ? { color: tokens.series } : {},
|
|
921
|
-
textStyle: { color: text },
|
|
922
|
-
title: { textStyle: { color: text }, subtextStyle: { color: muted } },
|
|
923
|
-
legend: { textStyle: { color: muted } },
|
|
924
|
-
categoryAxis: axisTheme(tokens, false),
|
|
925
|
-
valueAxis: axisTheme(tokens, true),
|
|
926
|
-
logAxis: axisTheme(tokens, true),
|
|
927
|
-
timeAxis: axisTheme(tokens, true),
|
|
928
|
-
tooltip: {
|
|
929
|
-
// ECharts' default 0.4s transform lags the tooltip ~300ms behind the cursor.
|
|
930
|
-
transitionDuration: 0,
|
|
931
|
-
backgroundColor: tokens.popover ?? void 0,
|
|
932
|
-
borderColor: line,
|
|
933
|
-
borderWidth: 1,
|
|
934
|
-
padding: [8, 12],
|
|
935
|
-
// Rounded card with a soft shadow; in dark mode the shadow barely shows, so the border carries the edge.
|
|
936
|
-
extraCssText: "border-radius:8px;box-shadow:var(--shadow-card, 0 4px 12px rgb(0 0 0 / 0.08));",
|
|
937
|
-
textStyle: { color: tokens.popoverForeground ?? void 0, fontSize: 12 },
|
|
938
|
-
axisPointer: { lineStyle: { color: line }, crossStyle: { color: line } }
|
|
939
|
-
}
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
function useChartTokens() {
|
|
943
|
-
const [tokens, setTokens] = useState(() => readChartTokens());
|
|
944
|
-
const tokensRef = useRef(tokens);
|
|
945
|
-
useEffect(() => {
|
|
946
|
-
const sync = () => {
|
|
947
|
-
const next = readChartTokens();
|
|
948
|
-
if (sameChartTokens(tokensRef.current, next)) return;
|
|
949
|
-
tokensRef.current = next;
|
|
950
|
-
setTokens(next);
|
|
951
|
-
};
|
|
952
|
-
sync();
|
|
953
|
-
return watchChartTokens(sync);
|
|
954
|
-
}, []);
|
|
955
|
-
return tokens;
|
|
956
|
-
}
|
|
957
|
-
var SERIES_TOKEN_NAME_RE = /^chart-([1-5])$/;
|
|
958
|
-
var TONE_NAME_RE = /^(?:positive|warning|negative|neutral|info)(?:-fill)?$/;
|
|
959
|
-
var CSS_VAR_RE = /^var\(\s*(--[\w-]+)\s*(?:,\s*(.+))?\)$/;
|
|
960
|
-
var EMBEDDED_VAR_RE = /var\(\s*(--[\w-]+)\s*\)/g;
|
|
961
|
-
function resolveChartColors(colors, tokens) {
|
|
962
|
-
return colors.map((color) => {
|
|
963
|
-
const token = SERIES_TOKEN_NAME_RE.exec(color.trim());
|
|
964
|
-
if (token) return tokens?.series[Number(token[1]) - 1] ?? "";
|
|
965
|
-
if (TONE_NAME_RE.test(color.trim())) {
|
|
966
|
-
if (typeof document === "undefined") return "";
|
|
967
|
-
return toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue(`--${color.trim()}`)) ?? "";
|
|
968
|
-
}
|
|
969
|
-
if (typeof document === "undefined") return color;
|
|
970
|
-
let value = color.trim();
|
|
971
|
-
const cssVar = CSS_VAR_RE.exec(value);
|
|
972
|
-
const styles = getComputedStyle(document.documentElement);
|
|
973
|
-
if (cssVar) {
|
|
974
|
-
value = styles.getPropertyValue(cssVar[1]).trim() || (cssVar[2] ?? "").trim();
|
|
975
|
-
} else if (value.includes("var(")) {
|
|
976
|
-
value = value.replace(EMBEDDED_VAR_RE, (_, name) => styles.getPropertyValue(name).trim());
|
|
977
|
-
}
|
|
978
|
-
return toCanvasColor(value) ?? "";
|
|
979
|
-
});
|
|
980
|
-
}
|
|
981
|
-
function resolveFillColors(tokens) {
|
|
982
|
-
const [positive = "", warning = "", negative = "", neutral = ""] = resolveChartColors(
|
|
983
|
-
["positive-fill", "warning-fill", "negative-fill", "neutral-fill"],
|
|
984
|
-
tokens
|
|
985
|
-
);
|
|
986
|
-
return { positive, warning, negative, neutral };
|
|
987
|
-
}
|
|
988
|
-
var TRANSPARENT_RE = /^(?:transparent|rgba\([^)]*,\s*0(?:\.0+)?\))$/i;
|
|
989
|
-
function readChartSurface(el) {
|
|
990
|
-
if (typeof document === "undefined") return null;
|
|
991
|
-
for (let node = el; node; node = node.parentElement) {
|
|
992
|
-
const bg = getComputedStyle(node).backgroundColor.trim();
|
|
993
|
-
if (bg && !TRANSPARENT_RE.test(bg)) {
|
|
994
|
-
const color = toCanvasColor(bg);
|
|
995
|
-
if (color) return color;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue("--background"));
|
|
999
|
-
}
|
|
1000
|
-
var WIDTH_BUCKET = 40;
|
|
1001
|
-
function useChartSurface(forwarded, tokens) {
|
|
1002
|
-
const [node, setNode] = useState(null);
|
|
1003
|
-
const [surface, setSurface] = useState(void 0);
|
|
1004
|
-
const [width, setWidth] = useState(void 0);
|
|
1005
|
-
const ref = useCallback(
|
|
1006
|
-
(el) => {
|
|
1007
|
-
setNode(el);
|
|
1008
|
-
if (typeof forwarded === "function") forwarded(el);
|
|
1009
|
-
else if (forwarded) forwarded.current = el;
|
|
1010
|
-
},
|
|
1011
|
-
[forwarded]
|
|
1012
|
-
);
|
|
1013
|
-
useEffect(() => {
|
|
1014
|
-
if (!node) return;
|
|
1015
|
-
setSurface(readChartSurface(node) ?? void 0);
|
|
1016
|
-
}, [node, tokens]);
|
|
1017
|
-
useEffect(() => {
|
|
1018
|
-
if (!node || typeof ResizeObserver === "undefined") return;
|
|
1019
|
-
const update = (w) => setWidth(Math.floor(w / WIDTH_BUCKET) * WIDTH_BUCKET);
|
|
1020
|
-
update(node.getBoundingClientRect().width);
|
|
1021
|
-
const observer = new ResizeObserver((entries) => update(entries[0]?.contentRect.width ?? 0));
|
|
1022
|
-
observer.observe(node);
|
|
1023
|
-
return () => observer.disconnect();
|
|
1024
|
-
}, [node]);
|
|
1025
|
-
return { ref, surface, width };
|
|
1026
|
-
}
|
|
1027
654
|
var DEFAULT_CHART_HEIGHT = 288;
|
|
1028
655
|
var DEFAULT_EMPTY_TITLE = "\u8868\u793A\u3067\u304D\u308B\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093";
|
|
1029
656
|
var ChartFrame = forwardRef(function ChartFrame2({
|
|
@@ -1047,8 +674,8 @@ var ChartFrame = forwardRef(function ChartFrame2({
|
|
|
1047
674
|
const state = isLoading ? "loading" : isEmpty ? "empty" : "ready";
|
|
1048
675
|
return /* @__PURE__ */ jsxs("figure", { "data-slot": "chart-frame", className: cn("m-0 flex w-full min-w-0 flex-col gap-3", className), ...props, children: [
|
|
1049
676
|
(title || summary) && /* @__PURE__ */ jsxs("figcaption", { "data-slot": "chart-frame-header", className: "flex flex-col gap-1", children: [
|
|
1050
|
-
title && /* @__PURE__ */ jsx("h3", { id: titleId, "data-slot": "chart-frame-title", className: "text-sm leading-
|
|
1051
|
-
summary && /* @__PURE__ */ jsx("p", { id: summaryId, "data-slot": "chart-frame-summary", className: "text-sm text-muted-foreground", children: summary })
|
|
677
|
+
title && /* @__PURE__ */ jsx("h3", { id: titleId, "data-slot": "chart-frame-title", className: "text-sm leading-snug font-semibold", children: title }),
|
|
678
|
+
summary && /* @__PURE__ */ jsx("p", { id: summaryId, "data-slot": "chart-frame-summary", className: "text-sm leading-relaxed text-muted-foreground", children: summary })
|
|
1052
679
|
] }),
|
|
1053
680
|
/* @__PURE__ */ jsx(
|
|
1054
681
|
"div",
|
|
@@ -1107,336 +734,6 @@ function ChartEmpty({ title, description, action }) {
|
|
|
1107
734
|
}
|
|
1108
735
|
);
|
|
1109
736
|
}
|
|
1110
|
-
use([
|
|
1111
|
-
BarChart,
|
|
1112
|
-
CustomChart,
|
|
1113
|
-
LineChart,
|
|
1114
|
-
PieChart,
|
|
1115
|
-
GridComponent,
|
|
1116
|
-
LegendComponent,
|
|
1117
|
-
MarkAreaComponent,
|
|
1118
|
-
MarkLineComponent,
|
|
1119
|
-
MarkPointComponent,
|
|
1120
|
-
TooltipComponent,
|
|
1121
|
-
CanvasRenderer
|
|
1122
|
-
]);
|
|
1123
|
-
var HEADER_PAD_X = 16;
|
|
1124
|
-
var HEADER_PAD_TOP = 16;
|
|
1125
|
-
var HEADER_PAD_BOTTOM = 12;
|
|
1126
|
-
var HEADER_LINE_HEIGHT = 20;
|
|
1127
|
-
var HEADER_GAP = 4;
|
|
1128
|
-
var HEADER_FONT_SIZE = 14;
|
|
1129
|
-
function wrapChartText(text, maxWidth, measure) {
|
|
1130
|
-
const lines = [];
|
|
1131
|
-
let line = "";
|
|
1132
|
-
for (const ch of text) {
|
|
1133
|
-
if (ch === "\n") {
|
|
1134
|
-
lines.push(line);
|
|
1135
|
-
line = "";
|
|
1136
|
-
continue;
|
|
1137
|
-
}
|
|
1138
|
-
if (line !== "" && measure(line + ch) > maxWidth) {
|
|
1139
|
-
lines.push(line);
|
|
1140
|
-
line = ch.trim() === "" ? "" : ch;
|
|
1141
|
-
} else {
|
|
1142
|
-
line += ch;
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
if (line !== "" || lines.length === 0) lines.push(line);
|
|
1146
|
-
return lines.filter((l, i) => l !== "" || i < lines.length - 1);
|
|
1147
|
-
}
|
|
1148
|
-
function chartExportHeaderLayout(header, width, measure) {
|
|
1149
|
-
const title = header?.title?.trim();
|
|
1150
|
-
const summary = header?.summary?.trim();
|
|
1151
|
-
if (!title && !summary) return { lines: [], height: 0 };
|
|
1152
|
-
const room = Math.max(40, width - HEADER_PAD_X * 2);
|
|
1153
|
-
const lines = [
|
|
1154
|
-
...title ? wrapChartText(title, room, (t) => measure(t, "title")).map((text) => ({ text, kind: "title" })) : [],
|
|
1155
|
-
...summary ? wrapChartText(summary, room, (t) => measure(t, "summary")).map((text) => ({ text, kind: "summary" })) : []
|
|
1156
|
-
];
|
|
1157
|
-
const gap = title && summary ? HEADER_GAP : 0;
|
|
1158
|
-
return { lines, height: HEADER_PAD_TOP + lines.length * HEADER_LINE_HEIGHT + gap + HEADER_PAD_BOTTOM };
|
|
1159
|
-
}
|
|
1160
|
-
function loadImage(src) {
|
|
1161
|
-
return new Promise((resolve, reject) => {
|
|
1162
|
-
const image = new Image();
|
|
1163
|
-
image.onload = () => resolve(image);
|
|
1164
|
-
image.onerror = () => reject(new Error("PNG \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F"));
|
|
1165
|
-
image.src = src;
|
|
1166
|
-
});
|
|
1167
|
-
}
|
|
1168
|
-
async function pngWithHeader(dataUrl, header, look, pixelRatio) {
|
|
1169
|
-
const image = await loadImage(dataUrl);
|
|
1170
|
-
const width = image.width / pixelRatio;
|
|
1171
|
-
const plotHeight = image.height / pixelRatio;
|
|
1172
|
-
const canvas = document.createElement("canvas");
|
|
1173
|
-
const ctx = canvas.getContext("2d");
|
|
1174
|
-
if (!ctx) return dataUrl;
|
|
1175
|
-
const font = (kind) => `${kind === "title" ? 500 : 400} ${HEADER_FONT_SIZE}px ${look.fontFamily}`;
|
|
1176
|
-
ctx.font = font("title");
|
|
1177
|
-
const layout = chartExportHeaderLayout(header, width, (text, kind) => {
|
|
1178
|
-
ctx.font = font(kind);
|
|
1179
|
-
return ctx.measureText(text).width;
|
|
1180
|
-
});
|
|
1181
|
-
if (layout.height === 0) return dataUrl;
|
|
1182
|
-
canvas.width = Math.round(image.width);
|
|
1183
|
-
canvas.height = Math.round((layout.height + plotHeight) * pixelRatio);
|
|
1184
|
-
ctx.scale(pixelRatio, pixelRatio);
|
|
1185
|
-
ctx.fillStyle = look.background;
|
|
1186
|
-
ctx.fillRect(0, 0, width, layout.height + plotHeight);
|
|
1187
|
-
ctx.textBaseline = "middle";
|
|
1188
|
-
let y = HEADER_PAD_TOP;
|
|
1189
|
-
let previous = null;
|
|
1190
|
-
for (const line of layout.lines) {
|
|
1191
|
-
if (previous === "title" && line.kind === "summary") y += HEADER_GAP;
|
|
1192
|
-
ctx.font = font(line.kind);
|
|
1193
|
-
ctx.fillStyle = line.kind === "title" ? look.color : look.mutedColor;
|
|
1194
|
-
ctx.fillText(line.text, HEADER_PAD_X, y + HEADER_LINE_HEIGHT / 2);
|
|
1195
|
-
y += HEADER_LINE_HEIGHT;
|
|
1196
|
-
previous = line.kind;
|
|
1197
|
-
}
|
|
1198
|
-
ctx.drawImage(image, 0, layout.height, width, plotHeight);
|
|
1199
|
-
return canvas.toDataURL("image/png");
|
|
1200
|
-
}
|
|
1201
|
-
function useResolvedChartColors(colors) {
|
|
1202
|
-
const tokens = useChartTokens();
|
|
1203
|
-
const key = colors.join("\0");
|
|
1204
|
-
return useMemo(() => resolveChartColors(colors, tokens), [key, tokens]);
|
|
1205
|
-
}
|
|
1206
|
-
var COMPONENT_MAIN_TYPES = /* @__PURE__ */ new Set([
|
|
1207
|
-
"title",
|
|
1208
|
-
"legend",
|
|
1209
|
-
"grid",
|
|
1210
|
-
"xAxis",
|
|
1211
|
-
"yAxis",
|
|
1212
|
-
"polar",
|
|
1213
|
-
"radiusAxis",
|
|
1214
|
-
"angleAxis",
|
|
1215
|
-
"radar",
|
|
1216
|
-
"dataZoom",
|
|
1217
|
-
"visualMap",
|
|
1218
|
-
"tooltip",
|
|
1219
|
-
"axisPointer",
|
|
1220
|
-
"toolbox",
|
|
1221
|
-
"brush",
|
|
1222
|
-
"geo",
|
|
1223
|
-
"parallel",
|
|
1224
|
-
"parallelAxis",
|
|
1225
|
-
"singleAxis",
|
|
1226
|
-
"graphic",
|
|
1227
|
-
"calendar",
|
|
1228
|
-
"dataset",
|
|
1229
|
-
"series",
|
|
1230
|
-
"matrix",
|
|
1231
|
-
"thumbnail"
|
|
1232
|
-
]);
|
|
1233
|
-
function echartSetOptionOpts(prev, next) {
|
|
1234
|
-
const special = (o) => "timeline" in o || "baseOption" in o || "options" in o || "media" in o;
|
|
1235
|
-
if (!prev || special(prev) || special(next)) return { notMerge: true, lazyUpdate: true };
|
|
1236
|
-
const types = /* @__PURE__ */ new Set();
|
|
1237
|
-
for (const key of [...Object.keys(prev), ...Object.keys(next)]) if (COMPONENT_MAIN_TYPES.has(key)) types.add(key);
|
|
1238
|
-
return { notMerge: false, replaceMerge: [...types], lazyUpdate: true };
|
|
1239
|
-
}
|
|
1240
|
-
function withMotionPreference(option, reducedMotion) {
|
|
1241
|
-
return { ...option, animation: reducedMotion ? false : option.animation ?? true };
|
|
1242
|
-
}
|
|
1243
|
-
var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
1244
|
-
function usePrefersReducedMotion() {
|
|
1245
|
-
const [reduced, setReduced] = useState(
|
|
1246
|
-
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(REDUCED_MOTION_QUERY).matches
|
|
1247
|
-
);
|
|
1248
|
-
useEffect(() => {
|
|
1249
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1250
|
-
const media = window.matchMedia(REDUCED_MOTION_QUERY);
|
|
1251
|
-
const sync = () => setReduced(media.matches);
|
|
1252
|
-
sync();
|
|
1253
|
-
media.addEventListener("change", sync);
|
|
1254
|
-
return () => media.removeEventListener("change", sync);
|
|
1255
|
-
}, []);
|
|
1256
|
-
return reduced;
|
|
1257
|
-
}
|
|
1258
|
-
var EChart = forwardRef(function EChart2({
|
|
1259
|
-
option,
|
|
1260
|
-
height,
|
|
1261
|
-
loading = false,
|
|
1262
|
-
theme,
|
|
1263
|
-
onEvents,
|
|
1264
|
-
ariaLabel,
|
|
1265
|
-
className,
|
|
1266
|
-
actions = false,
|
|
1267
|
-
fileName = "chart.png",
|
|
1268
|
-
exportHeader
|
|
1269
|
-
}, ref) {
|
|
1270
|
-
const containerRef = useRef(null);
|
|
1271
|
-
const [instance, setInstance] = useState(null);
|
|
1272
|
-
const [copied, setCopied] = useState(false);
|
|
1273
|
-
const [tokens, setTokens] = useState(() => readChartTokens());
|
|
1274
|
-
const reducedMotion = usePrefersReducedMotion();
|
|
1275
|
-
const appliedRef = useRef(null);
|
|
1276
|
-
const tokensRef = useRef(tokens);
|
|
1277
|
-
useEffect(() => {
|
|
1278
|
-
if (theme !== void 0) return;
|
|
1279
|
-
const sync = () => {
|
|
1280
|
-
const next = readChartTokens();
|
|
1281
|
-
if (sameChartTokens(tokensRef.current, next)) return;
|
|
1282
|
-
tokensRef.current = next;
|
|
1283
|
-
setTokens(next);
|
|
1284
|
-
};
|
|
1285
|
-
sync();
|
|
1286
|
-
return watchChartTokens(sync);
|
|
1287
|
-
}, [theme]);
|
|
1288
|
-
const autoTheme = useMemo(() => tokens ? buildChartTheme(tokens) : void 0, [tokens]);
|
|
1289
|
-
const resolvedTheme = theme ?? autoTheme;
|
|
1290
|
-
useEffect(() => {
|
|
1291
|
-
const container = containerRef.current;
|
|
1292
|
-
if (!container) return;
|
|
1293
|
-
const inst = init(container, resolvedTheme, { renderer: "canvas" });
|
|
1294
|
-
appliedRef.current = null;
|
|
1295
|
-
container.dataset.rendering = "";
|
|
1296
|
-
inst.on("finished", () => {
|
|
1297
|
-
delete container.dataset.rendering;
|
|
1298
|
-
});
|
|
1299
|
-
setInstance(inst);
|
|
1300
|
-
let frame = 0;
|
|
1301
|
-
const observer = new ResizeObserver(() => {
|
|
1302
|
-
cancelAnimationFrame(frame);
|
|
1303
|
-
frame = requestAnimationFrame(() => {
|
|
1304
|
-
if (!inst.isDisposed()) inst.resize();
|
|
1305
|
-
});
|
|
1306
|
-
});
|
|
1307
|
-
observer.observe(container);
|
|
1308
|
-
return () => {
|
|
1309
|
-
observer.disconnect();
|
|
1310
|
-
cancelAnimationFrame(frame);
|
|
1311
|
-
inst.dispose();
|
|
1312
|
-
};
|
|
1313
|
-
}, [resolvedTheme]);
|
|
1314
|
-
useEffect(() => {
|
|
1315
|
-
if (!instance) return;
|
|
1316
|
-
if (containerRef.current) containerRef.current.dataset.rendering = "";
|
|
1317
|
-
const next = withMotionPreference(option, reducedMotion);
|
|
1318
|
-
instance.setOption(next, echartSetOptionOpts(appliedRef.current, next));
|
|
1319
|
-
appliedRef.current = next;
|
|
1320
|
-
}, [instance, option, reducedMotion]);
|
|
1321
|
-
useEffect(() => {
|
|
1322
|
-
if (!instance) return;
|
|
1323
|
-
if (loading) instance.showLoading();
|
|
1324
|
-
else instance.hideLoading();
|
|
1325
|
-
}, [instance, loading]);
|
|
1326
|
-
useEffect(() => {
|
|
1327
|
-
if (!instance || !onEvents) return;
|
|
1328
|
-
const entries = Object.entries(onEvents);
|
|
1329
|
-
for (const [event, handler] of entries) {
|
|
1330
|
-
instance.on(event, handler);
|
|
1331
|
-
}
|
|
1332
|
-
return () => {
|
|
1333
|
-
if (instance.isDisposed()) return;
|
|
1334
|
-
for (const [event, handler] of entries) {
|
|
1335
|
-
instance.off(event, handler);
|
|
1336
|
-
}
|
|
1337
|
-
};
|
|
1338
|
-
}, [instance, onEvents]);
|
|
1339
|
-
const includeTitle = typeof actions === "object" ? actions.includeTitle ?? true : true;
|
|
1340
|
-
const getPngDataUrl = useCallback(async () => {
|
|
1341
|
-
if (!instance) return null;
|
|
1342
|
-
let backgroundColor = "#ffffff";
|
|
1343
|
-
for (let el = containerRef.current; el; el = el.parentElement) {
|
|
1344
|
-
const bg = getComputedStyle(el).backgroundColor;
|
|
1345
|
-
if (bg && bg !== "rgba(0, 0, 0, 0)" && bg !== "transparent") {
|
|
1346
|
-
backgroundColor = bg;
|
|
1347
|
-
break;
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
const pixelRatio = 2;
|
|
1351
|
-
const dataUrl = instance.getDataURL({ type: "png", pixelRatio, backgroundColor });
|
|
1352
|
-
if (!includeTitle || !exportHeader || !(exportHeader.title || exportHeader.summary) || !containerRef.current) return dataUrl;
|
|
1353
|
-
try {
|
|
1354
|
-
const style = getComputedStyle(containerRef.current);
|
|
1355
|
-
return await pngWithHeader(
|
|
1356
|
-
dataUrl,
|
|
1357
|
-
exportHeader,
|
|
1358
|
-
{ background: backgroundColor, color: style.color, mutedColor: tokens?.mutedForeground ?? style.color, fontFamily: style.fontFamily },
|
|
1359
|
-
pixelRatio
|
|
1360
|
-
);
|
|
1361
|
-
} catch {
|
|
1362
|
-
return dataUrl;
|
|
1363
|
-
}
|
|
1364
|
-
}, [instance, includeTitle, exportHeader, tokens]);
|
|
1365
|
-
const handleCopy = useCallback(async () => {
|
|
1366
|
-
const dataUrl = await getPngDataUrl();
|
|
1367
|
-
if (!dataUrl) return;
|
|
1368
|
-
try {
|
|
1369
|
-
const blob = await (await fetch(dataUrl)).blob();
|
|
1370
|
-
await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
|
|
1371
|
-
setCopied(true);
|
|
1372
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
1373
|
-
} catch {
|
|
1374
|
-
}
|
|
1375
|
-
}, [getPngDataUrl]);
|
|
1376
|
-
const handleDownload = useCallback(async () => {
|
|
1377
|
-
const dataUrl = await getPngDataUrl();
|
|
1378
|
-
if (!dataUrl) return;
|
|
1379
|
-
const link = document.createElement("a");
|
|
1380
|
-
link.href = dataUrl;
|
|
1381
|
-
link.download = fileName;
|
|
1382
|
-
link.click();
|
|
1383
|
-
}, [getPngDataUrl, fileName]);
|
|
1384
|
-
const inFrame = useContext(ChartFrameContext);
|
|
1385
|
-
const styleHeight = height == null ? void 0 : typeof height === "number" ? `${height}px` : height;
|
|
1386
|
-
return /* @__PURE__ */ jsxs(
|
|
1387
|
-
"div",
|
|
1388
|
-
{
|
|
1389
|
-
ref,
|
|
1390
|
-
"data-slot": "echart",
|
|
1391
|
-
className: cn("group relative w-full", height == null && "h-[400px]", className),
|
|
1392
|
-
style: styleHeight != null ? { height: styleHeight } : void 0,
|
|
1393
|
-
children: [
|
|
1394
|
-
/* @__PURE__ */ jsx(
|
|
1395
|
-
"div",
|
|
1396
|
-
{
|
|
1397
|
-
ref: containerRef,
|
|
1398
|
-
"data-slot": "echart-canvas",
|
|
1399
|
-
className: "h-full w-full",
|
|
1400
|
-
role: inFrame ? void 0 : "img",
|
|
1401
|
-
"aria-label": inFrame ? void 0 : ariaLabel ?? "\u30C1\u30E3\u30FC\u30C8"
|
|
1402
|
-
}
|
|
1403
|
-
),
|
|
1404
|
-
actions && /* @__PURE__ */ jsxs(
|
|
1405
|
-
"div",
|
|
1406
|
-
{
|
|
1407
|
-
"data-slot": "echart-actions",
|
|
1408
|
-
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",
|
|
1409
|
-
children: [
|
|
1410
|
-
/* @__PURE__ */ jsx(
|
|
1411
|
-
Button,
|
|
1412
|
-
{
|
|
1413
|
-
type: "button",
|
|
1414
|
-
variant: "ghost",
|
|
1415
|
-
size: "icon-sm",
|
|
1416
|
-
onClick: handleCopy,
|
|
1417
|
-
"aria-label": copied ? "\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F" : "PNG \u3092\u30AF\u30EA\u30C3\u30D7\u30DC\u30FC\u30C9\u306B\u30B3\u30D4\u30FC",
|
|
1418
|
-
children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" })
|
|
1419
|
-
}
|
|
1420
|
-
),
|
|
1421
|
-
/* @__PURE__ */ jsx(
|
|
1422
|
-
Button,
|
|
1423
|
-
{
|
|
1424
|
-
type: "button",
|
|
1425
|
-
variant: "ghost",
|
|
1426
|
-
size: "icon-sm",
|
|
1427
|
-
onClick: handleDownload,
|
|
1428
|
-
"aria-label": "PNG \u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9",
|
|
1429
|
-
children: /* @__PURE__ */ jsx(Download, { className: "size-4" })
|
|
1430
|
-
}
|
|
1431
|
-
)
|
|
1432
|
-
]
|
|
1433
|
-
}
|
|
1434
|
-
)
|
|
1435
|
-
]
|
|
1436
|
-
}
|
|
1437
|
-
);
|
|
1438
|
-
});
|
|
1439
|
-
EChart.displayName = "EChart";
|
|
1440
737
|
|
|
1441
738
|
// ../squadkit/registry/lib/chart-utils.ts
|
|
1442
739
|
var ROOT_PROP_KEYS = /* @__PURE__ */ new Set(["id", "style", "role", "tabIndex", "lang", "hidden"]);
|
|
@@ -1939,6 +1236,8 @@ function timeFormat(locale, options) {
|
|
|
1939
1236
|
}
|
|
1940
1237
|
var toDate = (t) => new Date(t.year, t.month - 1, t.day);
|
|
1941
1238
|
var TIME_AXIS_MAX_LABELS = 6;
|
|
1239
|
+
var NARROW_PLOT_WIDTH = 400;
|
|
1240
|
+
var NARROW_TIME_AXIS_MAX_LABELS = 4;
|
|
1942
1241
|
var TIME_AXIS_STEPS = {
|
|
1943
1242
|
year: [1, 2, 5, 10, 20, 50, 100],
|
|
1944
1243
|
month: [1, 2, 3, 4, 6, 12, 24, 36, 60, 120],
|
|
@@ -2175,7 +1474,8 @@ var LEGEND_LINE_HEIGHT = 24;
|
|
|
2175
1474
|
var LEGEND_LINE_BUDGET = 320;
|
|
2176
1475
|
function legendLines(items, plotWidth, reserve = 0) {
|
|
2177
1476
|
const width = items.reduce((sum, name) => sum + [...name].length * 12 + 8 + 5 + 16, 0);
|
|
2178
|
-
const
|
|
1477
|
+
const narrow = plotWidth !== void 0 && plotWidth < NARROW_PLOT_WIDTH;
|
|
1478
|
+
const budget = Math.max(80, (plotWidth ? narrow ? plotWidth : Math.min(LEGEND_LINE_BUDGET, plotWidth) : LEGEND_LINE_BUDGET) - (narrow ? 0 : reserve));
|
|
2179
1479
|
return Math.min(3, Math.max(1, Math.ceil(width / budget)));
|
|
2180
1480
|
}
|
|
2181
1481
|
var ACTIONS_RESERVE = 80;
|
|
@@ -2331,7 +1631,13 @@ function buildCartesianOption(cfg) {
|
|
|
2331
1631
|
const last = labels.length - 1;
|
|
2332
1632
|
const timeStep = startEndOnly ? null : timeAxisLabelStep(
|
|
2333
1633
|
rawIndex,
|
|
2334
|
-
plotWidth ? Math.max(
|
|
1634
|
+
plotWidth ? Math.max(
|
|
1635
|
+
2,
|
|
1636
|
+
Math.min(
|
|
1637
|
+
plotWidth < NARROW_PLOT_WIDTH ? NARROW_TIME_AXIS_MAX_LABELS : TIME_AXIS_MAX_LABELS,
|
|
1638
|
+
Math.floor(plotWidth / TIME_LABEL_WIDTH)
|
|
1639
|
+
)
|
|
1640
|
+
) : void 0
|
|
2335
1641
|
);
|
|
2336
1642
|
const plainStep = (() => {
|
|
2337
1643
|
if (kind !== "line" || startEndOnly || timeStep !== null || !plotWidth || labels.length < 3) return 1;
|
|
@@ -2351,7 +1657,8 @@ function buildCartesianOption(cfg) {
|
|
|
2351
1657
|
const shareHighlight = percent && kind === "area";
|
|
2352
1658
|
const picked = highlight !== "auto" || mainIdx.length === 0 || percent && !shareHighlight ? [] : shareHighlight ? categories.length <= 2 ? pickShareHighlightPoints(values[0] ?? []) : [] : stackTotals ? pickHighlightPoints(stackTotals) : mainIdx.length <= 2 ? pickHighlightPoints(values[highlightSeries] ?? []) : [];
|
|
2353
1659
|
const pointGap = plotWidth && labels.length > 1 ? plotWidth / (kind === "bar" ? labels.length : labels.length - 1) : null;
|
|
2354
|
-
const
|
|
1660
|
+
const latestOnly = cfg.highlight === void 0 && !shareHighlight && picked.length === 2;
|
|
1661
|
+
const highlightPoints = latestOnly ? [picked[1]] : picked.length === 2 && pointGap !== null && Math.abs(picked[1].index - picked[0].index) * pointGap < HIGHLIGHT_LABEL_WIDTH ? [picked[1]] : picked;
|
|
2355
1662
|
const boundaryIndex = kind !== "bar" && !percent && cfg.forecast && cfg.forecast.data.length > 0 ? lastActual : -1;
|
|
2356
1663
|
const edgeAlign = (i) => horizontalBars || labels.length < 2 ? void 0 : i === boundaryIndex && i !== last ? { align: "right", offset: [-6, 0] } : i === last ? { align: "right", ...kind === "bar" ? { offset: [8, 0] } : {} } : i === 0 ? { align: "left", ...kind === "bar" ? { offset: [-8, 0] } : {} } : void 0;
|
|
2357
1664
|
const perBarTarget = kind === "bar" && Boolean(targetKey);
|
|
@@ -2500,6 +1807,8 @@ function buildCartesianOption(cfg) {
|
|
|
2500
1807
|
// 100% stacked: the top band's upper edge is the 100% line, not a value — drawn, it reads as「this band = 100%」.
|
|
2501
1808
|
lineStyle: percent && c === categories.length - 1 ? { width: 0, color, opacity: 0 } : { width: 2, color, opacity: dimSeries ? DIMMED : 1 },
|
|
2502
1809
|
itemStyle: { color, opacity: dimSeries ? DIMMED : 1 },
|
|
1810
|
+
// Hovering a series fades the others (not for a stack, where the bands read together).
|
|
1811
|
+
emphasis: stacked ? void 0 : { focus: "series" },
|
|
2503
1812
|
areaStyle: areaStyle && dimSeries ? { ...areaStyle, opacity: DIMMED * 0.3 } : areaStyle,
|
|
2504
1813
|
markPoint: markPointFor(c, color),
|
|
2505
1814
|
markLine: void 0,
|
|
@@ -2892,7 +2201,8 @@ function buildCartesianOption(cfg) {
|
|
|
2892
2201
|
legend: {
|
|
2893
2202
|
show: showLegend,
|
|
2894
2203
|
top: 0,
|
|
2895
|
-
|
|
2204
|
+
// Narrow: left-aligned and wrapping above the plot, so nothing is cut off at the right edge.
|
|
2205
|
+
...plotWidth !== void 0 && plotWidth < NARROW_PLOT_WIDTH ? { left: 0, right: 0 } : { right: reserveActions ? ACTIONS_RESERVE : 0 },
|
|
2896
2206
|
// Plain wraps onto a second line at narrow widths instead of hiding items behind arrows.
|
|
2897
2207
|
type: "plain",
|
|
2898
2208
|
icon: "circle",
|
|
@@ -2942,7 +2252,11 @@ function buildCartesianOption(cfg) {
|
|
|
2942
2252
|
};
|
|
2943
2253
|
};
|
|
2944
2254
|
const shares = percent ? cartesianSeriesValues(i <= lastActual ? [row] : [], categories, "percent") : null;
|
|
2945
|
-
|
|
2255
|
+
const legendRank = (p) => {
|
|
2256
|
+
const at = categories.indexOf(p.seriesName ?? "");
|
|
2257
|
+
return at === -1 ? categories.length : at;
|
|
2258
|
+
};
|
|
2259
|
+
for (const p of [...list].sort((a, b) => legendRank(a) - legendRank(b))) {
|
|
2946
2260
|
const color = typeof p.color === "string" ? p.color : "currentColor";
|
|
2947
2261
|
if (p.seriesId === FORECAST_SERIES_ID) {
|
|
2948
2262
|
if (i > lastActual) rows.push({ name: p.seriesName ?? forecastLabel, color, value: forecastValues[i] ?? null });
|
|
@@ -3210,8 +2524,7 @@ function AreaChartImpl({
|
|
|
3210
2524
|
className,
|
|
3211
2525
|
...rest
|
|
3212
2526
|
}, ref) {
|
|
3213
|
-
const tokens =
|
|
3214
|
-
const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
|
|
2527
|
+
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
3215
2528
|
const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
3216
2529
|
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
3217
2530
|
const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
@@ -3393,8 +2706,7 @@ function BarChartImpl({
|
|
|
3393
2706
|
className,
|
|
3394
2707
|
...rest
|
|
3395
2708
|
}, ref) {
|
|
3396
|
-
const tokens =
|
|
3397
|
-
const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
|
|
2709
|
+
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
3398
2710
|
const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
3399
2711
|
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
3400
2712
|
const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
@@ -3529,8 +2841,8 @@ function BarChartImpl({
|
|
|
3529
2841
|
}
|
|
3530
2842
|
);
|
|
3531
2843
|
}
|
|
3532
|
-
var
|
|
3533
|
-
|
|
2844
|
+
var BarChart = forwardRef(BarChartImpl);
|
|
2845
|
+
BarChart.displayName = "BarChart";
|
|
3534
2846
|
var NO_ROWS3 = [];
|
|
3535
2847
|
function LineChartImpl({
|
|
3536
2848
|
data = NO_ROWS3,
|
|
@@ -3578,8 +2890,7 @@ function LineChartImpl({
|
|
|
3578
2890
|
className,
|
|
3579
2891
|
...rest
|
|
3580
2892
|
}, ref) {
|
|
3581
|
-
const tokens =
|
|
3582
|
-
const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
|
|
2893
|
+
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
3583
2894
|
const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
3584
2895
|
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
3585
2896
|
const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format2), [valueFormatter, format2]);
|
|
@@ -3716,8 +3027,8 @@ function LineChartImpl({
|
|
|
3716
3027
|
}
|
|
3717
3028
|
);
|
|
3718
3029
|
}
|
|
3719
|
-
var
|
|
3720
|
-
|
|
3030
|
+
var LineChart = forwardRef(LineChartImpl);
|
|
3031
|
+
LineChart.displayName = "LineChart";
|
|
3721
3032
|
function useElementWidth() {
|
|
3722
3033
|
const [node, setNode] = useState(null);
|
|
3723
3034
|
const [width, setWidth] = useState(null);
|
|
@@ -3767,7 +3078,7 @@ function DonutChartImpl({
|
|
|
3767
3078
|
const maxSlices = donutOptions?.maxSlices;
|
|
3768
3079
|
const showLegend = donutOptions?.showLegend ?? true;
|
|
3769
3080
|
const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
|
|
3770
|
-
const tokens =
|
|
3081
|
+
const { ref: frameRef, tokens } = useChartSurface(ref);
|
|
3771
3082
|
const slices = useMemo(
|
|
3772
3083
|
() => donutSlices(data, { index: labelKey, value: valueKey, colors, maxSlices, otherColor: CHART_OTHER_COLOR }),
|
|
3773
3084
|
[data, labelKey, valueKey, colors, maxSlices]
|
|
@@ -3833,7 +3144,7 @@ function DonutChartImpl({
|
|
|
3833
3144
|
ChartFrame,
|
|
3834
3145
|
{
|
|
3835
3146
|
...chartRootProps(rest),
|
|
3836
|
-
ref,
|
|
3147
|
+
ref: frameRef,
|
|
3837
3148
|
title,
|
|
3838
3149
|
summary: resolvedSummary,
|
|
3839
3150
|
isLoading: isLoading ?? loading ?? false,
|
|
@@ -4149,8 +3460,14 @@ function blockColorToCss(color) {
|
|
|
4149
3460
|
}
|
|
4150
3461
|
var NO_ROWS7 = [];
|
|
4151
3462
|
var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hoverEffect = true, className, ...props }, ref) {
|
|
3463
|
+
const containerRef = useRef(null);
|
|
3464
|
+
const setRef = useCallback((node) => {
|
|
3465
|
+
containerRef.current = node;
|
|
3466
|
+
if (typeof ref === "function") return ref(node);
|
|
3467
|
+
if (ref) ref.current = node;
|
|
3468
|
+
}, [ref]);
|
|
4152
3469
|
const fallback = defaultColor ? blockColorToCss(defaultColor) : DEFAULT_BLOCK_COLOR;
|
|
4153
|
-
return /* @__PURE__ */ jsx("div", { ref, "data-slot": "tracker", className: cn("flex h-6 w-full gap-0.5", className), ...props, children: data.map((block, i) => {
|
|
3470
|
+
return /* @__PURE__ */ jsx("div", { ref: setRef, "data-slot": "tracker", className: cn("flex h-6 w-full gap-0.5", className), ...props, children: data.map((block, i) => {
|
|
4154
3471
|
const blockClass = cn(
|
|
4155
3472
|
"h-full min-w-0 flex-1 rounded-[2px]",
|
|
4156
3473
|
hoverEffect && "transition-opacity hover:opacity-60 motion-reduce:transition-none"
|
|
@@ -4164,7 +3481,7 @@ var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hove
|
|
|
4164
3481
|
render: /* @__PURE__ */ jsx("div", { "data-slot": "tracker-block", role: "img", tabIndex: 0, "aria-label": block.tooltip, className: blockClass, style })
|
|
4165
3482
|
}
|
|
4166
3483
|
),
|
|
4167
|
-
/* @__PURE__ */ jsx(TooltipContent, { children: block.tooltip })
|
|
3484
|
+
/* @__PURE__ */ jsx(TooltipContent, { container: containerRef, children: block.tooltip })
|
|
4168
3485
|
] }, block.key ?? i) : /* @__PURE__ */ jsx("div", { "data-slot": "tracker-block", className: blockClass, style }, block.key ?? i);
|
|
4169
3486
|
}) });
|
|
4170
3487
|
});
|
|
@@ -4541,8 +3858,7 @@ function WaterfallChartImpl({
|
|
|
4541
3858
|
...rest
|
|
4542
3859
|
}, ref) {
|
|
4543
3860
|
const valueKey = categories[0] ?? "";
|
|
4544
|
-
const tokens =
|
|
4545
|
-
const { ref: frameRef, width: plotWidth } = useChartSurface(ref, tokens);
|
|
3861
|
+
const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
|
|
4546
3862
|
const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
|
|
4547
3863
|
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatterProp, format2), [valueFormatterProp, format2]);
|
|
4548
3864
|
const steps = useMemo(() => waterfallSteps(data, { index, value: valueKey, totals, mode }), [data, index, valueKey, totals, mode]);
|
|
@@ -4941,8 +4257,7 @@ function ScatterChartImpl({
|
|
|
4941
4257
|
className,
|
|
4942
4258
|
...rest
|
|
4943
4259
|
}, ref) {
|
|
4944
|
-
const tokens =
|
|
4945
|
-
const { ref: frameRef, width: plotWidth } = useChartSurface(ref, tokens);
|
|
4260
|
+
const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
|
|
4946
4261
|
const formatters = useMemo(
|
|
4947
4262
|
() => ({
|
|
4948
4263
|
x: resolveValueFormatter(valueFormatter, xFormat ?? format2),
|
|
@@ -5646,8 +4961,7 @@ function HeatmapImpl({
|
|
|
5646
4961
|
ariaLabel,
|
|
5647
4962
|
...rest
|
|
5648
4963
|
}, ref) {
|
|
5649
|
-
const tokens =
|
|
5650
|
-
const { ref: frameRef, surface, width: plotWidth } = useChartSurface(ref, tokens);
|
|
4964
|
+
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
5651
4965
|
const formatter = useMemo(() => resolveValueFormatter(valueFormatter, format2 ?? "number"), [valueFormatter, format2]);
|
|
5652
4966
|
const model = useMemo(
|
|
5653
4967
|
() => buildHeatmapModel({ data, x, y, value, xLabels, yLabels, flag, scale, minValue, maxValue }),
|
|
@@ -5716,149 +5030,6 @@ function HeatmapLegend({
|
|
|
5716
5030
|
}
|
|
5717
5031
|
var Heatmap = forwardRef(HeatmapImpl);
|
|
5718
5032
|
Heatmap.displayName = "Heatmap";
|
|
5719
|
-
var VB_WIDTH = 100;
|
|
5720
|
-
function normalizeData(values, height, vPad = 2) {
|
|
5721
|
-
const min = Math.min(...values);
|
|
5722
|
-
const max = Math.max(...values);
|
|
5723
|
-
const range = max - min;
|
|
5724
|
-
const drawHeight = height - vPad * 2;
|
|
5725
|
-
if (range === 0) return values.map(() => vPad + drawHeight / 2);
|
|
5726
|
-
return values.map((v) => height - vPad - (v - min) / range * drawHeight);
|
|
5727
|
-
}
|
|
5728
|
-
function buildLinePath(ys) {
|
|
5729
|
-
if (ys.length === 0) return "";
|
|
5730
|
-
const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
|
|
5731
|
-
return ys.map((y, i) => `${i === 0 ? "M" : "L"}${(i * step).toFixed(2)},${y.toFixed(2)}`).join(" ");
|
|
5732
|
-
}
|
|
5733
|
-
function buildAreaPath(ys, height) {
|
|
5734
|
-
if (ys.length === 0) return "";
|
|
5735
|
-
const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
|
|
5736
|
-
const lastX = ((ys.length - 1) * step).toFixed(2);
|
|
5737
|
-
return `${buildLinePath(ys)} L${lastX},${height} L0,${height} Z`;
|
|
5738
|
-
}
|
|
5739
|
-
function sparklineHighlightPoints(values) {
|
|
5740
|
-
if (values.length === 0) return [];
|
|
5741
|
-
const last = values.length - 1;
|
|
5742
|
-
const points = [{ kind: "latest", index: last }];
|
|
5743
|
-
let maxI = 0;
|
|
5744
|
-
let minI = 0;
|
|
5745
|
-
let max = values[0];
|
|
5746
|
-
let min = max;
|
|
5747
|
-
values.forEach((v, i) => {
|
|
5748
|
-
if (v >= max) [max, maxI] = [v, i];
|
|
5749
|
-
if (v <= min) [min, minI] = [v, i];
|
|
5750
|
-
});
|
|
5751
|
-
const latest = values[last];
|
|
5752
|
-
if (max === min) return points;
|
|
5753
|
-
if (max !== latest) points.push({ kind: "max", index: maxI });
|
|
5754
|
-
if (min !== latest) points.push({ kind: "min", index: minI });
|
|
5755
|
-
return points;
|
|
5756
|
-
}
|
|
5757
|
-
function buildBarRects(ys, height, gap = 1) {
|
|
5758
|
-
const barW = Math.max(1, VB_WIDTH / ys.length - gap);
|
|
5759
|
-
return ys.map((y, i) => ({ x: i * (barW + gap), y, w: barW, h: height - y }));
|
|
5760
|
-
}
|
|
5761
|
-
var NO_ROWS12 = [];
|
|
5762
|
-
var Sparkline = forwardRef(function Sparkline2({
|
|
5763
|
-
data = NO_ROWS12,
|
|
5764
|
-
variant = "line",
|
|
5765
|
-
height = 40,
|
|
5766
|
-
color = "text-chart-1",
|
|
5767
|
-
area = false,
|
|
5768
|
-
animate = false,
|
|
5769
|
-
highlight = "auto",
|
|
5770
|
-
"aria-label": ariaLabel,
|
|
5771
|
-
className,
|
|
5772
|
-
...props
|
|
5773
|
-
}, ref) {
|
|
5774
|
-
const [mounted, setMounted] = useState(false);
|
|
5775
|
-
useEffect(() => {
|
|
5776
|
-
if (animate) setMounted(true);
|
|
5777
|
-
}, [animate]);
|
|
5778
|
-
if (data.length === 0) return null;
|
|
5779
|
-
const values = data.map((d) => d.value);
|
|
5780
|
-
const ys = normalizeData(values, height);
|
|
5781
|
-
const step = ys.length > 1 ? VB_WIDTH / (ys.length - 1) : 0;
|
|
5782
|
-
const points = variant !== "line" ? [] : highlight === "auto" ? sparklineHighlightPoints(values) : highlight === "latest" ? [{ kind: "latest", index: values.length - 1 }] : [];
|
|
5783
|
-
return /* @__PURE__ */ jsxs(
|
|
5784
|
-
"svg",
|
|
5785
|
-
{
|
|
5786
|
-
ref,
|
|
5787
|
-
"data-slot": "sparkline",
|
|
5788
|
-
viewBox: `0 0 ${VB_WIDTH} ${height}`,
|
|
5789
|
-
preserveAspectRatio: "none",
|
|
5790
|
-
width: "100%",
|
|
5791
|
-
height,
|
|
5792
|
-
role: ariaLabel ? "img" : void 0,
|
|
5793
|
-
"aria-label": ariaLabel,
|
|
5794
|
-
"aria-hidden": ariaLabel ? void 0 : true,
|
|
5795
|
-
className: cn("overflow-visible", className),
|
|
5796
|
-
...props,
|
|
5797
|
-
children: [
|
|
5798
|
-
variant === "line" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5799
|
-
area && /* @__PURE__ */ jsx(
|
|
5800
|
-
"path",
|
|
5801
|
-
{
|
|
5802
|
-
d: buildAreaPath(ys, height),
|
|
5803
|
-
strokeWidth: 0,
|
|
5804
|
-
className: cn("fill-current opacity-15", color)
|
|
5805
|
-
}
|
|
5806
|
-
),
|
|
5807
|
-
/* @__PURE__ */ jsx(
|
|
5808
|
-
"path",
|
|
5809
|
-
{
|
|
5810
|
-
d: buildLinePath(ys),
|
|
5811
|
-
fill: "none",
|
|
5812
|
-
strokeWidth: 1.5,
|
|
5813
|
-
strokeLinecap: "round",
|
|
5814
|
-
strokeLinejoin: "round",
|
|
5815
|
-
vectorEffect: "non-scaling-stroke",
|
|
5816
|
-
pathLength: animate ? 1 : void 0,
|
|
5817
|
-
strokeDasharray: animate ? 1 : void 0,
|
|
5818
|
-
strokeDashoffset: animate ? mounted ? 0 : 1 : void 0,
|
|
5819
|
-
className: cn("stroke-current", animate && "motion-reduce:transition-none!", color),
|
|
5820
|
-
style: animate ? { transition: "stroke-dashoffset 0.6s ease-in-out" } : void 0
|
|
5821
|
-
}
|
|
5822
|
-
),
|
|
5823
|
-
points.map((p) => {
|
|
5824
|
-
const x = (p.index * step).toFixed(2);
|
|
5825
|
-
const y = (ys[p.index] ?? 0).toFixed(2);
|
|
5826
|
-
return /* @__PURE__ */ jsx(
|
|
5827
|
-
"path",
|
|
5828
|
-
{
|
|
5829
|
-
"data-slot": "sparkline-point",
|
|
5830
|
-
"data-point": p.kind,
|
|
5831
|
-
d: `M${x},${y} L${x},${y}`,
|
|
5832
|
-
fill: "none",
|
|
5833
|
-
strokeWidth: p.kind === "latest" ? 5 : 4,
|
|
5834
|
-
strokeLinecap: "round",
|
|
5835
|
-
vectorEffect: "non-scaling-stroke",
|
|
5836
|
-
className: cn("stroke-current", p.kind === "latest" ? color : "text-muted-foreground")
|
|
5837
|
-
},
|
|
5838
|
-
p.kind
|
|
5839
|
-
);
|
|
5840
|
-
})
|
|
5841
|
-
] }),
|
|
5842
|
-
variant === "bar" && buildBarRects(ys, height).map((rect, i) => /* @__PURE__ */ jsx(
|
|
5843
|
-
"rect",
|
|
5844
|
-
{
|
|
5845
|
-
x: rect.x,
|
|
5846
|
-
y: animate ? mounted ? rect.y : height : rect.y,
|
|
5847
|
-
width: rect.w,
|
|
5848
|
-
height: animate ? mounted ? rect.h : 0 : rect.h,
|
|
5849
|
-
rx: 0.5,
|
|
5850
|
-
className: cn("fill-current", animate && "motion-reduce:transition-none!", color),
|
|
5851
|
-
style: animate ? {
|
|
5852
|
-
transition: `height 0.4s ease-out ${i * 0.02}s, y 0.4s ease-out ${i * 0.02}s`
|
|
5853
|
-
} : void 0
|
|
5854
|
-
},
|
|
5855
|
-
i
|
|
5856
|
-
))
|
|
5857
|
-
]
|
|
5858
|
-
}
|
|
5859
|
-
);
|
|
5860
|
-
});
|
|
5861
|
-
Sparkline.displayName = "Sparkline";
|
|
5862
5033
|
function resolveFormat(format2, row) {
|
|
5863
5034
|
return typeof format2 === "function" ? format2(row) : format2;
|
|
5864
5035
|
}
|
|
@@ -5923,10 +5094,10 @@ function useDataTable() {
|
|
|
5923
5094
|
if (!ctx) throw new Error("useDataTable must be used inside <DataTable>");
|
|
5924
5095
|
return ctx;
|
|
5925
5096
|
}
|
|
5926
|
-
var
|
|
5097
|
+
var NO_ROWS12 = [];
|
|
5927
5098
|
function DataTable({
|
|
5928
|
-
columns =
|
|
5929
|
-
data =
|
|
5099
|
+
columns = NO_ROWS12,
|
|
5100
|
+
data = NO_ROWS12,
|
|
5930
5101
|
enableSorting = true,
|
|
5931
5102
|
sorting: sortingProp,
|
|
5932
5103
|
onSortingChange,
|
|
@@ -7362,7 +6533,7 @@ var deltaVariants = cva(
|
|
|
7362
6533
|
{
|
|
7363
6534
|
variants: {
|
|
7364
6535
|
variant: {
|
|
7365
|
-
badge: "h-5 rounded-
|
|
6536
|
+
badge: "h-5 rounded-md border px-2 py-0.5 text-xs font-medium [&>svg]:size-3",
|
|
7366
6537
|
inline: "text-sm [&>svg]:size-3.5"
|
|
7367
6538
|
},
|
|
7368
6539
|
sentiment: {
|
|
@@ -7372,9 +6543,9 @@ var deltaVariants = cva(
|
|
|
7372
6543
|
}
|
|
7373
6544
|
},
|
|
7374
6545
|
compoundVariants: [
|
|
7375
|
-
{ variant: "badge", sentiment: "positive", className: "bg-positive-subtle" },
|
|
7376
|
-
{ variant: "badge", sentiment: "negative", className: "bg-negative-subtle" },
|
|
7377
|
-
{ variant: "badge", sentiment: "neutral", className: "bg-neutral-subtle" }
|
|
6546
|
+
{ variant: "badge", sentiment: "positive", className: "border-positive/20 bg-positive-subtle dark:border-positive/25" },
|
|
6547
|
+
{ variant: "badge", sentiment: "negative", className: "border-negative/20 bg-negative-subtle dark:border-negative/25" },
|
|
6548
|
+
{ variant: "badge", sentiment: "neutral", className: "border-neutral/20 bg-neutral-subtle dark:border-neutral/25" }
|
|
7378
6549
|
],
|
|
7379
6550
|
defaultVariants: {
|
|
7380
6551
|
variant: "badge",
|
|
@@ -7395,6 +6566,7 @@ var Delta = forwardRef(
|
|
|
7395
6566
|
({
|
|
7396
6567
|
value,
|
|
7397
6568
|
comparison,
|
|
6569
|
+
betterWhen,
|
|
7398
6570
|
polarity,
|
|
7399
6571
|
neutralBand,
|
|
7400
6572
|
format: format2,
|
|
@@ -7407,7 +6579,7 @@ var Delta = forwardRef(
|
|
|
7407
6579
|
...props
|
|
7408
6580
|
}, ref) => {
|
|
7409
6581
|
if (!comparison) return null;
|
|
7410
|
-
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 });
|
|
7411
6583
|
const display = change ?? defaultChangeDisplay(format2);
|
|
7412
6584
|
const formatDigits = typeof format2 === "object" && format2 !== null && "digits" in format2 ? format2.digits : void 0;
|
|
7413
6585
|
const changeDigits = display === "points" ? digits ?? formatDigits : digits;
|
|
@@ -7443,6 +6615,9 @@ var SPARKLINE_MIN_POINTS = 6;
|
|
|
7443
6615
|
var SPARKLINE_HEIGHT = 32;
|
|
7444
6616
|
var DELTA_PLACEMENT = "col-start-1 row-span-1 row-start-3 justify-self-start @[288px]/card:col-start-2 @[288px]/card:row-span-2 @[288px]/card:row-start-1 @[288px]/card:justify-self-end";
|
|
7445
6617
|
var HEADER_CLASS = "@container/card pb-(--card-spacing)";
|
|
6618
|
+
var LONG_VALUE_CHARS = 10;
|
|
6619
|
+
var DELTA_UNDER_PLACEMENT = "col-start-1 row-span-1 row-start-3 justify-self-start";
|
|
6620
|
+
var KPI_FOOTER_CLASS = "flex-col items-start gap-2 rounded-none border-t-0 bg-transparent pt-0 text-sm";
|
|
7446
6621
|
var PLACEHOLDER = /\{(\w+)\}/g;
|
|
7447
6622
|
var isJapanese2 = (locale) => locale.toLowerCase().startsWith("ja");
|
|
7448
6623
|
var isMissing = (v) => v === null || v === void 0 || v === "";
|
|
@@ -7479,6 +6654,9 @@ function warnShallowSummary(template) {
|
|
|
7479
6654
|
`[KpiCard] summary="${template}" only repeats the delta badge and the previous actual. Say one fact beyond the comparison \u2014 composition, target, record or rate (e.g. "{label}\u306F\u76EE\u6A19\u306E {achievement} \u307E\u3067\u6765\u3066\u3044\u307E\u3059\u3002").`
|
|
7480
6655
|
);
|
|
7481
6656
|
}
|
|
6657
|
+
function digitGroups(text) {
|
|
6658
|
+
return text.match(/[^,,]*[,,]|[^,,]+$/g) ?? [text];
|
|
6659
|
+
}
|
|
7482
6660
|
function KpiCard({
|
|
7483
6661
|
label: label2,
|
|
7484
6662
|
value,
|
|
@@ -7487,7 +6665,8 @@ function KpiCard({
|
|
|
7487
6665
|
comparison: comparisonProp,
|
|
7488
6666
|
comparisons,
|
|
7489
6667
|
provisional,
|
|
7490
|
-
|
|
6668
|
+
betterWhen,
|
|
6669
|
+
polarity: polarityProp,
|
|
7491
6670
|
change,
|
|
7492
6671
|
neutralBand,
|
|
7493
6672
|
showPrevious = true,
|
|
@@ -7514,6 +6693,7 @@ function KpiCard({
|
|
|
7514
6693
|
const isProvisional = provisional !== void 0 && provisional !== false;
|
|
7515
6694
|
const provisionalLabel = typeof provisional === "object" && provisional.label ? provisional.label : "\u901F\u5831";
|
|
7516
6695
|
const sample = useSampleMark();
|
|
6696
|
+
const polarity = betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarityProp;
|
|
7517
6697
|
const neutral = polarity === "neutral";
|
|
7518
6698
|
const hasPrevious = comparison !== void 0 && showPrevious;
|
|
7519
6699
|
const stacked = allComparisons.length > 1;
|
|
@@ -7565,7 +6745,7 @@ function KpiCard({
|
|
|
7565
6745
|
/* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-3/5" })
|
|
7566
6746
|
] }) : null
|
|
7567
6747
|
] }),
|
|
7568
|
-
(summary || record || hasTarget && !targetBar || sourceParts.length > 0 || hasUpdated || showSparkline) && /* @__PURE__ */ jsxs(CardFooter, { className:
|
|
6748
|
+
(summary || record || hasTarget && !targetBar || sourceParts.length > 0 || hasUpdated || showSparkline) && /* @__PURE__ */ jsxs(CardFooter, { className: KPI_FOOTER_CLASS, children: [
|
|
7569
6749
|
summary && /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-4/5" }),
|
|
7570
6750
|
record && /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-28 rounded-4xl" }),
|
|
7571
6751
|
hasTarget && !targetBar && /* @__PURE__ */ jsx(Skeleton, { "aria-hidden": "true", className: "h-5 w-3/5" }),
|
|
@@ -7646,27 +6826,32 @@ function KpiCard({
|
|
|
7646
6826
|
},
|
|
7647
6827
|
i
|
|
7648
6828
|
));
|
|
6829
|
+
const valueText = fmt(value);
|
|
6830
|
+
const longValue = valueText.length > LONG_VALUE_CHARS;
|
|
7649
6831
|
return /* @__PURE__ */ jsxs(Card, { "data-slot": "kpi-card", size, className: cardClass, ...props, children: [
|
|
7650
6832
|
/* @__PURE__ */ jsxs(CardHeader, { className: HEADER_CLASS, children: [
|
|
7651
|
-
/* @__PURE__ */ jsx(CardDescription, { "data-slot": "kpi-card-label", title: label2, className: "col-start-1 min-w-0 truncate text-[13px] font-medium text-muted-foreground", children: label2 }),
|
|
6833
|
+
/* @__PURE__ */ jsx(CardDescription, { "data-slot": "kpi-card-label", title: label2, className: "col-start-1 min-w-0 truncate text-[13px] leading-snug font-medium text-muted-foreground", children: label2 }),
|
|
7652
6834
|
/* @__PURE__ */ jsxs(
|
|
7653
6835
|
CardTitle,
|
|
7654
6836
|
{
|
|
7655
6837
|
"data-slot": "kpi-card-value",
|
|
7656
|
-
title:
|
|
6838
|
+
title: valueText,
|
|
7657
6839
|
className: cn(
|
|
7658
|
-
"col-start-1 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 font-semibold tracking-tight tabular-nums",
|
|
6840
|
+
"col-start-1 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 leading-none font-semibold tracking-tight tabular-nums",
|
|
7659
6841
|
// Fixed size: the step follows the card width only, never the length of the value.
|
|
7660
6842
|
valueSize
|
|
7661
6843
|
),
|
|
7662
6844
|
children: [
|
|
7663
|
-
/* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children:
|
|
6845
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "kpi-card-value-text", className: longValue ? "min-w-0 break-words" : "whitespace-nowrap", children: longValue ? digitGroups(valueText).map((group, i) => /* @__PURE__ */ jsxs("span", { className: "whitespace-nowrap", children: [
|
|
6846
|
+
group,
|
|
6847
|
+
/* @__PURE__ */ jsx("wbr", {})
|
|
6848
|
+
] }, i)) : valueText }),
|
|
7664
6849
|
isProvisional && /* @__PURE__ */ jsx(Badge, { "data-slot": "kpi-card-provisional", variant: "outline", className: "align-middle", children: provisionalLabel }),
|
|
7665
6850
|
sample && /* @__PURE__ */ jsx(SampleBadge, { label: sample.label })
|
|
7666
6851
|
]
|
|
7667
6852
|
}
|
|
7668
6853
|
),
|
|
7669
|
-
comparison && (stacked ? /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-comparisons", className: "flex flex-wrap items-center gap-1", children: deltas }) : /* @__PURE__ */ jsx(CardAction, { className: DELTA_PLACEMENT, children: deltas })),
|
|
6854
|
+
comparison && (stacked ? /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-comparisons", className: "flex flex-wrap items-center gap-1", children: deltas }) : /* @__PURE__ */ jsx(CardAction, { className: longValue ? DELTA_UNDER_PLACEMENT : DELTA_PLACEMENT, children: deltas })),
|
|
7670
6855
|
hasPrevious && comparison && /* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-previous", className: "col-span-full text-sm text-muted-foreground tabular-nums", children: result?.previous != null ? `${baseline} ${fmt(result.previous)}` : `${baseline}\u306E\u5B9F\u7E3E\u306A\u3057` }),
|
|
7671
6856
|
bar && progress && /* @__PURE__ */ jsxs("div", { "data-slot": "kpi-card-target-progress", className: "col-span-full mt-1 flex min-w-0 flex-col gap-1.5", children: [
|
|
7672
6857
|
/* @__PURE__ */ jsxs(
|
|
@@ -7719,8 +6904,8 @@ function KpiCard({
|
|
|
7719
6904
|
)
|
|
7720
6905
|
] })
|
|
7721
6906
|
] }),
|
|
7722
|
-
hasFooter && /* @__PURE__ */ jsxs(CardFooter, { className:
|
|
7723
|
-
summaryText && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-summary", title: summaryText, className: "line-clamp-2
|
|
6907
|
+
hasFooter && /* @__PURE__ */ jsxs(CardFooter, { className: KPI_FOOTER_CLASS, children: [
|
|
6908
|
+
summaryText && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-summary", title: summaryText, className: "line-clamp-2 text-sm leading-relaxed text-muted-foreground tabular-nums", children: summaryText }),
|
|
7724
6909
|
record && /* @__PURE__ */ jsx(Badge, { "data-slot": "kpi-card-record", variant: "outline", children: record.label }),
|
|
7725
6910
|
targetText && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-target", className: "text-muted-foreground tabular-nums", children: targetText }),
|
|
7726
6911
|
sourceParts.length > 0 && /* @__PURE__ */ jsx(
|
|
@@ -7728,11 +6913,11 @@ function KpiCard({
|
|
|
7728
6913
|
{
|
|
7729
6914
|
"data-slot": "kpi-card-source",
|
|
7730
6915
|
title: sourceParts.join("\u30FB"),
|
|
7731
|
-
className: "line-clamp-2 w-full text-xs text-muted-foreground tabular-nums",
|
|
6916
|
+
className: "line-clamp-2 w-full text-xs leading-normal text-muted-foreground tabular-nums",
|
|
7732
6917
|
children: sourceParts.join("\u30FB")
|
|
7733
6918
|
}
|
|
7734
6919
|
),
|
|
7735
|
-
hasUpdated && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-updated", className: "text-xs text-muted-foreground", children: updatedAtText(updatedAt, updatedAtDisplay, locale, now, timeZone) }),
|
|
6920
|
+
hasUpdated && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-updated", className: "text-xs leading-normal text-muted-foreground", children: updatedAtText(updatedAt, updatedAtDisplay, locale, now, timeZone) }),
|
|
7736
6921
|
showSparkline && // mt-auto: the footers of a row are as tall as the tallest, so the sparklines share one bottom edge.
|
|
7737
6922
|
/* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-history", className: "mt-auto w-full pt-2 text-chart-1", children: /* @__PURE__ */ jsx(
|
|
7738
6923
|
Sparkline,
|
|
@@ -7756,8 +6941,8 @@ function updatedAtText(updatedAt, display, locale, now, timeZone) {
|
|
|
7756
6941
|
var trendIndicatorVariants = cva("inline-flex items-center gap-0.5 text-sm font-medium", {
|
|
7757
6942
|
variants: {
|
|
7758
6943
|
sentiment: {
|
|
7759
|
-
positive: "text-
|
|
7760
|
-
negative: "text-
|
|
6944
|
+
positive: "text-positive",
|
|
6945
|
+
negative: "text-negative",
|
|
7761
6946
|
neutral: "text-muted-foreground"
|
|
7762
6947
|
}
|
|
7763
6948
|
},
|
|
@@ -7817,11 +7002,11 @@ var legacyColorTones = {
|
|
|
7817
7002
|
blue: "info"
|
|
7818
7003
|
};
|
|
7819
7004
|
var toneStyles = {
|
|
7820
|
-
positive: { dot: "bg-positive", bg: "bg-positive-subtle", text: "text-positive" },
|
|
7821
|
-
negative: { dot: "bg-negative", bg: "bg-negative-subtle", text: "text-negative" },
|
|
7822
|
-
warning: { dot: "bg-warning", bg: "bg-warning-subtle", text: "text-warning" },
|
|
7823
|
-
info: { dot: "bg-info", bg: "bg-info-subtle", text: "text-info" },
|
|
7824
|
-
neutral: { dot: "bg-neutral", bg: "bg-neutral-subtle", text: "text-neutral" }
|
|
7005
|
+
positive: { dot: "bg-positive", bg: "bg-positive-subtle", text: "text-positive", border: "border-positive/20 dark:border-positive/25" },
|
|
7006
|
+
negative: { dot: "bg-negative", bg: "bg-negative-subtle", text: "text-negative", border: "border-negative/20 dark:border-negative/25" },
|
|
7007
|
+
warning: { dot: "bg-warning", bg: "bg-warning-subtle", text: "text-warning", border: "border-warning/20 dark:border-warning/25" },
|
|
7008
|
+
info: { dot: "bg-info", bg: "bg-info-subtle", text: "text-info", border: "border-info/20 dark:border-info/25" },
|
|
7009
|
+
neutral: { dot: "bg-neutral", bg: "bg-neutral-subtle", text: "text-neutral", border: "border-neutral/20 dark:border-neutral/25" }
|
|
7825
7010
|
};
|
|
7826
7011
|
var resolveTone = (color) => {
|
|
7827
7012
|
if (color === void 0) return "neutral";
|
|
@@ -7838,10 +7023,10 @@ var StatusBadge = forwardRef(function StatusBadge2({ status, label: label2, colo
|
|
|
7838
7023
|
ref,
|
|
7839
7024
|
"data-slot": "status-badge",
|
|
7840
7025
|
variant: "outline",
|
|
7841
|
-
className: cn("gap-1.5
|
|
7026
|
+
className: cn("gap-1.5 rounded-md", style.border, style.bg, style.text, className),
|
|
7842
7027
|
"aria-label": displayLabel,
|
|
7843
7028
|
children: [
|
|
7844
|
-
/* @__PURE__ */ jsx("span", { className: cn("inline-block size-
|
|
7029
|
+
/* @__PURE__ */ jsx("span", { className: cn("inline-block size-1.5 rounded-full", style.dot), "aria-hidden": "true" }),
|
|
7845
7030
|
displayLabel
|
|
7846
7031
|
]
|
|
7847
7032
|
}
|
|
@@ -7861,6 +7046,6 @@ var Placeholder = forwardRef(function Placeholder2({ className, ...props }, ref)
|
|
|
7861
7046
|
});
|
|
7862
7047
|
Placeholder.displayName = "Placeholder";
|
|
7863
7048
|
|
|
7864
|
-
export { AppShell, AreaChart,
|
|
7865
|
-
//# sourceMappingURL=chunk-
|
|
7866
|
-
//# sourceMappingURL=chunk-
|
|
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
|