@squadbase/vantage 0.6.2-dev1.54bde93 → 0.6.2-dev1.56da87f
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/{build-A23M4GCH.js → build-U7GO26HR.js} +3 -3
- package/dist/{build-A23M4GCH.js.map → build-U7GO26HR.js.map} +1 -1
- package/dist/{check-FBHT6W6J.js → check-MRVAIHG5.js} +3 -3
- package/dist/{check-FBHT6W6J.js.map → check-MRVAIHG5.js.map} +1 -1
- package/dist/{chunk-57GHR5LN.js → chunk-3RJEOP3J.js} +29 -18
- package/dist/chunk-3RJEOP3J.js.map +1 -0
- package/dist/{chunk-QOXXOFGL.js → chunk-77CISBMG.js} +994 -464
- package/dist/chunk-77CISBMG.js.map +1 -0
- package/dist/{chunk-JXFCSF3K.js → chunk-EG4PX726.js} +12 -7
- package/dist/chunk-EG4PX726.js.map +1 -0
- package/dist/{chunk-2N72FKLB.js → chunk-NZ5QIIG4.js} +33 -11
- package/dist/chunk-NZ5QIIG4.js.map +1 -0
- package/dist/{chunk-5C2SEDPH.js → chunk-PJ4SPXHS.js} +4 -4
- package/dist/{chunk-5C2SEDPH.js.map → chunk-PJ4SPXHS.js.map} +1 -1
- package/dist/{chunk-7S52M2SL.js → chunk-QNOX7WLZ.js} +3 -3
- package/dist/{chunk-7S52M2SL.js.map → chunk-QNOX7WLZ.js.map} +1 -1
- package/dist/{chunk-PDOBHMUQ.js → chunk-ROHNXP7J.js} +72 -3
- package/dist/chunk-ROHNXP7J.js.map +1 -0
- package/dist/{chunk-6OTTGAPO.js → chunk-TRMHNMMZ.js} +24 -7
- package/dist/chunk-TRMHNMMZ.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/components/index.d.ts +49 -29
- package/dist/components/index.js +5 -5
- package/dist/{delta-text-CvwBGJ95.d.ts → delta-text-CbrOaW83.d.ts} +4 -2
- package/dist/{dev-H4I2JL63.js → dev-O42JFQ64.js} +3 -3
- package/dist/{dev-H4I2JL63.js.map → dev-O42JFQ64.js.map} +1 -1
- package/dist/doc/index.d.ts +14 -14
- package/dist/doc/index.js +198 -84
- package/dist/doc/index.js.map +1 -1
- package/dist/{doctor-B2O3GJDU.js → doctor-YD3XAAOT.js} +3 -3
- package/dist/{doctor-B2O3GJDU.js.map → doctor-YD3XAAOT.js.map} +1 -1
- package/dist/{format-U0cQl069.d.ts → format-DihQkL1N.d.ts} +17 -11
- package/dist/slide/index.d.ts +2 -2
- package/dist/slide/index.js +95 -44
- package/dist/slide/index.js.map +1 -1
- package/dist/table/index.js +6 -6
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +5 -5
- package/docs/en/agent-skills.md +1 -1
- package/docs/ja/agent-skills.md +1 -1
- package/package.json +2 -2
- package/registry/ui/app-shell.tsx +138 -1
- package/registry/ui/area-chart.tsx +344 -85
- package/registry/ui/attention-list.tsx +177 -15
- package/registry/ui/bar-chart.tsx +341 -85
- package/registry/ui/bar-list.tsx +332 -77
- package/registry/ui/box-plot-chart.tsx +405 -97
- package/registry/ui/category-bar.tsx +248 -40
- package/registry/ui/chart-frame.tsx +257 -46
- package/registry/ui/data-table.tsx +229 -37
- package/registry/ui/date-range-picker.tsx +190 -36
- package/registry/ui/delta.tsx +171 -12
- package/registry/ui/donut-chart.tsx +339 -84
- package/registry/ui/echart.tsx +142 -4
- package/registry/ui/filter-bar.tsx +179 -20
- package/registry/ui/funnel-steps.tsx +354 -80
- package/registry/ui/heatmap.tsx +293 -52
- package/registry/ui/histogram-chart.tsx +395 -97
- package/registry/ui/kpi-card.tsx +245 -44
- package/registry/ui/legend.tsx +330 -76
- package/registry/ui/line-chart.tsx +344 -85
- package/registry/ui/multi-select.tsx +159 -9
- package/registry/ui/page-shell.tsx +141 -3
- package/registry/ui/paired-chart.tsx +349 -90
- package/registry/ui/progress-circle.tsx +205 -39
- package/registry/ui/sample-data.tsx +153 -9
- package/registry/ui/scatter-chart.tsx +391 -100
- package/registry/ui/searchable-select.tsx +145 -7
- package/registry/ui/states.tsx +170 -13
- package/registry/ui/status-badge.tsx +193 -28
- package/registry/ui/tracker.tsx +205 -39
- package/registry/ui/trend-indicator.tsx +149 -6
- package/registry/ui/updated-at.tsx +170 -16
- package/registry/ui/waterfall-chart.tsx +415 -102
- package/skills/vantage-add-feature/SKILL.md +5 -0
- package/skills/vantage-design/SKILL.md +25 -27
- package/skills/vantage-design/references/extract.md +10 -13
- package/skills/vantage-design/references/format.md +12 -173
- package/skills/vantage-design/references/presets.md +0 -10
- package/templates/AGENTS.md +29 -15
- package/templates/agents/api.md +7 -0
- package/templates/agents/page.md +37 -1
- package/templates/agents/slide.md +7 -1
- package/dist/chunk-2N72FKLB.js.map +0 -1
- package/dist/chunk-57GHR5LN.js.map +0 -1
- package/dist/chunk-6OTTGAPO.js.map +0 -1
- package/dist/chunk-JXFCSF3K.js.map +0 -1
- package/dist/chunk-PDOBHMUQ.js.map +0 -1
- package/dist/chunk-QOXXOFGL.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ChartFrameContext, useChartSurface, resolveChartColors, CHART_OTHER_COLOR, EChart, resolveFillColors } from './chunk-
|
|
1
|
+
import { ChartFrameContext, useChartSurface, resolveChartColors, CHART_OTHER_COLOR, EChart, resolveFillColors } from './chunk-EG4PX726.js';
|
|
2
2
|
import { Sparkline } from './chunk-2IAPIOPS.js';
|
|
3
|
-
import { formatDateRange, EMPTY_VALUE,
|
|
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-
|
|
5
|
-
import { Button } from './chunk-
|
|
3
|
+
import { formatDateRange, EMPTY_VALUE, formatDate, toValueFormatter, formatValue, formatPoints, formatKind, formatDelta, MINUS_SIGN, formatDatesInText, DEFAULT_LOCALE } from './chunk-3RJEOP3J.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-QNOX7WLZ.js';
|
|
5
|
+
import { useLocale, uiLanguage, Button, weekStartsOn, resolveLocale, defaultFiscalYearStartMonth, FALLBACK_LOCALE } from './chunk-ROHNXP7J.js';
|
|
6
6
|
import { cn } from './chunk-U736PVHY.js';
|
|
7
7
|
import { forwardRef, useState, useEffect, createContext, useId, useMemo, useRef, useCallback, Fragment as Fragment$1, useContext } from 'react';
|
|
8
8
|
import { cva } from 'class-variance-authority';
|
|
@@ -13,7 +13,7 @@ import { GraphicComponent, VisualMapComponent } from 'echarts/components';
|
|
|
13
13
|
import { ScatterChart as ScatterChart$1, HeatmapChart } from 'echarts/charts';
|
|
14
14
|
import 'echarts';
|
|
15
15
|
import { flexRender, useReactTable, getPaginationRowModel, getFilteredRowModel, getSortedRowModel, getCoreRowModel } from '@tanstack/react-table';
|
|
16
|
-
import { subMonths, subDays, endOfDay, startOfDay, startOfWeek, subWeeks, endOfWeek, startOfMonth, endOfMonth, isSameDay,
|
|
16
|
+
import { subMonths, subDays, endOfDay, startOfDay, startOfWeek, subWeeks, endOfWeek, startOfMonth, endOfMonth, isSameDay, addMonths } from 'date-fns';
|
|
17
17
|
import { ja } from 'date-fns/locale';
|
|
18
18
|
|
|
19
19
|
// @squadbase/vantage — generated build. Do not edit.
|
|
@@ -41,36 +41,50 @@ function formatRelativeTime(date, options) {
|
|
|
41
41
|
const now = nowValue instanceof Date ? nowValue.getTime() : nowValue;
|
|
42
42
|
if (!Number.isFinite(time) || !Number.isFinite(now)) return EMPTY_VALUE;
|
|
43
43
|
const diff = time - now;
|
|
44
|
-
const rtf = new Intl.RelativeTimeFormat(options?.locale
|
|
44
|
+
const rtf = new Intl.RelativeTimeFormat(resolveLocale(options?.locale), { numeric: "always" });
|
|
45
45
|
for (const [unit, size] of UNITS) {
|
|
46
46
|
if (Math.abs(diff) >= size) return rtf.format(Math.trunc(diff / size), unit);
|
|
47
47
|
}
|
|
48
48
|
return rtf.format(Math.trunc(diff / SECOND), "second");
|
|
49
49
|
}
|
|
50
50
|
var REFRESH_MS = 6e4;
|
|
51
|
+
var TEXT = {
|
|
52
|
+
ja: {
|
|
53
|
+
justNow: "\u305F\u3063\u305F\u4ECA",
|
|
54
|
+
relative: (relative2) => `${relative2}\u306B\u66F4\u65B0`,
|
|
55
|
+
absoluteFirst: (shown, relative2) => `${shown} \u66F4\u65B0\uFF08${relative2}\uFF09`
|
|
56
|
+
},
|
|
57
|
+
en: {
|
|
58
|
+
justNow: "just now",
|
|
59
|
+
relative: (relative2) => `Updated ${relative2}`,
|
|
60
|
+
absoluteFirst: (shown, relative2) => `Updated ${shown} (${relative2})`
|
|
61
|
+
}
|
|
62
|
+
};
|
|
51
63
|
var toMs = (value) => value instanceof Date ? value.getTime() : new Date(value).getTime();
|
|
52
|
-
function relative(at, now) {
|
|
53
|
-
if (now - at < REFRESH_MS && now - at > -REFRESH_MS) return
|
|
54
|
-
return formatRelativeTime(at, { now });
|
|
64
|
+
function relative(at, now, locale) {
|
|
65
|
+
if (now - at < REFRESH_MS && now - at > -REFRESH_MS) return TEXT[uiLanguage(locale)].justNow;
|
|
66
|
+
return formatRelativeTime(at, { now, locale });
|
|
55
67
|
}
|
|
56
|
-
function absolute(at, timeZone) {
|
|
68
|
+
function absolute(at, locale, timeZone) {
|
|
57
69
|
if (!Number.isFinite(at)) return void 0;
|
|
58
|
-
const zone = new Intl.DateTimeFormat(
|
|
59
|
-
const text = formatDate(at, "datetime",
|
|
70
|
+
const zone = new Intl.DateTimeFormat(locale, { timeZone, timeZoneName: "short" }).formatToParts(at).find((part) => part.type === "timeZoneName")?.value;
|
|
71
|
+
const text = formatDate(at, "datetime", locale, { timeZone });
|
|
60
72
|
return zone ? `${text} ${zone}` : text;
|
|
61
73
|
}
|
|
62
|
-
function label(at, now, variant, timeZone) {
|
|
74
|
+
function label(at, now, variant, locale, timeZone) {
|
|
63
75
|
if (!Number.isFinite(at) || !Number.isFinite(now)) return EMPTY_VALUE;
|
|
76
|
+
const t = TEXT[uiLanguage(locale)];
|
|
64
77
|
if (variant === "relative") {
|
|
65
|
-
return now - at < REFRESH_MS && now - at > -REFRESH_MS ? "
|
|
78
|
+
return now - at < REFRESH_MS && now - at > -REFRESH_MS ? uiLanguage(locale) === "ja" ? t.justNow : t.relative(t.justNow) : t.relative(relative(at, now, locale));
|
|
66
79
|
}
|
|
67
|
-
const today = formatDate(at, "date",
|
|
68
|
-
const when = formatDate(at, "datetime",
|
|
80
|
+
const today = formatDate(at, "date", locale, { timeZone }) === formatDate(now, "date", locale, { timeZone });
|
|
81
|
+
const when = formatDate(at, "datetime", locale, { timeZone });
|
|
69
82
|
const shown = today ? when.slice(-5) : when;
|
|
70
|
-
return
|
|
83
|
+
return t.absoluteFirst(shown, relative(at, now, locale));
|
|
71
84
|
}
|
|
72
85
|
var UpdatedAt = forwardRef(
|
|
73
86
|
({ at, variant = "relative", timeZone, prefix, now, className }, ref) => {
|
|
87
|
+
const locale = useLocale();
|
|
74
88
|
const atMs = toMs(at);
|
|
75
89
|
const [current, setCurrent] = useState(null);
|
|
76
90
|
const fixed = now === void 0 ? void 0 : toMs(now);
|
|
@@ -83,9 +97,9 @@ var UpdatedAt = forwardRef(
|
|
|
83
97
|
const clock = fixed ?? current;
|
|
84
98
|
const ready = clock !== null;
|
|
85
99
|
const dateTime = Number.isFinite(atMs) ? new Date(atMs).toISOString() : void 0;
|
|
86
|
-
const full = ready ? absolute(atMs, timeZone) : void 0;
|
|
100
|
+
const full = ready ? absolute(atMs, locale, timeZone) : void 0;
|
|
87
101
|
const classes = cn("text-sm text-muted-foreground tabular-nums", className);
|
|
88
|
-
const text = ready ? `${prefix ?? ""}${label(atMs, clock, variant, timeZone)}` : null;
|
|
102
|
+
const text = ready ? `${prefix ?? ""}${label(atMs, clock, variant, locale, timeZone)}` : null;
|
|
89
103
|
if (!full) {
|
|
90
104
|
return /* @__PURE__ */ jsx("time", { ref, "data-slot": "updated-at", dateTime, className: classes, suppressHydrationWarning: true, children: text });
|
|
91
105
|
}
|
|
@@ -116,9 +130,11 @@ var PageShell = forwardRef(
|
|
|
116
130
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "page-shell", className: cn("flex flex-col", className), ...props })
|
|
117
131
|
);
|
|
118
132
|
PageShell.displayName = "PageShell";
|
|
133
|
+
var SOURCE_PREFIX = { ja: "\u51FA\u5178\uFF1A", en: "Source: " };
|
|
119
134
|
var PageShellHeader = forwardRef(
|
|
120
135
|
({ className, updatedAt, updatedAtVariant, timeZone, source, period, status, children, ...props }, ref) => {
|
|
121
|
-
const
|
|
136
|
+
const locale = useLocale();
|
|
137
|
+
const periodText = period ? formatDateRange(period.start, period.end, { timeZone, locale }) : void 0;
|
|
122
138
|
const hasChips = Boolean(source) || periodText !== void 0 && periodText !== EMPTY_VALUE;
|
|
123
139
|
const hasStatus = status !== void 0 && status !== null && status !== false && status !== "";
|
|
124
140
|
return /* @__PURE__ */ jsxs(
|
|
@@ -133,7 +149,7 @@ var PageShellHeader = forwardRef(
|
|
|
133
149
|
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,
|
|
134
150
|
hasChips ? /* @__PURE__ */ jsxs("div", { "data-slot": "page-shell-chips", className: "order-1 flex basis-full flex-wrap gap-1.5", children: [
|
|
135
151
|
source ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "h-auto max-w-full whitespace-normal text-muted-foreground", children: [
|
|
136
|
-
|
|
152
|
+
SOURCE_PREFIX[uiLanguage(locale)],
|
|
137
153
|
source
|
|
138
154
|
] }) : null,
|
|
139
155
|
periodText && periodText !== EMPTY_VALUE ? /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "tabular-nums text-muted-foreground", children: periodText }) : null
|
|
@@ -301,6 +317,7 @@ var PageShellContent = forwardRef(
|
|
|
301
317
|
)
|
|
302
318
|
);
|
|
303
319
|
PageShellContent.displayName = "PageShellContent";
|
|
320
|
+
var PAGE_PLACEHOLDER = { ja: "\u30DA\u30FC\u30B8\u3092\u9078\u629E", en: "Select a page" };
|
|
304
321
|
function flattenItems(item) {
|
|
305
322
|
if (item.children && item.children.length > 0) {
|
|
306
323
|
return item.children.flatMap(flattenItems);
|
|
@@ -314,6 +331,7 @@ function NavSelect({
|
|
|
314
331
|
const allItems = groups.flatMap((g) => g.items.flatMap(flattenItems));
|
|
315
332
|
const currentValue = allItems.find((item) => item.isActive)?.href ?? "";
|
|
316
333
|
const selectItems = allItems.map((item) => ({ value: item.href, label: item.label }));
|
|
334
|
+
const placeholder = PAGE_PLACEHOLDER[uiLanguage(useLocale())];
|
|
317
335
|
return /* @__PURE__ */ jsxs(
|
|
318
336
|
Select,
|
|
319
337
|
{
|
|
@@ -323,7 +341,7 @@ function NavSelect({
|
|
|
323
341
|
if (href !== null) onNavigate(href);
|
|
324
342
|
},
|
|
325
343
|
children: [
|
|
326
|
-
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-48", children: /* @__PURE__ */ jsx(SelectValue, { placeholder
|
|
344
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-48", children: /* @__PURE__ */ jsx(SelectValue, { placeholder }) }),
|
|
327
345
|
/* @__PURE__ */ jsx(
|
|
328
346
|
SelectContent,
|
|
329
347
|
{
|
|
@@ -496,8 +514,11 @@ var SectionHeader = forwardRef(
|
|
|
496
514
|
)
|
|
497
515
|
);
|
|
498
516
|
SectionHeader.displayName = "SectionHeader";
|
|
499
|
-
var
|
|
500
|
-
|
|
517
|
+
var TEXT2 = {
|
|
518
|
+
ja: { label: "\u898B\u672C\u306E\u5024", title: "\u5B9F\u30C7\u30FC\u30BF\u306B\u307E\u3060\u3064\u306A\u304C\u3063\u3066\u3044\u306A\u3044\u898B\u672C\u306E\u5024\u3067\u3059" },
|
|
519
|
+
en: { label: "Sample data", title: "Sample values, not connected to real data yet" }
|
|
520
|
+
};
|
|
521
|
+
var DEFAULT_SAMPLE_LABEL = TEXT2.en.label;
|
|
501
522
|
var SampleContext = createContext(null);
|
|
502
523
|
function useSampleMark() {
|
|
503
524
|
return useContext(SampleContext);
|
|
@@ -505,20 +526,22 @@ function useSampleMark() {
|
|
|
505
526
|
function SampleClaim({ children }) {
|
|
506
527
|
return /* @__PURE__ */ jsx(SampleContext.Provider, { value: null, children });
|
|
507
528
|
}
|
|
508
|
-
function SampleBadge({ label: label2
|
|
529
|
+
function SampleBadge({ label: label2, className, ...props }) {
|
|
530
|
+
const t = TEXT2[uiLanguage(useLocale())];
|
|
509
531
|
return /* @__PURE__ */ jsx(
|
|
510
532
|
Badge,
|
|
511
533
|
{
|
|
512
534
|
"data-slot": "sample-badge",
|
|
513
|
-
title:
|
|
535
|
+
title: t.title,
|
|
514
536
|
className: cn("border-warning/20 dark:border-warning/25 bg-warning-subtle text-warning align-middle", className),
|
|
515
537
|
...props,
|
|
516
|
-
children: label2
|
|
538
|
+
children: label2 ?? t.label
|
|
517
539
|
}
|
|
518
540
|
);
|
|
519
541
|
}
|
|
520
|
-
function SampleData({ label: label2
|
|
521
|
-
const
|
|
542
|
+
function SampleData({ label: label2, children }) {
|
|
543
|
+
const shown = label2 ?? TEXT2[uiLanguage(useLocale())].label;
|
|
544
|
+
const state = useMemo(() => ({ label: shown }), [shown]);
|
|
522
545
|
return /* @__PURE__ */ jsx("div", { "data-slot": "sample-data", style: { display: "contents" }, children: /* @__PURE__ */ jsx(SampleContext.Provider, { value: state, children }) });
|
|
523
546
|
}
|
|
524
547
|
var SUBGRID_CLASS = {
|
|
@@ -652,7 +675,10 @@ function DashboardCardPreset({
|
|
|
652
675
|
] }) });
|
|
653
676
|
}
|
|
654
677
|
var DEFAULT_CHART_HEIGHT = 288;
|
|
655
|
-
var
|
|
678
|
+
var TEXT3 = {
|
|
679
|
+
ja: { emptyTitle: "\u8868\u793A\u3067\u304D\u308B\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093", loading: "\u8AAD\u307F\u8FBC\u307F\u4E2D" },
|
|
680
|
+
en: { emptyTitle: "No data to display", loading: "Loading" }
|
|
681
|
+
};
|
|
656
682
|
var ChartFrame = forwardRef(function ChartFrame2({
|
|
657
683
|
title,
|
|
658
684
|
summary,
|
|
@@ -669,6 +695,7 @@ var ChartFrame = forwardRef(function ChartFrame2({
|
|
|
669
695
|
...props
|
|
670
696
|
}, ref) {
|
|
671
697
|
const id = useId();
|
|
698
|
+
const t = TEXT3[uiLanguage(useLocale())];
|
|
672
699
|
const titleId = title ? `${id}-title` : void 0;
|
|
673
700
|
const summaryId = summary ? `${id}-summary` : void 0;
|
|
674
701
|
const state = isLoading ? "loading" : isEmpty ? "empty" : "ready";
|
|
@@ -690,7 +717,7 @@ var ChartFrame = forwardRef(function ChartFrame2({
|
|
|
690
717
|
"aria-busy": isLoading || void 0,
|
|
691
718
|
className: "relative w-full min-w-0",
|
|
692
719
|
style: { height: typeof height === "number" ? `${height}px` : height },
|
|
693
|
-
children: state === "loading" ? /* @__PURE__ */ jsx(ChartSkeleton, { variant }) : state === "empty" ? /* @__PURE__ */ jsx(ChartEmpty, { ...emptyState }) : /* @__PURE__ */ jsx(ChartFrameContext.Provider, { value: true, children })
|
|
720
|
+
children: state === "loading" ? /* @__PURE__ */ jsx(ChartSkeleton, { variant, loadingText: t.loading }) : state === "empty" ? /* @__PURE__ */ jsx(ChartEmpty, { ...emptyState, defaultTitle: t.emptyTitle }) : /* @__PURE__ */ jsx(ChartFrameContext.Provider, { value: true, children })
|
|
694
721
|
}
|
|
695
722
|
),
|
|
696
723
|
state === "ready" && dataTable && dataTable.rows.length > 0 && /* @__PURE__ */ jsx(ChartDataTableView, { table: dataTable, fallbackCaption: title ?? ariaLabel })
|
|
@@ -700,14 +727,14 @@ ChartFrame.displayName = "ChartFrame";
|
|
|
700
727
|
var BAR_HEIGHTS = [58, 74, 46, 88, 64, 80, 52];
|
|
701
728
|
var LIST_WIDTHS = [92, 76, 64, 48, 36];
|
|
702
729
|
var LINE_POINTS = "0,70 16,58 33,62 50,40 66,46 83,28 100,34";
|
|
703
|
-
function ChartSkeleton({ variant }) {
|
|
730
|
+
function ChartSkeleton({ variant, loadingText }) {
|
|
704
731
|
const pulse = "animate-pulse motion-reduce:animate-none";
|
|
705
732
|
return /* @__PURE__ */ jsxs("div", { "data-slot": "chart-skeleton", "data-variant": variant, className: "absolute inset-0 flex flex-col gap-3", children: [
|
|
706
733
|
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "contents", children: variant === "list" ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-1 flex-col justify-around", pulse), children: LIST_WIDTHS.map((w) => /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsx("div", { className: "h-5 rounded-sm bg-muted", style: { width: `${w}%` } }) }, w)) }) : variant === "donut" ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-1 items-center justify-center", pulse), children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 100 100", className: "h-full max-h-full w-auto text-muted", children: /* @__PURE__ */ jsx("circle", { cx: "50", cy: "50", r: "40", fill: "none", stroke: "currentColor", strokeWidth: "14" }) }) }) : variant === "bar" ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-1 items-end gap-3 px-1", pulse), children: BAR_HEIGHTS.map((h, i) => /* @__PURE__ */ jsx("div", { className: "flex-1 rounded-t-sm bg-muted", style: { height: `${h}%` } }, i)) }) : (
|
|
707
734
|
// A soft muted silhouette only — no stroke, no baseline, nothing that reads as a data line.
|
|
708
735
|
/* @__PURE__ */ jsx("div", { className: cn("relative flex-1", pulse), children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 100 100", preserveAspectRatio: "none", className: "absolute inset-0 h-full w-full text-muted", children: /* @__PURE__ */ jsx("polygon", { points: `${LINE_POINTS} 100,100 0,100`, fill: "currentColor", opacity: variant === "area" ? 0.8 : 0.5 }) }) })
|
|
709
736
|
) }),
|
|
710
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children:
|
|
737
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: loadingText })
|
|
711
738
|
] });
|
|
712
739
|
}
|
|
713
740
|
function ChartDataTableView({ table, fallbackCaption }) {
|
|
@@ -720,14 +747,14 @@ function ChartDataTableView({ table, fallbackCaption }) {
|
|
|
720
747
|
) }, r)) })
|
|
721
748
|
] }) });
|
|
722
749
|
}
|
|
723
|
-
function ChartEmpty({ title, description, action }) {
|
|
750
|
+
function ChartEmpty({ title, description, action, defaultTitle }) {
|
|
724
751
|
return /* @__PURE__ */ jsxs(
|
|
725
752
|
"div",
|
|
726
753
|
{
|
|
727
754
|
"data-slot": "chart-empty",
|
|
728
755
|
className: "absolute inset-0 flex flex-col items-center justify-center gap-1 rounded-md border border-dashed border-border p-6 text-center",
|
|
729
756
|
children: [
|
|
730
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-balance", children: title ??
|
|
757
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-balance", children: title ?? defaultTitle }),
|
|
731
758
|
description && /* @__PURE__ */ jsx("p", { className: "max-w-prose text-sm text-balance text-muted-foreground", children: description }),
|
|
732
759
|
action && /* @__PURE__ */ jsx("div", { className: "mt-3", children: action })
|
|
733
760
|
]
|
|
@@ -776,37 +803,63 @@ function chartColorAt(colors, i) {
|
|
|
776
803
|
function tintCss(cssColor, percent) {
|
|
777
804
|
return `color-mix(in oklab, ${cssColor} ${percent}%, transparent)`;
|
|
778
805
|
}
|
|
779
|
-
function resolveValueFormatter(valueFormatter,
|
|
780
|
-
return valueFormatter ?? toValueFormatter(
|
|
806
|
+
function resolveValueFormatter(valueFormatter, format, locale) {
|
|
807
|
+
return valueFormatter ?? toValueFormatter(format, locale);
|
|
781
808
|
}
|
|
782
|
-
function resolveAxisFormatter(valueFormatter,
|
|
809
|
+
function resolveAxisFormatter(valueFormatter, format, localeArg) {
|
|
783
810
|
if (valueFormatter) return valueFormatter;
|
|
784
|
-
const
|
|
785
|
-
|
|
811
|
+
const locale = resolveLocale(localeArg);
|
|
812
|
+
const spec = format === void 0 ? { type: "compact" } : typeof format === "string" ? { type: format } : format;
|
|
813
|
+
if (spec.type !== "compact" && spec.type !== "number" && spec.type !== "currency") return toValueFormatter(format, locale);
|
|
786
814
|
const currency = "currency" in spec ? spec.currency : void 0;
|
|
787
815
|
const short = spec.type === "currency" ? { type: "currency", currency, notation: "compact" } : { type: "compact" };
|
|
788
816
|
return (value) => formatValue(value, short, locale);
|
|
789
817
|
}
|
|
790
|
-
var
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
];
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
818
|
+
var compactUnitCache = /* @__PURE__ */ new Map();
|
|
819
|
+
function compactUnits(locale) {
|
|
820
|
+
const cached = compactUnitCache.get(locale);
|
|
821
|
+
if (cached !== void 0) return cached;
|
|
822
|
+
let units = [];
|
|
823
|
+
try {
|
|
824
|
+
const compact = new Intl.NumberFormat(locale, { notation: "compact" });
|
|
825
|
+
const seen = /* @__PURE__ */ new Set();
|
|
826
|
+
for (let exp = 3; exp <= 15; exp++) {
|
|
827
|
+
const parts = compact.formatToParts(10 ** exp);
|
|
828
|
+
const at = parts.findIndex((p) => p.type === "compact");
|
|
829
|
+
if (at === -1) continue;
|
|
830
|
+
if (parts[at - 1]?.type !== "integer" || at !== parts.length - 1) {
|
|
831
|
+
units = null;
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
const token = parts[at].value;
|
|
835
|
+
if (seen.has(token)) continue;
|
|
836
|
+
seen.add(token);
|
|
837
|
+
units.push({ token, size: 10 ** exp });
|
|
838
|
+
}
|
|
839
|
+
} catch {
|
|
840
|
+
units = null;
|
|
841
|
+
}
|
|
842
|
+
const sorted = units && units.length > 0 ? units.sort((a, b) => b.size - a.size) : null;
|
|
843
|
+
compactUnitCache.set(locale, sorted);
|
|
844
|
+
return sorted;
|
|
845
|
+
}
|
|
846
|
+
var escapeRegExp = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
847
|
+
function resolveAxisTickFormatter(valueFormatter, format, localeArg) {
|
|
848
|
+
const locale = resolveLocale(localeArg);
|
|
849
|
+
const base = resolveAxisFormatter(valueFormatter, format, locale);
|
|
850
|
+
const spec = format === void 0 ? { type: "compact" } : typeof format === "string" ? { type: format } : format;
|
|
851
|
+
const units = !valueFormatter && (spec.type === "compact" || spec.type === "number" || spec.type === "currency") ? compactUnits(locale) : null;
|
|
852
|
+
if (!units) return () => base;
|
|
801
853
|
const number = new Intl.NumberFormat(locale, { maximumFractionDigits: 3 });
|
|
854
|
+
const numberToken = new RegExp(`\\d[\\d,]*(?:\\.\\d+)?(?:${units.map((u) => escapeRegExp(u.token)).join("|")})?`);
|
|
802
855
|
return (top) => {
|
|
803
|
-
const unit =
|
|
856
|
+
const unit = units.find((u) => Math.abs(top) >= u.size);
|
|
804
857
|
if (!unit) return base;
|
|
805
858
|
return (value) => {
|
|
806
859
|
const text = base(value);
|
|
807
860
|
if (value === 0 || !Number.isFinite(value)) return text;
|
|
808
|
-
const scaled = `${number.format(Math.abs(value) / unit.size)}${unit.
|
|
809
|
-
return text.replace(
|
|
861
|
+
const scaled = `${number.format(Math.abs(value) / unit.size)}${unit.token}`;
|
|
862
|
+
return text.replace(numberToken, () => scaled);
|
|
810
863
|
};
|
|
811
864
|
};
|
|
812
865
|
}
|
|
@@ -823,8 +876,15 @@ function clamp(value, min, max) {
|
|
|
823
876
|
return Math.min(max, Math.max(min, value));
|
|
824
877
|
}
|
|
825
878
|
var MAX_CHART_SERIES = 5;
|
|
826
|
-
var
|
|
827
|
-
function
|
|
879
|
+
var OTHER_SERIES_LABELS = { ja: "\u305D\u306E\u4ED6", en: "Other" };
|
|
880
|
+
function otherSeriesLabel(locale) {
|
|
881
|
+
return OTHER_SERIES_LABELS[uiLanguage(resolveLocale(locale))];
|
|
882
|
+
}
|
|
883
|
+
var OTHER_NAMES = new Set(Object.values(OTHER_SERIES_LABELS));
|
|
884
|
+
function isOtherName(name) {
|
|
885
|
+
return typeof name === "string" && OTHER_NAMES.has(name);
|
|
886
|
+
}
|
|
887
|
+
function aggregateTopN(items, n = MAX_CHART_SERIES, otherLabel = otherSeriesLabel()) {
|
|
828
888
|
if (items.length <= n) return { top: [...items], rest: [], other: null };
|
|
829
889
|
const ranked = items.map((item, i) => ({ item, i })).sort((a, b) => b.item.value - a.item.value || a.i - b.i);
|
|
830
890
|
const keep = new Set(ranked.slice(0, n).map((r) => r.i));
|
|
@@ -832,7 +892,7 @@ function aggregateTopN(items, n = MAX_CHART_SERIES, otherLabel = OTHER_SERIES_LA
|
|
|
832
892
|
const rest = items.filter((_, i) => !keep.has(i));
|
|
833
893
|
return { top, rest, other: { name: otherLabel, value: rest.reduce((sum, item) => sum + item.value, 0) } };
|
|
834
894
|
}
|
|
835
|
-
function aggregateSeries(data, categories, n = MAX_CHART_SERIES, otherLabel =
|
|
895
|
+
function aggregateSeries(data, categories, n = MAX_CHART_SERIES, otherLabel = otherSeriesLabel()) {
|
|
836
896
|
const totals = categories.map((name) => ({
|
|
837
897
|
name,
|
|
838
898
|
value: data.reduce((sum, row) => sum + (toChartNumber(row[name]) ?? 0), 0)
|
|
@@ -853,12 +913,13 @@ function aggregateSeries(data, categories, n = MAX_CHART_SERIES, otherLabel = OT
|
|
|
853
913
|
otherCategory: other.name
|
|
854
914
|
};
|
|
855
915
|
}
|
|
856
|
-
function aggregateSeriesKeeping(data, categories, keep, n = MAX_CHART_SERIES) {
|
|
857
|
-
if (keep === void 0 || !categories.includes(keep)) return aggregateSeries(data, categories, n);
|
|
916
|
+
function aggregateSeriesKeeping(data, categories, keep, n = MAX_CHART_SERIES, otherLabel = otherSeriesLabel()) {
|
|
917
|
+
if (keep === void 0 || !categories.includes(keep)) return aggregateSeries(data, categories, n, otherLabel);
|
|
858
918
|
const aggregated = aggregateSeries(
|
|
859
919
|
data,
|
|
860
920
|
categories.filter((c) => c !== keep),
|
|
861
|
-
n
|
|
921
|
+
n,
|
|
922
|
+
otherLabel
|
|
862
923
|
);
|
|
863
924
|
return { ...aggregated, categories: [...aggregated.categories, keep] };
|
|
864
925
|
}
|
|
@@ -880,7 +941,7 @@ function seriesColorsFor(categories, colors, otherColor, otherCategory = null, a
|
|
|
880
941
|
const list = Array.isArray(colors) ? colors : void 0;
|
|
881
942
|
const record = !Array.isArray(colors) && colors ? colors : void 0;
|
|
882
943
|
return categories.map((category, i) => {
|
|
883
|
-
if (otherCategory !== null && category === otherCategory || category
|
|
944
|
+
if (otherCategory !== null && category === otherCategory || isOtherName(category)) return otherColor;
|
|
884
945
|
const fromRecord = record?.[category];
|
|
885
946
|
if (fromRecord) return fromRecord;
|
|
886
947
|
if (list && list.length > 0) {
|
|
@@ -890,7 +951,7 @@ function seriesColorsFor(categories, colors, otherColor, otherCategory = null, a
|
|
|
890
951
|
return DEFAULT_CHART_COLORS[i % DEFAULT_CHART_COLORS.length];
|
|
891
952
|
});
|
|
892
953
|
}
|
|
893
|
-
function donutSlices(data, { index, value, colors, maxSlices = MAX_CHART_SERIES, otherColor, otherLabel =
|
|
954
|
+
function donutSlices(data, { index, value, colors, maxSlices = MAX_CHART_SERIES, otherColor, otherLabel = otherSeriesLabel() }) {
|
|
894
955
|
const items = data.map((row, i) => {
|
|
895
956
|
const n = toChartNumber(row[value]);
|
|
896
957
|
return { name: String(row[index] ?? ""), value: n !== null && n > 0 ? n : 0, row, i };
|
|
@@ -900,7 +961,8 @@ function donutSlices(data, { index, value, colors, maxSlices = MAX_CHART_SERIES,
|
|
|
900
961
|
const slices = top.map((item, rank) => ({
|
|
901
962
|
name: item.name,
|
|
902
963
|
value: item.value,
|
|
903
|
-
|
|
964
|
+
// A row the data itself names「その他」/ "Other" is the same remainder: grey, like the folded slice.
|
|
965
|
+
color: isOtherName(item.name) ? otherColor : palette[rank % palette.length],
|
|
904
966
|
isOther: false,
|
|
905
967
|
row: item.row
|
|
906
968
|
}));
|
|
@@ -921,7 +983,7 @@ function sortBarListData(data, sortOrder) {
|
|
|
921
983
|
else if (sortOrder === "descending") rows.sort((a, b) => b.value - a.value);
|
|
922
984
|
return rows;
|
|
923
985
|
}
|
|
924
|
-
function barListRows(data, { index = "name", category = "value", sortOrder = "descending", maxItems = MAX_CHART_SERIES, otherLabel =
|
|
986
|
+
function barListRows(data, { index = "name", category = "value", sortOrder = "descending", maxItems = MAX_CHART_SERIES, otherLabel = otherSeriesLabel(), exclude } = {}) {
|
|
925
987
|
const items = data.map((row) => {
|
|
926
988
|
const cells = row;
|
|
927
989
|
const name = String(cells[index] ?? "");
|
|
@@ -955,7 +1017,7 @@ var BAR_LIST_TINT = 45;
|
|
|
955
1017
|
var BAR_LIST_OTHER_TINT = 30;
|
|
956
1018
|
function barListFills(rows, color, otherColor) {
|
|
957
1019
|
return rows.map(
|
|
958
|
-
(row) => row.isOther ? tintCss(otherColor, BAR_LIST_OTHER_TINT) : tintCss(chartColorToCss(row.color ?? color), BAR_LIST_TINT)
|
|
1020
|
+
(row) => row.isOther || isOtherName(row.name) ? tintCss(otherColor, BAR_LIST_OTHER_TINT) : tintCss(chartColorToCss(row.color ?? color), BAR_LIST_TINT)
|
|
959
1021
|
);
|
|
960
1022
|
}
|
|
961
1023
|
function barListShareText(value, total) {
|
|
@@ -1052,6 +1114,22 @@ function progressCircleGeometry(value, max, radius, strokeWidth) {
|
|
|
1052
1114
|
const circumference = 2 * Math.PI * normalizedRadius;
|
|
1053
1115
|
return { size: radius * 2, normalizedRadius, circumference, offset: circumference * (1 - ratio), ratio };
|
|
1054
1116
|
}
|
|
1117
|
+
var SUMMARY_TEXT = {
|
|
1118
|
+
ja: {
|
|
1119
|
+
up: "\u3001\u524D\u306E\u70B9\u3088\u308A\u5897\u52A0",
|
|
1120
|
+
down: "\u3001\u524D\u306E\u70B9\u3088\u308A\u6E1B\u5C11",
|
|
1121
|
+
flat: "\u3001\u524D\u306E\u70B9\u3068\u6A2A\u3070\u3044",
|
|
1122
|
+
latest: (label2, value) => `\u6700\u65B0 ${label2} \u306F ${value}`,
|
|
1123
|
+
top: (name, share) => `\u6700\u5927\u306F ${name}(${share})`
|
|
1124
|
+
},
|
|
1125
|
+
en: {
|
|
1126
|
+
up: ", up from the previous point",
|
|
1127
|
+
down: ", down from the previous point",
|
|
1128
|
+
flat: ", flat from the previous point",
|
|
1129
|
+
latest: (label2, value) => `Latest ${label2}: ${value}`,
|
|
1130
|
+
top: (name, share) => `Largest: ${name} (${share})`
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1055
1133
|
function buildChartSummary(input) {
|
|
1056
1134
|
const key = input.categories[0];
|
|
1057
1135
|
if (key === void 0) return void 0;
|
|
@@ -1063,54 +1141,96 @@ function buildChartSummary(input) {
|
|
|
1063
1141
|
}
|
|
1064
1142
|
const latest = points[points.length - 1];
|
|
1065
1143
|
if (!latest) return void 0;
|
|
1066
|
-
const
|
|
1144
|
+
const locale = resolveLocale(input.locale);
|
|
1145
|
+
const t = SUMMARY_TEXT[uiLanguage(locale)];
|
|
1146
|
+
const text = input.valueFormatter ?? toValueFormatter(input.format ?? "compact", locale);
|
|
1067
1147
|
const prev = points[points.length - 2];
|
|
1068
|
-
const direction = !prev ? "" : latest.value > prev.value ?
|
|
1148
|
+
const direction = !prev ? "" : latest.value > prev.value ? t.up : latest.value < prev.value ? t.down : t.flat;
|
|
1069
1149
|
const head = input.title ? `${input.title}: ` : "";
|
|
1070
|
-
return `${head}
|
|
1150
|
+
return `${head}${t.latest(latest.label, text(latest.value))}${direction}`;
|
|
1071
1151
|
}
|
|
1072
|
-
function buildShareSummary(slices, title) {
|
|
1152
|
+
function buildShareSummary(slices, title, locale) {
|
|
1073
1153
|
const total = slices.reduce((sum, s) => sum + s.value, 0);
|
|
1074
1154
|
const top = slices[0];
|
|
1075
1155
|
if (!top || total <= 0) return void 0;
|
|
1076
1156
|
const share = `${Math.round(top.value / total * 1e3) / 10}%`;
|
|
1077
|
-
return `${title ? `${title}: ` : ""}
|
|
1157
|
+
return `${title ? `${title}: ` : ""}${SUMMARY_TEXT[uiLanguage(resolveLocale(locale))].top(top.name, share)}`;
|
|
1078
1158
|
}
|
|
1079
1159
|
|
|
1080
1160
|
// ../squadkit/registry/lib/comparison.ts
|
|
1081
1161
|
var COMPARISON_LABELS = {
|
|
1082
|
-
"prior-period": "
|
|
1083
|
-
"prior-year": "
|
|
1084
|
-
target: "
|
|
1162
|
+
"prior-period": "vs. prior period",
|
|
1163
|
+
"prior-year": "vs. same period last year",
|
|
1164
|
+
target: "vs. target"
|
|
1085
1165
|
};
|
|
1086
1166
|
var BASELINE_NOUNS = {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1167
|
+
ja: {
|
|
1168
|
+
"prior-period": {
|
|
1169
|
+
day: "\u524D\u65E5",
|
|
1170
|
+
week: "\u524D\u9031",
|
|
1171
|
+
month: "\u524D\u6708",
|
|
1172
|
+
quarter: "\u524D\u56DB\u534A\u671F",
|
|
1173
|
+
year: "\u524D\u5E74",
|
|
1174
|
+
unknown: "\u524D\u671F"
|
|
1175
|
+
},
|
|
1176
|
+
"prior-year": {
|
|
1177
|
+
day: "\u524D\u5E74\u540C\u65E5",
|
|
1178
|
+
week: "\u524D\u5E74\u540C\u9031",
|
|
1179
|
+
month: "\u524D\u5E74\u540C\u6708",
|
|
1180
|
+
quarter: "\u524D\u5E74\u540C\u671F",
|
|
1181
|
+
year: "\u524D\u5E74",
|
|
1182
|
+
unknown: "\u524D\u5E74\u540C\u671F"
|
|
1183
|
+
},
|
|
1184
|
+
target: "\u76EE\u6A19",
|
|
1185
|
+
custom: "\u6BD4\u8F03\u5BFE\u8C61"
|
|
1094
1186
|
},
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1187
|
+
en: {
|
|
1188
|
+
"prior-period": {
|
|
1189
|
+
day: "prior day",
|
|
1190
|
+
week: "prior week",
|
|
1191
|
+
month: "prior month",
|
|
1192
|
+
quarter: "prior quarter",
|
|
1193
|
+
year: "prior year",
|
|
1194
|
+
unknown: "prior period"
|
|
1195
|
+
},
|
|
1196
|
+
"prior-year": {
|
|
1197
|
+
day: "same day last year",
|
|
1198
|
+
week: "same week last year",
|
|
1199
|
+
month: "same month last year",
|
|
1200
|
+
quarter: "same quarter last year",
|
|
1201
|
+
year: "prior year",
|
|
1202
|
+
unknown: "same period last year"
|
|
1203
|
+
},
|
|
1204
|
+
target: "target",
|
|
1205
|
+
custom: "baseline"
|
|
1102
1206
|
}
|
|
1103
1207
|
};
|
|
1104
|
-
|
|
1208
|
+
var LABEL_OF = {
|
|
1209
|
+
ja: (baseline) => `${baseline}\u6BD4`,
|
|
1210
|
+
en: (baseline) => `vs. ${baseline}`
|
|
1211
|
+
};
|
|
1212
|
+
function baselineOfLabel(named, language) {
|
|
1213
|
+
if (named.length > 1 && named.endsWith("\u6BD4")) return named.slice(0, -1);
|
|
1214
|
+
if (language === "en") {
|
|
1215
|
+
const stripped = named.replace(/^vs\.?\s+/i, "");
|
|
1216
|
+
if (stripped) return stripped;
|
|
1217
|
+
}
|
|
1218
|
+
return named;
|
|
1219
|
+
}
|
|
1220
|
+
function comparisonBaseline(vs, grain, label2, toDate2, locale) {
|
|
1221
|
+
const language = uiLanguage(resolveLocale(locale));
|
|
1222
|
+
const nouns = BASELINE_NOUNS[language];
|
|
1105
1223
|
const named = label2?.trim();
|
|
1106
|
-
if (named) return
|
|
1107
|
-
if (vs === "custom") return
|
|
1108
|
-
if (vs === "target") return
|
|
1109
|
-
if (vs === "prior-year" && toDate2) return
|
|
1110
|
-
return
|
|
1224
|
+
if (named) return baselineOfLabel(named, language);
|
|
1225
|
+
if (vs === "custom") return nouns.custom;
|
|
1226
|
+
if (vs === "target") return nouns.target;
|
|
1227
|
+
if (vs === "prior-year" && toDate2) return nouns["prior-year"].unknown;
|
|
1228
|
+
return nouns[vs][grain ?? "unknown"];
|
|
1111
1229
|
}
|
|
1112
|
-
function comparisonLabel(vs, grain, label2, toDate2) {
|
|
1113
|
-
|
|
1230
|
+
function comparisonLabel(vs, grain, label2, toDate2, locale) {
|
|
1231
|
+
if (label2?.trim()) return label2;
|
|
1232
|
+
const resolved = resolveLocale(locale);
|
|
1233
|
+
return LABEL_OF[uiLanguage(resolved)](comparisonBaseline(vs, grain, void 0, toDate2, resolved));
|
|
1114
1234
|
}
|
|
1115
1235
|
var toNumber = (v) => v === null || v === void 0 || Number.isNaN(v) ? null : v;
|
|
1116
1236
|
function computeComparison(current, comparison, options) {
|
|
@@ -1118,7 +1238,7 @@ function computeComparison(current, comparison, options) {
|
|
|
1118
1238
|
const neutralBand = options?.neutralBand ?? 0.01;
|
|
1119
1239
|
const cur = toNumber(current);
|
|
1120
1240
|
const prev = toNumber(comparison.previous);
|
|
1121
|
-
const label2 = comparisonLabel(comparison.vs, comparison.grain, comparison.label, comparison.toDate);
|
|
1241
|
+
const label2 = comparisonLabel(comparison.vs, comparison.grain, comparison.label, comparison.toDate, options?.locale);
|
|
1122
1242
|
const difference = cur !== null && prev !== null ? cur - prev : null;
|
|
1123
1243
|
const ratio = difference !== null && prev !== null && prev !== 0 ? difference / Math.abs(prev) : null;
|
|
1124
1244
|
let direction;
|
|
@@ -1131,20 +1251,20 @@ function computeComparison(current, comparison, options) {
|
|
|
1131
1251
|
else if (direction === "down") sentiment = polarity === "higher-is-better" ? "negative" : "positive";
|
|
1132
1252
|
return { current: cur, previous: prev, difference, ratio, direction, sentiment, label: label2, vs: comparison.vs };
|
|
1133
1253
|
}
|
|
1134
|
-
function defaultChangeDisplay(
|
|
1135
|
-
return formatKind(
|
|
1254
|
+
function defaultChangeDisplay(format) {
|
|
1255
|
+
return formatKind(format) === "percent" ? "points" : "relative";
|
|
1136
1256
|
}
|
|
1137
|
-
function formatChange(result, display = "relative", locale
|
|
1257
|
+
function formatChange(result, display = "relative", locale, format, digits) {
|
|
1138
1258
|
if (result.direction === "none") return null;
|
|
1139
|
-
if (display === "difference") return result.difference === null ? null : formatDelta(result.difference,
|
|
1259
|
+
if (display === "difference") return result.difference === null ? null : formatDelta(result.difference, format, locale);
|
|
1140
1260
|
if (display === "points")
|
|
1141
1261
|
return result.difference === null ? null : formatPoints(result.difference, locale, digits === void 0 ? void 0 : { digits });
|
|
1142
1262
|
return result.ratio === null ? null : formatDelta(result.ratio, digits === void 0 ? "percent" : { type: "percent", digits }, locale);
|
|
1143
1263
|
}
|
|
1144
|
-
function formatChangeAmount(result, display = "relative", locale
|
|
1264
|
+
function formatChangeAmount(result, display = "relative", locale, format, digits) {
|
|
1145
1265
|
if (result.direction === "none") return null;
|
|
1146
1266
|
if (display === "difference")
|
|
1147
|
-
return result.difference === null ? null : formatValue(Math.abs(result.difference),
|
|
1267
|
+
return result.difference === null ? null : formatValue(Math.abs(result.difference), format, locale);
|
|
1148
1268
|
if (display === "points")
|
|
1149
1269
|
return result.difference === null ? null : formatPoints(result.difference, locale, { signDisplay: "never", ...digits === void 0 ? {} : { digits } });
|
|
1150
1270
|
return result.ratio === null ? null : formatValue(Math.abs(result.ratio), digits === void 0 ? "percent" : { type: "percent", digits }, locale);
|
|
@@ -1163,6 +1283,29 @@ function toneForValue(value, thresholds) {
|
|
|
1163
1283
|
}
|
|
1164
1284
|
|
|
1165
1285
|
// ../squadkit/registry/lib/chart-options.ts
|
|
1286
|
+
var CHART_TEXT = {
|
|
1287
|
+
ja: {
|
|
1288
|
+
target: "\u76EE\u6A19",
|
|
1289
|
+
forecast: "\u4E88\u6E2C",
|
|
1290
|
+
total: "\u5408\u8A08",
|
|
1291
|
+
provisional: "\u901F\u5831",
|
|
1292
|
+
noComparison: "\u6BD4\u8F03\u306A\u3057",
|
|
1293
|
+
share: (share) => `\uFF08${share}\uFF09`,
|
|
1294
|
+
targetRate: (rate) => `\uFF08\u9054\u6210\u7387 ${rate}\uFF09`,
|
|
1295
|
+
provisionalTitle: (title, label2) => `${title}(${label2})`
|
|
1296
|
+
},
|
|
1297
|
+
en: {
|
|
1298
|
+
target: "Target",
|
|
1299
|
+
forecast: "Forecast",
|
|
1300
|
+
total: "Total",
|
|
1301
|
+
provisional: "Preliminary",
|
|
1302
|
+
noComparison: "No comparison",
|
|
1303
|
+
share: (share) => ` (${share})`,
|
|
1304
|
+
targetRate: (rate) => ` (${rate} achieved)`,
|
|
1305
|
+
provisionalTitle: (title, label2) => `${title} (${label2})`
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
var chartText = (locale) => CHART_TEXT[uiLanguage(resolveLocale(locale))];
|
|
1166
1309
|
function chartMotion(reducedMotion) {
|
|
1167
1310
|
if (reducedMotion) return { animation: false };
|
|
1168
1311
|
return { animation: true, animationDuration: 0, animationDurationUpdate: 300, animationEasingUpdate: "cubicOut" };
|
|
@@ -1227,12 +1370,12 @@ function parseTimeIndex(values) {
|
|
|
1227
1370
|
var timeFormatCache = /* @__PURE__ */ new Map();
|
|
1228
1371
|
function timeFormat(locale, options) {
|
|
1229
1372
|
const key = `${locale}|${JSON.stringify(options)}`;
|
|
1230
|
-
let
|
|
1231
|
-
if (!
|
|
1232
|
-
|
|
1233
|
-
timeFormatCache.set(key,
|
|
1373
|
+
let format = timeFormatCache.get(key);
|
|
1374
|
+
if (!format) {
|
|
1375
|
+
format = new Intl.DateTimeFormat(locale, options);
|
|
1376
|
+
timeFormatCache.set(key, format);
|
|
1234
1377
|
}
|
|
1235
|
-
return
|
|
1378
|
+
return format;
|
|
1236
1379
|
}
|
|
1237
1380
|
var toDate = (t) => new Date(t.year, t.month - 1, t.day);
|
|
1238
1381
|
var TIME_AXIS_MAX_LABELS = 6;
|
|
@@ -1251,9 +1394,10 @@ function timeAxisLabelStep(values, maxLabels = TIME_AXIS_MAX_LABELS) {
|
|
|
1251
1394
|
const steps = TIME_AXIS_STEPS[parsed.granularity];
|
|
1252
1395
|
return steps.find((step) => Math.ceil(count / step) <= max) ?? Math.ceil(count / max);
|
|
1253
1396
|
}
|
|
1254
|
-
function timeAxisLabels(values,
|
|
1397
|
+
function timeAxisLabels(values, localeArg, shown = () => true) {
|
|
1255
1398
|
const parsed = parseTimeIndex(values);
|
|
1256
1399
|
if (!parsed) return null;
|
|
1400
|
+
const locale = resolveLocale(localeArg);
|
|
1257
1401
|
const { granularity, times } = parsed;
|
|
1258
1402
|
let prevYear = null;
|
|
1259
1403
|
return times.map((t, i) => {
|
|
@@ -1265,9 +1409,10 @@ function timeAxisLabels(values, locale = DEFAULT_LOCALE, shown = () => true) {
|
|
|
1265
1409
|
return timeFormat(locale, options).format(toDate(t));
|
|
1266
1410
|
});
|
|
1267
1411
|
}
|
|
1268
|
-
function timeTooltipLabels(values,
|
|
1412
|
+
function timeTooltipLabels(values, localeArg) {
|
|
1269
1413
|
const parsed = parseTimeIndex(values);
|
|
1270
1414
|
if (!parsed) return null;
|
|
1415
|
+
const locale = resolveLocale(localeArg);
|
|
1271
1416
|
const options = parsed.granularity === "year" ? { year: "numeric" } : parsed.granularity === "month" ? { year: "numeric", month: "long" } : { year: "numeric", month: "long", day: "numeric" };
|
|
1272
1417
|
return parsed.times.map((t, i) => t === null ? String(values[i] ?? "") : timeFormat(locale, options).format(toDate(t)));
|
|
1273
1418
|
}
|
|
@@ -1344,16 +1489,16 @@ function escapeHtml(value) {
|
|
|
1344
1489
|
}
|
|
1345
1490
|
var shareFormat = new Intl.NumberFormat(DEFAULT_LOCALE, { maximumFractionDigits: 1 });
|
|
1346
1491
|
var formatShare = (share) => `${shareFormat.format(share)}%`;
|
|
1347
|
-
function tooltipHtml(title, rows, valueFormatter, notes = []) {
|
|
1492
|
+
function tooltipHtml(title, rows, valueFormatter, notes = [], locale) {
|
|
1493
|
+
const t = chartText(locale);
|
|
1348
1494
|
const lines = rows.map(
|
|
1349
|
-
(row) => `<div style="display:flex;align-items:center;gap:8px;line-height:20px"><span style="display:inline-block;width:8px;height:8px;border-radius:9999px;background:${escapeHtml(row.color)}"></span><span style="flex:1;opacity:.8">${escapeHtml(row.name)}</span><span style="font-weight:600;font-variant-numeric:tabular-nums;margin-left:12px">${row.value === null ? EMPTY_VALUE : escapeHtml(valueFormatter(row.value))}${row.share === void 0 ? "" : `<span style="opacity:.6;margin-left:4px"
|
|
1495
|
+
(row) => `<div style="display:flex;align-items:center;gap:8px;line-height:20px"><span style="display:inline-block;width:8px;height:8px;border-radius:9999px;background:${escapeHtml(row.color)}"></span><span style="flex:1;opacity:.8">${escapeHtml(row.name)}</span><span style="font-weight:600;font-variant-numeric:tabular-nums;margin-left:12px">${row.value === null ? EMPTY_VALUE : escapeHtml(valueFormatter(row.value))}${row.share === void 0 ? "" : `<span style="opacity:.6;margin-left:4px">${escapeHtml(t.share(formatShare(row.share)))}</span>`}</span></div>` + (row.note === void 0 ? "" : `<div style="padding-left:16px;line-height:18px;font-size:12px;opacity:.7;font-variant-numeric:tabular-nums">${escapeHtml(row.note)}</div>`)
|
|
1350
1496
|
);
|
|
1351
1497
|
const noteLines = notes.map(
|
|
1352
1498
|
(note) => `<div style="margin-top:4px;line-height:18px;font-size:12px;opacity:.7">${escapeHtml(note)}</div>`
|
|
1353
1499
|
);
|
|
1354
1500
|
return `<div style="font-weight:500;margin-bottom:4px">${escapeHtml(title)}</div>${lines.join("")}${noteLines.join("")}`;
|
|
1355
1501
|
}
|
|
1356
|
-
var BAR_TARGET_LABEL = "\u76EE\u6A19";
|
|
1357
1502
|
var TARGET_MARKER_OVERHANG = 4;
|
|
1358
1503
|
function targetMarkerRenderer(horizontalBars, barCategoryGap, color) {
|
|
1359
1504
|
return (_params, api) => {
|
|
@@ -1379,10 +1524,10 @@ function achievementRate(value, target) {
|
|
|
1379
1524
|
if (value === null || value === void 0 || target === null || target === void 0 || !(target > 0)) return null;
|
|
1380
1525
|
return value / target * 100;
|
|
1381
1526
|
}
|
|
1382
|
-
function barTargetNote(label2, value, target, valueFormatter) {
|
|
1527
|
+
function barTargetNote(label2, value, target, valueFormatter, locale) {
|
|
1383
1528
|
if (target === null) return null;
|
|
1384
1529
|
const rate = achievementRate(value, target);
|
|
1385
|
-
return `${label2} ${valueFormatter(target)}${rate === null ? "" :
|
|
1530
|
+
return `${label2} ${valueFormatter(target)}${rate === null ? "" : chartText(locale).targetRate(formatShare(rate))}`;
|
|
1386
1531
|
}
|
|
1387
1532
|
function barHalfWidth(barCategoryGap) {
|
|
1388
1533
|
const gap = typeof barCategoryGap === "string" && /^\d+(\.\d+)?%$/.test(barCategoryGap.trim()) ? parseFloat(barCategoryGap) / 100 : 0.2;
|
|
@@ -1430,9 +1575,8 @@ var OVERLAY_SERIES_ID = "__overlay";
|
|
|
1430
1575
|
var TARGET_MARKER_SERIES_ID = "__target-marker";
|
|
1431
1576
|
var TARGET_LEGEND_SERIES_ID = "__target-legend";
|
|
1432
1577
|
var TARGET_LEGEND_ICON = "path://M0,0 L100,0 L100,24 L0,24 Z";
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
return `${label2} \u2192`;
|
|
1578
|
+
function forecastBoundaryText(label2, locale) {
|
|
1579
|
+
return `${label2 ?? chartText(locale).forecast} \u2192`;
|
|
1436
1580
|
}
|
|
1437
1581
|
var COMPARISON_LINE_WIDTH = 1.5;
|
|
1438
1582
|
var COMPARISON_OPACITY = 0.6;
|
|
@@ -1458,7 +1602,6 @@ function isDarkSurface(color) {
|
|
|
1458
1602
|
});
|
|
1459
1603
|
return 0.2126 * r + 0.7152 * g + 0.0722 * b < 0.4;
|
|
1460
1604
|
}
|
|
1461
|
-
var STACK_TOTAL_LABEL = "\u5408\u8A08";
|
|
1462
1605
|
function stackTotalsOf(values) {
|
|
1463
1606
|
const length = Math.max(0, ...values.map((v) => v.length));
|
|
1464
1607
|
return Array.from({ length }, (_, i) => {
|
|
@@ -1524,13 +1667,15 @@ function indexGrain(values) {
|
|
|
1524
1667
|
const parsed = parseTimeIndex(values);
|
|
1525
1668
|
return parsed ? parsed.granularity : null;
|
|
1526
1669
|
}
|
|
1527
|
-
function comparisonNote(current, previous, comparison, grain,
|
|
1670
|
+
function comparisonNote(current, previous, comparison, grain, format, localeArg) {
|
|
1671
|
+
const locale = resolveLocale(localeArg);
|
|
1528
1672
|
const result = computeComparison(
|
|
1529
1673
|
current,
|
|
1530
|
-
comparison.vs === "custom" ? { previous, vs: "custom", label: comparison.label ?? "", grain } : { previous, vs: comparison.vs, label: comparison.label, grain }
|
|
1674
|
+
comparison.vs === "custom" ? { previous, vs: "custom", label: comparison.label ?? "", grain } : { previous, vs: comparison.vs, label: comparison.label, grain },
|
|
1675
|
+
{ locale }
|
|
1531
1676
|
);
|
|
1532
|
-
const text = formatChange(result, defaultChangeDisplay(
|
|
1533
|
-
if (text === null) return
|
|
1677
|
+
const text = formatChange(result, defaultChangeDisplay(format), locale, format);
|
|
1678
|
+
if (text === null) return `${chartText(locale).noComparison} ${result.label}`;
|
|
1534
1679
|
const arrow = result.direction === "up" ? "\u2191" : result.direction === "down" ? "\u2193" : "\u2192";
|
|
1535
1680
|
return `${arrow} ${text.replace(/^-/, "\u2212")} ${result.label}`;
|
|
1536
1681
|
}
|
|
@@ -1555,7 +1700,6 @@ function buildCartesianOption(cfg) {
|
|
|
1555
1700
|
toneColors,
|
|
1556
1701
|
valueFormatter,
|
|
1557
1702
|
axisFormatter = valueFormatter,
|
|
1558
|
-
locale = DEFAULT_LOCALE,
|
|
1559
1703
|
type = "default",
|
|
1560
1704
|
layout = "horizontal",
|
|
1561
1705
|
curveType = "linear",
|
|
@@ -1592,7 +1736,9 @@ function buildCartesianOption(cfg) {
|
|
|
1592
1736
|
chartOptions,
|
|
1593
1737
|
reserveActions = false
|
|
1594
1738
|
} = cfg;
|
|
1595
|
-
const
|
|
1739
|
+
const locale = resolveLocale(cfg.locale);
|
|
1740
|
+
const text = chartText(locale);
|
|
1741
|
+
const provisionalLabel = cfg.provisionalLabel ?? text.provisional;
|
|
1596
1742
|
const stacked = kind !== "line" && type !== "default";
|
|
1597
1743
|
const percent = kind !== "line" && type === "percent";
|
|
1598
1744
|
const horizontalBars = kind === "bar" && layout === "vertical";
|
|
@@ -1663,8 +1809,8 @@ function buildCartesianOption(cfg) {
|
|
|
1663
1809
|
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;
|
|
1664
1810
|
const perBarTarget = kind === "bar" && Boolean(targetKey);
|
|
1665
1811
|
const hasTarget = !perBarTarget && target !== void 0 && Number.isFinite(target);
|
|
1666
|
-
const targetText = hasTarget ? targetLabel ??
|
|
1667
|
-
const highlightText = (value) => shareHighlight ? `${Math.round(value)}%` : `${stackTotals ? `${
|
|
1812
|
+
const targetText = hasTarget ? targetLabel ?? `${text.target} ${axisFormatter(target)}` : "";
|
|
1813
|
+
const highlightText = (value) => shareHighlight ? `${Math.round(value)}%` : `${stackTotals ? `${text.total} ` : ""}${axisFormatter(value)}`;
|
|
1668
1814
|
const nearTargetLabel = (p, side) => {
|
|
1669
1815
|
if (!hasTarget || !plotWidth || kind === "bar" || labels.length < 2) return false;
|
|
1670
1816
|
if (side === "under" ? p.value > target : p.value <= target) return false;
|
|
@@ -1681,7 +1827,7 @@ function buildCartesianOption(cfg) {
|
|
|
1681
1827
|
const below = (p) => !shareHighlight && !hideTargetLabel && nearTargetLabel(p, "under");
|
|
1682
1828
|
const targetLabelBelow = !shareHighlight && !hideTargetLabel && highlightPoints.some((p) => nearTargetLabel(p, "over"));
|
|
1683
1829
|
const barTargets = perBarTarget && targetKey && !percent && (stacked || categories.length === 1) ? barTargetValues(data, targetKey) : null;
|
|
1684
|
-
const barTargetName = targetLabel ??
|
|
1830
|
+
const barTargetName = targetLabel ?? text.target;
|
|
1685
1831
|
const barTargetColor = labelColor ?? guideColor;
|
|
1686
1832
|
const markPointFor = (c, color) => c === highlightSeries && highlightPoints.length > 0 ? {
|
|
1687
1833
|
silent: true,
|
|
@@ -1860,7 +2006,7 @@ function buildCartesianOption(cfg) {
|
|
|
1860
2006
|
data: []
|
|
1861
2007
|
});
|
|
1862
2008
|
}
|
|
1863
|
-
const forecastLabel = forecast?.label ??
|
|
2009
|
+
const forecastLabel = forecast?.label ?? text.forecast;
|
|
1864
2010
|
const forecastBandAlpha = isDarkSurface(labelBackground) ? FORECAST_BAND_ALPHA_DARK : FORECAST_BAND_ALPHA_LIGHT;
|
|
1865
2011
|
const forecastValues = [];
|
|
1866
2012
|
if (forecast) {
|
|
@@ -2137,8 +2283,8 @@ function buildCartesianOption(cfg) {
|
|
|
2137
2283
|
const top = percent ? 100 : maxValue ?? Math.max(0, ...(stacked ? stackTotalsOf(values) : values.flat()).map((v) => v ?? 0));
|
|
2138
2284
|
const categoryColumn = showYAxis ? (yAxisWidth ?? Math.min(160, Math.max(0, ...labels.map(estimateTextWidth)))) + 8 : 0;
|
|
2139
2285
|
const plot = plotWidth - categoryColumn - (highlightPoints.length > 0 ? 64 : 16) - 4;
|
|
2140
|
-
const
|
|
2141
|
-
return valueAxisSplitNumber(plot, [
|
|
2286
|
+
const text2 = percent ? (v) => `${v}%` : (v) => axisFormatter(v);
|
|
2287
|
+
return valueAxisSplitNumber(plot, [text2(0), text2(top)]);
|
|
2142
2288
|
})();
|
|
2143
2289
|
const limits = valueAxisLimits({ minValue, maxValue }, kind !== "line");
|
|
2144
2290
|
const splitNumber = horizontalBars ? valueSplitNumber : valueAxisSplitCount(plotHeight);
|
|
@@ -2276,7 +2422,7 @@ function buildCartesianOption(cfg) {
|
|
|
2276
2422
|
});
|
|
2277
2423
|
}
|
|
2278
2424
|
if (stackTotals && i <= lastActual && rows.length > 1) {
|
|
2279
|
-
rows.push({ name:
|
|
2425
|
+
rows.push({ name: text.total, color: "transparent", value: stackTotals[i] ?? null });
|
|
2280
2426
|
}
|
|
2281
2427
|
const provisional = provStart !== -1 && i >= provStart && i <= lastActual;
|
|
2282
2428
|
if (provisional) {
|
|
@@ -2291,19 +2437,19 @@ function buildCartesianOption(cfg) {
|
|
|
2291
2437
|
...noteFor(at)
|
|
2292
2438
|
});
|
|
2293
2439
|
});
|
|
2294
|
-
if (stackTotals && rows.length > 1) rows.push({ name:
|
|
2440
|
+
if (stackTotals && rows.length > 1) rows.push({ name: text.total, color: "transparent", value: stackTotals[i] ?? null });
|
|
2295
2441
|
}
|
|
2296
2442
|
const title = tooltipTitles[i] ?? labels[i] ?? "";
|
|
2297
2443
|
const lines = [];
|
|
2298
2444
|
if (barTargets && i <= lastActual) {
|
|
2299
2445
|
const total = stackTotals ? stackTotals[i] ?? null : values[0]?.[i] ?? null;
|
|
2300
|
-
const note = barTargetNote(barTargetName, total, barTargets[i] ?? null, valueFormatter);
|
|
2446
|
+
const note = barTargetNote(barTargetName, total, barTargets[i] ?? null, valueFormatter, locale);
|
|
2301
2447
|
if (note) lines.push(note);
|
|
2302
2448
|
}
|
|
2303
2449
|
for (const note of notes) {
|
|
2304
2450
|
if (note.to === void 0 ? note.from === i : note.from <= i && i <= note.to) lines.push(note.label);
|
|
2305
2451
|
}
|
|
2306
|
-
return tooltipHtml(provisional ?
|
|
2452
|
+
return tooltipHtml(provisional ? text.provisionalTitle(title, provisionalLabel) : title, rows, valueFormatter, lines, locale);
|
|
2307
2453
|
}
|
|
2308
2454
|
},
|
|
2309
2455
|
xAxis: horizontalBars ? valueAxis : categoryAxis,
|
|
@@ -2332,7 +2478,6 @@ function donutTopText(slices, labels) {
|
|
|
2332
2478
|
return top ? { label: labelOf(top.name, labels), amount: donutShareText(top.value, total) } : null;
|
|
2333
2479
|
}
|
|
2334
2480
|
var DONUT_OUTSIDE_LABELS = 2;
|
|
2335
|
-
var DEFAULT_TOTAL_LABEL = "\u5408\u8A08";
|
|
2336
2481
|
var sliceValue = (value) => Number.isFinite(value) && value > 0 ? value : 0;
|
|
2337
2482
|
function donutShareText(value, total) {
|
|
2338
2483
|
const v = sliceValue(value);
|
|
@@ -2344,7 +2489,8 @@ function donutLegendItems(slices) {
|
|
|
2344
2489
|
const total = slices.reduce((sum, s) => sum + sliceValue(s.value), 0);
|
|
2345
2490
|
return slices.map((s, slice) => ({ name: s.name, value: sliceValue(s.value), share: donutShareText(s.value, total), isOther: Boolean(s.isOther), slice })).sort((a, b) => Number(a.isOther) - Number(b.isOther) || b.value - a.value || a.slice - b.slice);
|
|
2346
2491
|
}
|
|
2347
|
-
function donutCenterText(total, valueFormatter, { totalLabel
|
|
2492
|
+
function donutCenterText(total, valueFormatter, { totalLabel, unit, locale } = {}) {
|
|
2493
|
+
totalLabel ??= chartText(locale).total;
|
|
2348
2494
|
const amount = valueFormatter(total);
|
|
2349
2495
|
return { label: totalLabel, value: unit ? `${amount} ${unit}` : amount, amount, ...unit ? { unit } : {} };
|
|
2350
2496
|
}
|
|
@@ -2464,7 +2610,6 @@ function labelRows(data, index, labels) {
|
|
|
2464
2610
|
function hasLabel(labels, key) {
|
|
2465
2611
|
return Boolean(labels) && Object.prototype.hasOwnProperty.call(labels, key);
|
|
2466
2612
|
}
|
|
2467
|
-
var DEFAULT_PROVISIONAL_LABEL = "\u901F\u5831";
|
|
2468
2613
|
function provisionalStart(indexValues, from) {
|
|
2469
2614
|
if (from === void 0 || from === null) return -1;
|
|
2470
2615
|
const key = String(from);
|
|
@@ -2477,6 +2622,10 @@ function splitProvisional(values, start) {
|
|
|
2477
2622
|
provisional: values.map((v, i) => i >= Math.max(0, start - 1) ? v : null)
|
|
2478
2623
|
};
|
|
2479
2624
|
}
|
|
2625
|
+
var TEXT4 = {
|
|
2626
|
+
ja: { item: "\u9805\u76EE", chart: (categories) => `${categories.join("\u30FB")}\u306E\u9762\u30B0\u30E9\u30D5` },
|
|
2627
|
+
en: { item: "Item", chart: (categories) => `Area chart of ${categories.join(", ")}` }
|
|
2628
|
+
};
|
|
2480
2629
|
var NO_ROWS = [];
|
|
2481
2630
|
function AreaChartImpl({
|
|
2482
2631
|
data = NO_ROWS,
|
|
@@ -2485,7 +2634,7 @@ function AreaChartImpl({
|
|
|
2485
2634
|
colors,
|
|
2486
2635
|
labels,
|
|
2487
2636
|
valueFormatter,
|
|
2488
|
-
format
|
|
2637
|
+
format,
|
|
2489
2638
|
title,
|
|
2490
2639
|
summary,
|
|
2491
2640
|
actions,
|
|
@@ -2525,12 +2674,17 @@ function AreaChartImpl({
|
|
|
2525
2674
|
...rest
|
|
2526
2675
|
}, ref) {
|
|
2527
2676
|
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
2528
|
-
const
|
|
2529
|
-
const
|
|
2530
|
-
const
|
|
2677
|
+
const locale = useLocale();
|
|
2678
|
+
const t = TEXT4[uiLanguage(locale)];
|
|
2679
|
+
const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2680
|
+
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2681
|
+
const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2531
2682
|
const comparisonCategory = comparison && categories.includes(comparison.category) ? comparison.category : void 0;
|
|
2532
2683
|
const comparisonConfig = comparisonCategory === void 0 ? void 0 : comparison;
|
|
2533
|
-
const series = useMemo(
|
|
2684
|
+
const series = useMemo(
|
|
2685
|
+
() => aggregateSeriesKeeping(data, categories, comparisonCategory, void 0, otherSeriesLabel(locale)),
|
|
2686
|
+
[data, categories, comparisonCategory, locale]
|
|
2687
|
+
);
|
|
2534
2688
|
const palette = useMemo(
|
|
2535
2689
|
() => resolveChartColors(
|
|
2536
2690
|
seriesColorsWithComparison(series.categories, colors, CHART_OTHER_COLOR, series.otherCategory, categories, comparisonCategory),
|
|
@@ -2577,7 +2731,7 @@ function AreaChartImpl({
|
|
|
2577
2731
|
annotations,
|
|
2578
2732
|
forecast,
|
|
2579
2733
|
comparison: comparisonConfig,
|
|
2580
|
-
comparisonFormat:
|
|
2734
|
+
comparisonFormat: format,
|
|
2581
2735
|
provisionalFrom,
|
|
2582
2736
|
provisionalLabel,
|
|
2583
2737
|
reserveActions: Boolean(actions),
|
|
@@ -2586,7 +2740,8 @@ function AreaChartImpl({
|
|
|
2586
2740
|
labelColor: tokens?.foreground ?? void 0,
|
|
2587
2741
|
plotWidth,
|
|
2588
2742
|
plotHeight: typeof height === "number" ? height : void 0,
|
|
2589
|
-
chartOptions
|
|
2743
|
+
chartOptions,
|
|
2744
|
+
locale
|
|
2590
2745
|
}),
|
|
2591
2746
|
[
|
|
2592
2747
|
series,
|
|
@@ -2622,23 +2777,24 @@ function AreaChartImpl({
|
|
|
2622
2777
|
annotations,
|
|
2623
2778
|
forecast,
|
|
2624
2779
|
comparisonConfig,
|
|
2625
|
-
|
|
2780
|
+
format,
|
|
2626
2781
|
height,
|
|
2627
2782
|
tokens,
|
|
2628
2783
|
surface,
|
|
2629
2784
|
plotWidth,
|
|
2630
|
-
chartOptions
|
|
2785
|
+
chartOptions,
|
|
2786
|
+
locale
|
|
2631
2787
|
]
|
|
2632
2788
|
);
|
|
2633
2789
|
const dataTable = useMemo(() => {
|
|
2634
|
-
const table = chartDataTable(labelRows(series.data, index, labels), index, series.categories, tooltipFormatter, labels,
|
|
2635
|
-
const times = timeTooltipLabels(series.data.map((row) => row[index]));
|
|
2790
|
+
const table = chartDataTable(labelRows(series.data, index, labels), index, series.categories, tooltipFormatter, labels, t.item);
|
|
2791
|
+
const times = timeTooltipLabels(series.data.map((row) => row[index]), locale);
|
|
2636
2792
|
return times ? { ...table, rows: table.rows.map((row, i) => [times[i] ?? row[0] ?? "", ...row.slice(1)]) } : table;
|
|
2637
|
-
}, [series, index, tooltipFormatter, labels]);
|
|
2638
|
-
const label2 = ariaLabel ??
|
|
2793
|
+
}, [series, index, tooltipFormatter, labels, t, locale]);
|
|
2794
|
+
const label2 = ariaLabel ?? t.chart(categories);
|
|
2639
2795
|
const resolvedSummary = useMemo(
|
|
2640
|
-
() => summary === "auto" ? buildChartSummary({ data, index, categories, title, format
|
|
2641
|
-
[summary, data, index, categories, title,
|
|
2796
|
+
() => summary === "auto" ? buildChartSummary({ data, index, categories, title, format, valueFormatter, locale }) : summary,
|
|
2797
|
+
[summary, data, index, categories, title, format, valueFormatter, locale]
|
|
2642
2798
|
);
|
|
2643
2799
|
return /* @__PURE__ */ jsx(
|
|
2644
2800
|
ChartFrame,
|
|
@@ -2661,6 +2817,10 @@ function AreaChartImpl({
|
|
|
2661
2817
|
}
|
|
2662
2818
|
var AreaChart = forwardRef(AreaChartImpl);
|
|
2663
2819
|
AreaChart.displayName = "AreaChart";
|
|
2820
|
+
var TEXT5 = {
|
|
2821
|
+
ja: { item: "\u9805\u76EE", chart: (categories) => `${categories.join("\u30FB")}\u306E\u68D2\u30B0\u30E9\u30D5` },
|
|
2822
|
+
en: { item: "Item", chart: (categories) => `Bar chart of ${categories.join(", ")}` }
|
|
2823
|
+
};
|
|
2664
2824
|
var NO_ROWS2 = [];
|
|
2665
2825
|
function BarChartImpl({
|
|
2666
2826
|
data = NO_ROWS2,
|
|
@@ -2669,7 +2829,7 @@ function BarChartImpl({
|
|
|
2669
2829
|
colors,
|
|
2670
2830
|
labels,
|
|
2671
2831
|
valueFormatter,
|
|
2672
|
-
format
|
|
2832
|
+
format,
|
|
2673
2833
|
title,
|
|
2674
2834
|
summary,
|
|
2675
2835
|
actions,
|
|
@@ -2707,10 +2867,12 @@ function BarChartImpl({
|
|
|
2707
2867
|
...rest
|
|
2708
2868
|
}, ref) {
|
|
2709
2869
|
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
2710
|
-
const
|
|
2711
|
-
const
|
|
2712
|
-
const
|
|
2713
|
-
const
|
|
2870
|
+
const locale = useLocale();
|
|
2871
|
+
const t = TEXT5[uiLanguage(locale)];
|
|
2872
|
+
const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2873
|
+
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2874
|
+
const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2875
|
+
const series = useMemo(() => aggregateSeries(data, categories, void 0, otherSeriesLabel(locale)), [data, categories, locale]);
|
|
2714
2876
|
const palette = useMemo(
|
|
2715
2877
|
() => resolveChartColors(
|
|
2716
2878
|
// Meaning colours on bars are AREA colours (`warning` -> `--warning-fill`), the same as the thresholds' and a legend's.
|
|
@@ -2768,7 +2930,8 @@ function BarChartImpl({
|
|
|
2768
2930
|
labelColor: tokens?.foreground ?? void 0,
|
|
2769
2931
|
plotWidth,
|
|
2770
2932
|
plotHeight: typeof height === "number" ? height : void 0,
|
|
2771
|
-
chartOptions
|
|
2933
|
+
chartOptions,
|
|
2934
|
+
locale
|
|
2772
2935
|
}),
|
|
2773
2936
|
[
|
|
2774
2937
|
series,
|
|
@@ -2809,18 +2972,19 @@ function BarChartImpl({
|
|
|
2809
2972
|
tokens,
|
|
2810
2973
|
surface,
|
|
2811
2974
|
plotWidth,
|
|
2812
|
-
chartOptions
|
|
2975
|
+
chartOptions,
|
|
2976
|
+
locale
|
|
2813
2977
|
]
|
|
2814
2978
|
);
|
|
2815
2979
|
const dataTable = useMemo(() => {
|
|
2816
|
-
const table = chartDataTable(labelRows(series.data, index, labels), index, series.categories, tooltipFormatter, labels,
|
|
2817
|
-
const times = timeTooltipLabels(series.data.map((row) => row[index]));
|
|
2980
|
+
const table = chartDataTable(labelRows(series.data, index, labels), index, series.categories, tooltipFormatter, labels, t.item);
|
|
2981
|
+
const times = timeTooltipLabels(series.data.map((row) => row[index]), locale);
|
|
2818
2982
|
return times ? { ...table, rows: table.rows.map((row, i) => [times[i] ?? row[0] ?? "", ...row.slice(1)]) } : table;
|
|
2819
|
-
}, [series, index, tooltipFormatter, labels]);
|
|
2820
|
-
const label2 = ariaLabel ??
|
|
2983
|
+
}, [series, index, tooltipFormatter, labels, t, locale]);
|
|
2984
|
+
const label2 = ariaLabel ?? t.chart(categories);
|
|
2821
2985
|
const resolvedSummary = useMemo(
|
|
2822
|
-
() => summary === "auto" ? buildChartSummary({ data, index, categories, title, format
|
|
2823
|
-
[summary, data, index, categories, title,
|
|
2986
|
+
() => summary === "auto" ? buildChartSummary({ data, index, categories, title, format, valueFormatter, locale }) : summary,
|
|
2987
|
+
[summary, data, index, categories, title, format, valueFormatter, locale]
|
|
2824
2988
|
);
|
|
2825
2989
|
return /* @__PURE__ */ jsx(
|
|
2826
2990
|
ChartFrame,
|
|
@@ -2843,6 +3007,10 @@ function BarChartImpl({
|
|
|
2843
3007
|
}
|
|
2844
3008
|
var BarChart = forwardRef(BarChartImpl);
|
|
2845
3009
|
BarChart.displayName = "BarChart";
|
|
3010
|
+
var TEXT6 = {
|
|
3011
|
+
ja: { item: "\u9805\u76EE", chart: (categories) => `${categories.join("\u30FB")}\u306E\u6298\u308C\u7DDA\u30B0\u30E9\u30D5` },
|
|
3012
|
+
en: { item: "Item", chart: (categories) => `Line chart of ${categories.join(", ")}` }
|
|
3013
|
+
};
|
|
2846
3014
|
var NO_ROWS3 = [];
|
|
2847
3015
|
function LineChartImpl({
|
|
2848
3016
|
data = NO_ROWS3,
|
|
@@ -2851,7 +3019,7 @@ function LineChartImpl({
|
|
|
2851
3019
|
colors,
|
|
2852
3020
|
labels,
|
|
2853
3021
|
valueFormatter,
|
|
2854
|
-
format
|
|
3022
|
+
format,
|
|
2855
3023
|
title,
|
|
2856
3024
|
summary,
|
|
2857
3025
|
actions,
|
|
@@ -2891,12 +3059,17 @@ function LineChartImpl({
|
|
|
2891
3059
|
...rest
|
|
2892
3060
|
}, ref) {
|
|
2893
3061
|
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
2894
|
-
const
|
|
2895
|
-
const
|
|
2896
|
-
const
|
|
3062
|
+
const locale = useLocale();
|
|
3063
|
+
const t = TEXT6[uiLanguage(locale)];
|
|
3064
|
+
const tooltipFormatter = useMemo(() => resolveValueFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
3065
|
+
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
3066
|
+
const axisTicks = useMemo(() => resolveAxisTickFormatter(valueFormatter, format, locale), [valueFormatter, format, locale]);
|
|
2897
3067
|
const comparisonCategory = comparison && categories.includes(comparison.category) ? comparison.category : void 0;
|
|
2898
3068
|
const comparisonConfig = comparisonCategory === void 0 ? void 0 : comparison;
|
|
2899
|
-
const series = useMemo(
|
|
3069
|
+
const series = useMemo(
|
|
3070
|
+
() => aggregateSeriesKeeping(data, categories, comparisonCategory, void 0, otherSeriesLabel(locale)),
|
|
3071
|
+
[data, categories, comparisonCategory, locale]
|
|
3072
|
+
);
|
|
2900
3073
|
const palette = useMemo(
|
|
2901
3074
|
() => resolveChartColors(
|
|
2902
3075
|
seriesColorsWithComparison(series.categories, colors, CHART_OTHER_COLOR, series.otherCategory, categories, comparisonCategory),
|
|
@@ -2944,7 +3117,7 @@ function LineChartImpl({
|
|
|
2944
3117
|
annotations,
|
|
2945
3118
|
forecast,
|
|
2946
3119
|
comparison: comparisonConfig,
|
|
2947
|
-
comparisonFormat:
|
|
3120
|
+
comparisonFormat: format,
|
|
2948
3121
|
provisionalFrom,
|
|
2949
3122
|
provisionalLabel,
|
|
2950
3123
|
reserveActions: Boolean(actions),
|
|
@@ -2953,7 +3126,8 @@ function LineChartImpl({
|
|
|
2953
3126
|
labelColor: tokens?.foreground ?? void 0,
|
|
2954
3127
|
plotWidth,
|
|
2955
3128
|
plotHeight: typeof height === "number" ? height : void 0,
|
|
2956
|
-
chartOptions
|
|
3129
|
+
chartOptions,
|
|
3130
|
+
locale
|
|
2957
3131
|
}),
|
|
2958
3132
|
[
|
|
2959
3133
|
series,
|
|
@@ -2990,23 +3164,24 @@ function LineChartImpl({
|
|
|
2990
3164
|
annotations,
|
|
2991
3165
|
forecast,
|
|
2992
3166
|
comparisonConfig,
|
|
2993
|
-
|
|
3167
|
+
format,
|
|
2994
3168
|
height,
|
|
2995
3169
|
tokens,
|
|
2996
3170
|
surface,
|
|
2997
3171
|
plotWidth,
|
|
2998
|
-
chartOptions
|
|
3172
|
+
chartOptions,
|
|
3173
|
+
locale
|
|
2999
3174
|
]
|
|
3000
3175
|
);
|
|
3001
3176
|
const dataTable = useMemo(() => {
|
|
3002
|
-
const table = chartDataTable(labelRows(series.data, index, labels), index, series.categories, tooltipFormatter, labels,
|
|
3003
|
-
const times = timeTooltipLabels(series.data.map((row) => row[index]));
|
|
3177
|
+
const table = chartDataTable(labelRows(series.data, index, labels), index, series.categories, tooltipFormatter, labels, t.item);
|
|
3178
|
+
const times = timeTooltipLabels(series.data.map((row) => row[index]), locale);
|
|
3004
3179
|
return times ? { ...table, rows: table.rows.map((row, i) => [times[i] ?? row[0] ?? "", ...row.slice(1)]) } : table;
|
|
3005
|
-
}, [series, index, tooltipFormatter, labels]);
|
|
3006
|
-
const label2 = ariaLabel ??
|
|
3180
|
+
}, [series, index, tooltipFormatter, labels, t, locale]);
|
|
3181
|
+
const label2 = ariaLabel ?? t.chart(categories);
|
|
3007
3182
|
const resolvedSummary = useMemo(
|
|
3008
|
-
() => summary === "auto" ? buildChartSummary({ data, index, categories, title, format
|
|
3009
|
-
[summary, data, index, categories, title,
|
|
3183
|
+
() => summary === "auto" ? buildChartSummary({ data, index, categories, title, format, valueFormatter, locale }) : summary,
|
|
3184
|
+
[summary, data, index, categories, title, format, valueFormatter, locale]
|
|
3010
3185
|
);
|
|
3011
3186
|
return /* @__PURE__ */ jsx(
|
|
3012
3187
|
ChartFrame,
|
|
@@ -3029,6 +3204,10 @@ function LineChartImpl({
|
|
|
3029
3204
|
}
|
|
3030
3205
|
var LineChart = forwardRef(LineChartImpl);
|
|
3031
3206
|
LineChart.displayName = "LineChart";
|
|
3207
|
+
var TEXT7 = {
|
|
3208
|
+
ja: { item: "\u9805\u76EE", value: "\u5024", chart: (shares) => `\u69CB\u6210\u6BD4\u306E\u30C9\u30FC\u30CA\u30C4\u30B0\u30E9\u30D5\uFF08${shares.join("\u3001")}\uFF09` },
|
|
3209
|
+
en: { item: "Item", value: "Value", chart: (shares) => `Donut chart of shares (${shares.join(", ")})` }
|
|
3210
|
+
};
|
|
3032
3211
|
function useElementWidth() {
|
|
3033
3212
|
const [node, setNode] = useState(null);
|
|
3034
3213
|
const [width, setWidth] = useState(null);
|
|
@@ -3048,7 +3227,7 @@ function DonutChartImpl({
|
|
|
3048
3227
|
categories,
|
|
3049
3228
|
colors,
|
|
3050
3229
|
labels,
|
|
3051
|
-
format
|
|
3230
|
+
format,
|
|
3052
3231
|
valueFormatter: valueFormatterProp,
|
|
3053
3232
|
title,
|
|
3054
3233
|
summary,
|
|
@@ -3077,11 +3256,13 @@ function DonutChartImpl({
|
|
|
3077
3256
|
const center = resolveDonutCenter(donutOptions?.centerLabel, { showLabel: donutOptions?.showLabel ?? showLabel, label: label2 });
|
|
3078
3257
|
const maxSlices = donutOptions?.maxSlices;
|
|
3079
3258
|
const showLegend = donutOptions?.showLegend ?? true;
|
|
3080
|
-
const
|
|
3259
|
+
const locale = useLocale();
|
|
3260
|
+
const t = TEXT7[uiLanguage(locale)];
|
|
3261
|
+
const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format, locale), [valueFormatterProp, format, locale]);
|
|
3081
3262
|
const { ref: frameRef, tokens } = useChartSurface(ref);
|
|
3082
3263
|
const slices = useMemo(
|
|
3083
|
-
() => donutSlices(data, { index: labelKey, value: valueKey, colors, maxSlices, otherColor: CHART_OTHER_COLOR }),
|
|
3084
|
-
[data, labelKey, valueKey, colors, maxSlices]
|
|
3264
|
+
() => donutSlices(data, { index: labelKey, value: valueKey, colors, maxSlices, otherColor: CHART_OTHER_COLOR, otherLabel: otherSeriesLabel(locale) }),
|
|
3265
|
+
[data, labelKey, valueKey, colors, maxSlices, locale]
|
|
3085
3266
|
);
|
|
3086
3267
|
const palette = useMemo(() => resolveChartColors(slices.map((s) => chartFillName(s.color)), tokens), [slices, tokens]);
|
|
3087
3268
|
const rows = useMemo(() => slices.map((s) => s.row), [slices]);
|
|
@@ -3118,13 +3299,13 @@ function DonutChartImpl({
|
|
|
3118
3299
|
let centerLabel = null;
|
|
3119
3300
|
if (center.kind === "custom") centerLabel = center.node;
|
|
3120
3301
|
else if (center.kind === "total") {
|
|
3121
|
-
const text = donutCenterText(total, valueFormatter, { totalLabel: donutOptions?.totalLabel, unit: donutOptions?.unit });
|
|
3302
|
+
const text = donutCenterText(total, valueFormatter, { totalLabel: donutOptions?.totalLabel, unit: donutOptions?.unit, locale });
|
|
3122
3303
|
centerLabel = caption(text.label, text.amount, text.unit);
|
|
3123
3304
|
} else if (center.kind === "top") {
|
|
3124
3305
|
const top = donutTopText(slices, labels);
|
|
3125
3306
|
centerLabel = top && caption(top.label, top.amount);
|
|
3126
3307
|
}
|
|
3127
|
-
const a11yLabel = ariaLabel ??
|
|
3308
|
+
const a11yLabel = ariaLabel ?? t.chart(legend.map((item) => `${labelOf(item.name, labels)} ${item.share}`));
|
|
3128
3309
|
const dataTable = useMemo(
|
|
3129
3310
|
() => chartDataTable(
|
|
3130
3311
|
// Fixed keys, so `labels` (which renames the rows) cannot collide with the column names.
|
|
@@ -3132,13 +3313,13 @@ function DonutChartImpl({
|
|
|
3132
3313
|
"name",
|
|
3133
3314
|
["value"],
|
|
3134
3315
|
valueFormatter,
|
|
3135
|
-
{ name: labels?.[labelKey] ??
|
|
3316
|
+
{ name: labels?.[labelKey] ?? t.item, value: labels?.[valueKey] ?? t.value }
|
|
3136
3317
|
),
|
|
3137
|
-
[rows, labelKey, valueKey, valueFormatter, labels]
|
|
3318
|
+
[rows, labelKey, valueKey, valueFormatter, labels, t]
|
|
3138
3319
|
);
|
|
3139
3320
|
const resolvedSummary = useMemo(
|
|
3140
|
-
() => summary === "auto" ? buildShareSummary(slices, title) : summary,
|
|
3141
|
-
[summary, slices, title]
|
|
3321
|
+
() => summary === "auto" ? buildShareSummary(slices, title, locale) : summary,
|
|
3322
|
+
[summary, slices, title, locale]
|
|
3142
3323
|
);
|
|
3143
3324
|
return /* @__PURE__ */ jsx(
|
|
3144
3325
|
ChartFrame,
|
|
@@ -3193,6 +3374,10 @@ function DonutChartImpl({
|
|
|
3193
3374
|
}
|
|
3194
3375
|
var DonutChart = forwardRef(DonutChartImpl);
|
|
3195
3376
|
DonutChart.displayName = "DonutChart";
|
|
3377
|
+
var TEXT8 = {
|
|
3378
|
+
ja: { item: "\u9805\u76EE", value: "\u5024" },
|
|
3379
|
+
en: { item: "Item", value: "Value" }
|
|
3380
|
+
};
|
|
3196
3381
|
var listHeight = (n) => n * 32 + Math.max(0, n - 1) * 6;
|
|
3197
3382
|
var isExternal = (href) => /^https?:\/\//.test(href);
|
|
3198
3383
|
var NO_ROWS5 = [];
|
|
@@ -3204,7 +3389,7 @@ function BarListImpl({
|
|
|
3204
3389
|
labels,
|
|
3205
3390
|
thresholds,
|
|
3206
3391
|
highlight,
|
|
3207
|
-
format
|
|
3392
|
+
format,
|
|
3208
3393
|
valueFormatter,
|
|
3209
3394
|
formatValue: formatValue2,
|
|
3210
3395
|
title,
|
|
@@ -3226,16 +3411,18 @@ function BarListImpl({
|
|
|
3226
3411
|
const frame = requestAnimationFrame(() => setMounted(true));
|
|
3227
3412
|
return () => cancelAnimationFrame(frame);
|
|
3228
3413
|
}, [showAnimation]);
|
|
3414
|
+
const locale = useLocale();
|
|
3415
|
+
const t = TEXT8[uiLanguage(locale)];
|
|
3229
3416
|
const maxItems = barListOptions?.maxItems ?? MAX_CHART_SERIES;
|
|
3230
3417
|
const token = Array.isArray(colors) ? colors[0] : colors;
|
|
3231
3418
|
const barColor = token ?? color ?? "chart-1";
|
|
3232
|
-
const formatter = resolveValueFormatter(valueFormatter ?? formatValue2,
|
|
3419
|
+
const formatter = resolveValueFormatter(valueFormatter ?? formatValue2, format, locale);
|
|
3233
3420
|
const baseRows = barListRows(data, {
|
|
3234
3421
|
index,
|
|
3235
3422
|
category: categories?.[0],
|
|
3236
3423
|
sortOrder: barListOptions?.sortOrder ?? sortOrder ?? "descending",
|
|
3237
3424
|
maxItems,
|
|
3238
|
-
otherLabel: barListOptions?.otherLabel,
|
|
3425
|
+
otherLabel: barListOptions?.otherLabel ?? otherSeriesLabel(locale),
|
|
3239
3426
|
exclude: barListOptions?.exclude
|
|
3240
3427
|
});
|
|
3241
3428
|
const rows = baseRows.map((row) => {
|
|
@@ -3254,7 +3441,7 @@ function BarListImpl({
|
|
|
3254
3441
|
"name",
|
|
3255
3442
|
["value"],
|
|
3256
3443
|
formatter,
|
|
3257
|
-
{ name: index && labels?.[index] ||
|
|
3444
|
+
{ name: index && labels?.[index] || t.item, value: categories?.[0] && labels?.[categories[0]] || t.value }
|
|
3258
3445
|
);
|
|
3259
3446
|
const list = /* @__PURE__ */ jsxs("div", { "data-slot": "bar-list", className: "flex justify-between gap-6 text-sm", ...props, children: [
|
|
3260
3447
|
/* @__PURE__ */ jsx("div", { className: "relative min-w-0 flex-1 space-y-1.5", children: rows.map((row, i) => {
|
|
@@ -3328,9 +3515,10 @@ function BarListImpl({
|
|
|
3328
3515
|
var BarList = forwardRef(BarListImpl);
|
|
3329
3516
|
BarList.displayName = "BarList";
|
|
3330
3517
|
var NO_ROWS6 = [];
|
|
3331
|
-
var CategoryBar = forwardRef(function CategoryBar2({ values = NO_ROWS6, colors, marker, showLabels = true, format
|
|
3518
|
+
var CategoryBar = forwardRef(function CategoryBar2({ values = NO_ROWS6, colors, marker, showLabels = true, format, valueFormatter: valueFormatterProp, className, ...props }, forwardedRef) {
|
|
3332
3519
|
const { ref, width } = useChartSurface(forwardedRef, null);
|
|
3333
|
-
const
|
|
3520
|
+
const locale = useLocale();
|
|
3521
|
+
const valueFormatter = useMemo(() => resolveAxisFormatter(valueFormatterProp, format, locale), [valueFormatterProp, format, locale]);
|
|
3334
3522
|
const segments = categoryBarSegments(values);
|
|
3335
3523
|
const markerPosition = marker ? categoryBarMarkerPosition(marker.value, values) : 0;
|
|
3336
3524
|
const allLabels = showLabels ? categoryBarLabels(values, void 0, marker ? markerPosition : void 0) : [];
|
|
@@ -3487,6 +3675,45 @@ var Tracker = forwardRef(function Tracker2({ data = NO_ROWS7, defaultColor, hove
|
|
|
3487
3675
|
});
|
|
3488
3676
|
Tracker.displayName = "Tracker";
|
|
3489
3677
|
use([GraphicComponent]);
|
|
3678
|
+
var TEXT9 = {
|
|
3679
|
+
ja: {
|
|
3680
|
+
net: "\u7D14\u5897",
|
|
3681
|
+
total: "\u5408\u8A08",
|
|
3682
|
+
change: "\u5897\u6E1B",
|
|
3683
|
+
cumulative: "\u7D2F\u8A08",
|
|
3684
|
+
cumulativeChange: "\u7D2F\u8A08\u5897\u6E1B",
|
|
3685
|
+
item: "\u9805\u76EE",
|
|
3686
|
+
start: "\u958B\u59CB",
|
|
3687
|
+
end: "\u7D42\u4E86",
|
|
3688
|
+
fromTo: (from, to, net) => `${from} \u2192 ${to}\uFF08${net}\uFF09`,
|
|
3689
|
+
from: (from, net) => `${from} \u304B\u3089 ${net}`,
|
|
3690
|
+
to: (to, net) => `${to}\uFF08${net}\uFF09`,
|
|
3691
|
+
netOnly: (net) => `\u5897\u6E1B\u306E\u5408\u8A08 ${net}`,
|
|
3692
|
+
increase: (name, value) => `\u6700\u5927\u306E\u5897\u52A0\u306F ${name}\uFF08${value}\uFF09`,
|
|
3693
|
+
decrease: (name, value) => `\u6700\u5927\u306E\u6E1B\u5C11\u306F ${name}\uFF08${value}\uFF09`,
|
|
3694
|
+
sentenceJoin: "\u3002",
|
|
3695
|
+
chart: (label2) => `${label2}\u306E\u30A6\u30A9\u30FC\u30BF\u30FC\u30D5\u30A9\u30FC\u30EB\u30C1\u30E3\u30FC\u30C8`
|
|
3696
|
+
},
|
|
3697
|
+
en: {
|
|
3698
|
+
net: "Net change",
|
|
3699
|
+
total: "Total",
|
|
3700
|
+
change: "Change",
|
|
3701
|
+
cumulative: "Cumulative",
|
|
3702
|
+
cumulativeChange: "Cumulative change",
|
|
3703
|
+
item: "Item",
|
|
3704
|
+
start: "Start",
|
|
3705
|
+
end: "End",
|
|
3706
|
+
fromTo: (from, to, net) => `${from} \u2192 ${to} (${net})`,
|
|
3707
|
+
from: (from, net) => `${net} from ${from}`,
|
|
3708
|
+
to: (to, net) => `${to} (${net})`,
|
|
3709
|
+
netOnly: (net) => `Net change ${net}`,
|
|
3710
|
+
increase: (name, value) => `Largest increase: ${name} (${value})`,
|
|
3711
|
+
decrease: (name, value) => `Largest decrease: ${name} (${value})`,
|
|
3712
|
+
sentenceJoin: ". ",
|
|
3713
|
+
chart: (label2) => `Waterfall chart of ${label2}`
|
|
3714
|
+
}
|
|
3715
|
+
};
|
|
3716
|
+
var textOf = (locale) => TEXT9[uiLanguage(resolveLocale(locale))];
|
|
3490
3717
|
function waterfallSteps(data, config) {
|
|
3491
3718
|
const totals = new Set(config.totals ?? []);
|
|
3492
3719
|
const delta = config.mode === "delta";
|
|
@@ -3505,11 +3732,13 @@ function waterfallSteps(data, config) {
|
|
|
3505
3732
|
return { name, kind: n > 0 ? "increase" : n < 0 ? "decrease" : "flat", value: n, start, end: running, row };
|
|
3506
3733
|
});
|
|
3507
3734
|
if (delta && steps.some((s) => s.kind !== "gap")) {
|
|
3508
|
-
steps.push({ name:
|
|
3735
|
+
steps.push({ name: deltaTotalName(config.locale), kind: "total", value: running, start: 0, end: running, row: {} });
|
|
3509
3736
|
}
|
|
3510
3737
|
return steps;
|
|
3511
3738
|
}
|
|
3512
|
-
|
|
3739
|
+
function deltaTotalName(locale) {
|
|
3740
|
+
return textOf(locale).net;
|
|
3741
|
+
}
|
|
3513
3742
|
function waterfallDeltaEnds(data, config) {
|
|
3514
3743
|
const totals = new Set(config.totals ?? []);
|
|
3515
3744
|
const kinds = data.map((row) => totals.has(String(row[config.index] ?? "")));
|
|
@@ -3525,16 +3754,17 @@ function waterfallDeltaEnds(data, config) {
|
|
|
3525
3754
|
const closing = closingRow && closingRow.value === null && opening?.value != null ? { ...closingRow, value: opening.value + net } : closingRow;
|
|
3526
3755
|
return { opening, closing, net };
|
|
3527
3756
|
}
|
|
3528
|
-
function waterfallDeltaNote(ends, formatter, labels) {
|
|
3757
|
+
function waterfallDeltaNote(ends, formatter, labels, locale) {
|
|
3758
|
+
const t = textOf(locale);
|
|
3529
3759
|
const net = signedText(ends.net, formatter);
|
|
3530
3760
|
const { opening, closing } = ends;
|
|
3531
3761
|
const side = (e) => e && e.value !== null ? `${labelOf(e.name, labels)} ${formatter(e.value)}` : null;
|
|
3532
3762
|
const from = side(opening);
|
|
3533
3763
|
const to = side(closing);
|
|
3534
|
-
if (from && to) return
|
|
3535
|
-
if (from) return
|
|
3536
|
-
if (to) return
|
|
3537
|
-
return
|
|
3764
|
+
if (from && to) return t.fromTo(from, to, net);
|
|
3765
|
+
if (from) return t.from(from, net);
|
|
3766
|
+
if (to) return t.to(to, net);
|
|
3767
|
+
return t.netOnly(net);
|
|
3538
3768
|
}
|
|
3539
3769
|
function waterfallStack(steps) {
|
|
3540
3770
|
const base = [];
|
|
@@ -3586,7 +3816,8 @@ function waterfallStepText(step, formatter, delta = false) {
|
|
|
3586
3816
|
if (step.value === null) return EMPTY_VALUE;
|
|
3587
3817
|
return step.kind === "total" && !delta ? formatter(step.value) : signedText(step.value, formatter);
|
|
3588
3818
|
}
|
|
3589
|
-
function buildWaterfallSummary(steps, formatter, title, labels, delta) {
|
|
3819
|
+
function buildWaterfallSummary(steps, formatter, title, labels, delta, locale) {
|
|
3820
|
+
const t = textOf(locale);
|
|
3590
3821
|
const real = steps.filter((s) => s.kind !== "gap");
|
|
3591
3822
|
const first = real[0];
|
|
3592
3823
|
const last = real[real.length - 1];
|
|
@@ -3594,7 +3825,7 @@ function buildWaterfallSummary(steps, formatter, title, labels, delta) {
|
|
|
3594
3825
|
const name = (s) => labelOf(s.name, labels);
|
|
3595
3826
|
const head = title ? `${title}: ` : "";
|
|
3596
3827
|
const parts = [
|
|
3597
|
-
delta ? waterfallDeltaNote(delta, formatter, labels) : real.length === 1 ? `${name(first)} ${formatter(first.end)}` : `${name(first)} ${formatter(first.end)} \u2192 ${name(last)} ${formatter(last.end)}`
|
|
3828
|
+
delta ? waterfallDeltaNote(delta, formatter, labels, locale) : real.length === 1 ? `${name(first)} ${formatter(first.end)}` : `${name(first)} ${formatter(first.end)} \u2192 ${name(last)} ${formatter(last.end)}`
|
|
3598
3829
|
];
|
|
3599
3830
|
let up;
|
|
3600
3831
|
let down;
|
|
@@ -3602,21 +3833,22 @@ function buildWaterfallSummary(steps, formatter, title, labels, delta) {
|
|
|
3602
3833
|
if (s.kind === "increase" && (!up || s.value > up.value)) up = s;
|
|
3603
3834
|
if (s.kind === "decrease" && (!down || s.value < down.value)) down = s;
|
|
3604
3835
|
}
|
|
3605
|
-
if (up) parts.push(
|
|
3606
|
-
if (down) parts.push(
|
|
3607
|
-
return `${head}${parts.join(
|
|
3836
|
+
if (up) parts.push(t.increase(name(up), signedText(up.value, formatter)));
|
|
3837
|
+
if (down) parts.push(t.decrease(name(down), signedText(down.value, formatter)));
|
|
3838
|
+
return `${head}${parts.join(t.sentenceJoin)}`;
|
|
3608
3839
|
}
|
|
3609
|
-
function waterfallDataTable(steps, names, formatter, labels, delta) {
|
|
3840
|
+
function waterfallDataTable(steps, names, formatter, labels, delta, locale) {
|
|
3841
|
+
const t = textOf(locale);
|
|
3610
3842
|
const label2 = (key) => labelOf(key, labels);
|
|
3611
3843
|
const rows = steps.map((s) => [
|
|
3612
3844
|
label2(s.name),
|
|
3613
|
-
s.kind === "total" ? delta ?
|
|
3845
|
+
s.kind === "total" ? delta ? t.net : t.total : s.value === null ? EMPTY_VALUE : signedText(s.value, formatter),
|
|
3614
3846
|
s.kind === "gap" ? EMPTY_VALUE : delta ? signedText(s.end, formatter) : formatter(s.end)
|
|
3615
3847
|
]);
|
|
3616
3848
|
const end = (e, role) => e && e.value !== null ? [[label2(e.name), role, formatter(e.value)]] : [];
|
|
3617
3849
|
return {
|
|
3618
|
-
columns: [labels?.[names.index] ??
|
|
3619
|
-
rows: delta ? [...end(delta.opening,
|
|
3850
|
+
columns: [labels?.[names.index] ?? t.item, t.change, delta ? t.cumulativeChange : t.cumulative],
|
|
3851
|
+
rows: delta ? [...end(delta.opening, t.start), ...rows, ...end(delta.closing, t.end)] : rows
|
|
3620
3852
|
};
|
|
3621
3853
|
}
|
|
3622
3854
|
var WATERFALL_BAR_SHARE = 0.45;
|
|
@@ -3698,6 +3930,7 @@ function waterfallConnectorRenderer(color) {
|
|
|
3698
3930
|
var ROW_STYLE = "display:flex;align-items:center;gap:8px;line-height:20px";
|
|
3699
3931
|
function buildWaterfallOption(config) {
|
|
3700
3932
|
const { steps, colors, polarity, labels, valueFormatter, showValues = true, showTooltip = true } = config;
|
|
3933
|
+
const t = textOf(config.locale);
|
|
3701
3934
|
const delta = config.mode === "delta";
|
|
3702
3935
|
const axisFormatter = config.axisFormatter ?? valueFormatter;
|
|
3703
3936
|
const noteWidth = config.plotWidth ? Math.max(120, config.plotWidth - 16) : void 0;
|
|
@@ -3768,7 +4001,7 @@ function buildWaterfallOption(config) {
|
|
|
3768
4001
|
if (!step) return "";
|
|
3769
4002
|
const color = escapeHtml(colorOf(step) ?? "currentColor");
|
|
3770
4003
|
const line = (name, text) => `<div style="${ROW_STYLE}"><span style="display:inline-block;width:8px;height:8px;border-radius:9999px;background:${color}"></span><span style="flex:1;opacity:.8">${escapeHtml(name)}</span><span style="font-weight:500;font-variant-numeric:tabular-nums;margin-left:12px">${escapeHtml(text)}</span></div>`;
|
|
3771
|
-
const rows = step.kind === "total" ? line(delta ?
|
|
4004
|
+
const rows = step.kind === "total" ? line(delta ? t.net : t.total, delta ? signedText(step.end, valueFormatter) : valueFormatter(step.end)) : line(t.change, waterfallStepText(step, valueFormatter)) + (step.kind === "gap" ? "" : delta ? line(t.cumulativeChange, signedText(step.end, valueFormatter)) : line(t.cumulative, valueFormatter(step.end)));
|
|
3772
4005
|
return `<div style="font-weight:500;margin-bottom:4px">${escapeHtml(labelOf(step.name, labels))}</div>${rows}`;
|
|
3773
4006
|
}
|
|
3774
4007
|
},
|
|
@@ -3838,7 +4071,7 @@ function WaterfallChartImpl({
|
|
|
3838
4071
|
mode = "total",
|
|
3839
4072
|
polarity = "higher-is-better",
|
|
3840
4073
|
labels,
|
|
3841
|
-
format
|
|
4074
|
+
format,
|
|
3842
4075
|
valueFormatter: valueFormatterProp,
|
|
3843
4076
|
showValues = true,
|
|
3844
4077
|
showTooltip = true,
|
|
@@ -3859,11 +4092,15 @@ function WaterfallChartImpl({
|
|
|
3859
4092
|
}, ref) {
|
|
3860
4093
|
const valueKey = categories[0] ?? "";
|
|
3861
4094
|
const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
|
|
3862
|
-
const
|
|
3863
|
-
const
|
|
3864
|
-
const
|
|
4095
|
+
const locale = useLocale();
|
|
4096
|
+
const valueFormatter = useMemo(() => resolveValueFormatter(valueFormatterProp, format, locale), [valueFormatterProp, format, locale]);
|
|
4097
|
+
const axisFormatter = useMemo(() => resolveAxisFormatter(valueFormatterProp, format, locale), [valueFormatterProp, format, locale]);
|
|
4098
|
+
const steps = useMemo(
|
|
4099
|
+
() => waterfallSteps(data, { index, value: valueKey, totals, mode, locale }),
|
|
4100
|
+
[data, index, valueKey, totals, mode, locale]
|
|
4101
|
+
);
|
|
3865
4102
|
const ends = useMemo(() => mode === "delta" ? waterfallDeltaEnds(data, { index, value: valueKey, totals }) : void 0, [data, index, valueKey, totals, mode]);
|
|
3866
|
-
const deltaNote = useMemo(() => ends ? waterfallDeltaNote(ends, valueFormatter, labels) : void 0, [ends, valueFormatter, labels]);
|
|
4103
|
+
const deltaNote = useMemo(() => ends ? waterfallDeltaNote(ends, valueFormatter, labels, locale) : void 0, [ends, valueFormatter, labels, locale]);
|
|
3867
4104
|
const colors = useMemo(() => {
|
|
3868
4105
|
const fills = resolveFillColors(tokens);
|
|
3869
4106
|
const [total = ""] = resolveChartColors(["chart-1"], tokens);
|
|
@@ -3893,19 +4130,21 @@ function WaterfallChartImpl({
|
|
|
3893
4130
|
chartOptions,
|
|
3894
4131
|
minValue,
|
|
3895
4132
|
maxValue,
|
|
3896
|
-
yAxisWidth
|
|
4133
|
+
yAxisWidth,
|
|
4134
|
+
locale
|
|
3897
4135
|
}),
|
|
3898
|
-
[steps, colors, polarity, labels, valueFormatter, axisFormatter, showValues, showTooltip, tokens, mode, deltaNote, plotWidth, chartOptions, minValue, maxValue, yAxisWidth]
|
|
4136
|
+
[steps, colors, polarity, labels, valueFormatter, axisFormatter, showValues, showTooltip, tokens, mode, deltaNote, plotWidth, chartOptions, minValue, maxValue, yAxisWidth, locale]
|
|
3899
4137
|
);
|
|
3900
4138
|
const dataTable = useMemo(
|
|
3901
|
-
() => waterfallDataTable(steps, { index}, valueFormatter, labels, ends),
|
|
3902
|
-
[steps, index, valueKey, valueFormatter, labels, ends]
|
|
4139
|
+
() => waterfallDataTable(steps, { index}, valueFormatter, labels, ends, locale),
|
|
4140
|
+
[steps, index, valueKey, valueFormatter, labels, ends, locale]
|
|
3903
4141
|
);
|
|
3904
4142
|
const resolvedSummary = useMemo(
|
|
3905
|
-
() => summary === "auto" ? buildWaterfallSummary(steps, valueFormatter, title, labels, ends) : summary,
|
|
3906
|
-
[summary, steps, valueFormatter, title, labels, ends]
|
|
4143
|
+
() => summary === "auto" ? buildWaterfallSummary(steps, valueFormatter, title, labels, ends, locale) : summary,
|
|
4144
|
+
[summary, steps, valueFormatter, title, labels, ends, locale]
|
|
3907
4145
|
);
|
|
3908
|
-
const
|
|
4146
|
+
const t = textOf(locale);
|
|
4147
|
+
const label2 = ariaLabel ?? t.chart(labelOf(valueKey, labels) || t.change.toLowerCase());
|
|
3909
4148
|
return /* @__PURE__ */ jsx(
|
|
3910
4149
|
ChartFrame,
|
|
3911
4150
|
{
|
|
@@ -3947,7 +4186,38 @@ function scatterPoints(data, config) {
|
|
|
3947
4186
|
}
|
|
3948
4187
|
return points;
|
|
3949
4188
|
}
|
|
3950
|
-
|
|
4189
|
+
var TEXT10 = {
|
|
4190
|
+
ja: {
|
|
4191
|
+
who: (name, value) => `${name}\uFF08${value}\uFF09`,
|
|
4192
|
+
summary: (count, y, who) => `${count}\u70B9\u3002${y}\u304C\u6700\u5927\u306A\u306E\u306F ${who}`,
|
|
4193
|
+
name: "\u540D\u524D",
|
|
4194
|
+
series: "\u7CFB\u5217",
|
|
4195
|
+
x: "\u6A2A\u8EF8",
|
|
4196
|
+
y: "\u7E26\u8EF8",
|
|
4197
|
+
size: "\u5927\u304D\u3055",
|
|
4198
|
+
pair: (y, x) => `${y}\xD7${x}`,
|
|
4199
|
+
first: (pair, count) => `${pair}\uFF08\u5148\u982D ${count} \u70B9\uFF09`,
|
|
4200
|
+
guide: (label2, axis, value) => `${label2}\uFF08${axis} ${value}\uFF09`,
|
|
4201
|
+
caption: (base, guides) => `${base}\u3002\u57FA\u6E96\u7DDA: ${guides.join("\u3001")}`,
|
|
4202
|
+
chart: (y, x) => `${y}\xD7${x}\u306E\u6563\u5E03\u56F3`
|
|
4203
|
+
},
|
|
4204
|
+
en: {
|
|
4205
|
+
who: (name, value) => `${name} (${value})`,
|
|
4206
|
+
summary: (count, y, who) => `${count === 1 ? "1 point" : `${count} points`}. Highest ${y}: ${who}`,
|
|
4207
|
+
name: "Name",
|
|
4208
|
+
series: "Series",
|
|
4209
|
+
x: "X",
|
|
4210
|
+
y: "Y",
|
|
4211
|
+
size: "Size",
|
|
4212
|
+
pair: (y, x) => `${y} \xD7 ${x}`,
|
|
4213
|
+
first: (pair, count) => `${pair} (first ${count} points)`,
|
|
4214
|
+
guide: (label2, axis, value) => `${label2} (${axis} ${value})`,
|
|
4215
|
+
caption: (base, guides) => `${base}. Reference lines: ${guides.join(", ")}`,
|
|
4216
|
+
chart: (y, x) => `Scatter plot of ${y} \xD7 ${x}`
|
|
4217
|
+
}
|
|
4218
|
+
};
|
|
4219
|
+
var textOf2 = (locale) => TEXT10[uiLanguage(resolveLocale(locale))];
|
|
4220
|
+
function scatterSeries(points, max = MAX_CHART_SERIES, otherLabel = otherSeriesLabel()) {
|
|
3951
4221
|
const order = [];
|
|
3952
4222
|
const counts = /* @__PURE__ */ new Map();
|
|
3953
4223
|
for (const p of points) {
|
|
@@ -3960,7 +4230,7 @@ function scatterSeries(points, max = MAX_CHART_SERIES) {
|
|
|
3960
4230
|
const ranked = order.map((name, at) => ({ name, at, n: counts.get(name) ?? 0 })).sort((a, b) => b.n - a.n || a.at - b.at);
|
|
3961
4231
|
const kept = new Set(ranked.slice(0, Math.max(1, max)).map((r) => r.name));
|
|
3962
4232
|
const result = order.filter((name) => kept.has(name)).map((name) => ({ name, isOther: false, points: points.filter((p) => p.series === name) }));
|
|
3963
|
-
result.push({ name:
|
|
4233
|
+
result.push({ name: otherLabel, isOther: true, points: points.filter((p) => !kept.has(p.series)) });
|
|
3964
4234
|
return result;
|
|
3965
4235
|
}
|
|
3966
4236
|
var SCATTER_FADED_OPACITY = 0.2;
|
|
@@ -3974,24 +4244,26 @@ function scatterBubbleSize(value, max) {
|
|
|
3974
4244
|
function pointTitle(point, labels) {
|
|
3975
4245
|
return labelOf(point.name || point.series, labels);
|
|
3976
4246
|
}
|
|
3977
|
-
function buildScatterSummary(points, yName, yFormatter, title, labels) {
|
|
4247
|
+
function buildScatterSummary(points, yName, yFormatter, title, labels, locale) {
|
|
3978
4248
|
if (points.length === 0) return void 0;
|
|
4249
|
+
const t = textOf2(locale);
|
|
3979
4250
|
let best = points[0];
|
|
3980
4251
|
for (const p of points) if (p.y > best.y) best = p;
|
|
3981
4252
|
const head = title ? `${title}: ` : "";
|
|
3982
|
-
const who = best.name ?
|
|
3983
|
-
return `${head}${points.length
|
|
4253
|
+
const who = best.name ? t.who(labelOf(best.name, labels), yFormatter(best.y)) : yFormatter(best.y);
|
|
4254
|
+
return `${head}${t.summary(points.length, labelOf(yName, labels), who)}`;
|
|
3984
4255
|
}
|
|
3985
4256
|
var SCATTER_TABLE_MAX_ROWS = 100;
|
|
3986
4257
|
function scatterDataTable(points, config) {
|
|
4258
|
+
const t = textOf2(config.locale);
|
|
3987
4259
|
const label2 = (key) => labelOf(key, config.labels);
|
|
3988
4260
|
const column = (key, fallback) => config.labels?.[key] ?? fallback;
|
|
3989
4261
|
const columns = [
|
|
3990
|
-
...config.index ? [column(config.index,
|
|
3991
|
-
...config.series ? [column(config.series,
|
|
3992
|
-
column(config.x,
|
|
3993
|
-
column(config.y,
|
|
3994
|
-
...config.size ? [column(config.size,
|
|
4262
|
+
...config.index ? [column(config.index, t.name)] : [],
|
|
4263
|
+
...config.series ? [column(config.series, t.series)] : [],
|
|
4264
|
+
column(config.x, t.x),
|
|
4265
|
+
column(config.y, t.y),
|
|
4266
|
+
...config.size ? [column(config.size, t.size)] : []
|
|
3995
4267
|
];
|
|
3996
4268
|
const shown = points.slice(0, SCATTER_TABLE_MAX_ROWS);
|
|
3997
4269
|
const rows = shown.map((p, i) => {
|
|
@@ -4004,14 +4276,15 @@ function scatterDataTable(points, config) {
|
|
|
4004
4276
|
];
|
|
4005
4277
|
return config.index ? cells : [String(i + 1), ...cells];
|
|
4006
4278
|
});
|
|
4007
|
-
const
|
|
4279
|
+
const pair = t.pair(label2(config.y), label2(config.x));
|
|
4280
|
+
const base = points.length > shown.length ? t.first(pair, shown.length) : pair;
|
|
4008
4281
|
const guides = (config.referenceLines ?? []).map((line) => {
|
|
4009
4282
|
const key = line.axis === "x" ? config.x : config.y;
|
|
4010
4283
|
const text = config.formatters[line.axis](line.value);
|
|
4011
|
-
return line.label ?
|
|
4284
|
+
return line.label ? t.guide(line.label, label2(key), text) : `${label2(key)} ${text}`;
|
|
4012
4285
|
});
|
|
4013
4286
|
return {
|
|
4014
|
-
caption: guides.length > 0 ?
|
|
4287
|
+
caption: guides.length > 0 ? t.caption(base, guides) : base,
|
|
4015
4288
|
columns: config.index ? columns : ["#", ...columns],
|
|
4016
4289
|
rows
|
|
4017
4290
|
};
|
|
@@ -4233,7 +4506,7 @@ function ScatterChartImpl({
|
|
|
4233
4506
|
referenceLines,
|
|
4234
4507
|
colors,
|
|
4235
4508
|
labels,
|
|
4236
|
-
format
|
|
4509
|
+
format,
|
|
4237
4510
|
xFormat,
|
|
4238
4511
|
yFormat,
|
|
4239
4512
|
sizeFormat,
|
|
@@ -4258,26 +4531,27 @@ function ScatterChartImpl({
|
|
|
4258
4531
|
...rest
|
|
4259
4532
|
}, ref) {
|
|
4260
4533
|
const { ref: frameRef, width: plotWidth, tokens } = useChartSurface(ref);
|
|
4534
|
+
const locale = useLocale();
|
|
4261
4535
|
const formatters = useMemo(
|
|
4262
4536
|
() => ({
|
|
4263
|
-
x: resolveValueFormatter(valueFormatter, xFormat ??
|
|
4264
|
-
y: resolveValueFormatter(valueFormatter, yFormat ??
|
|
4265
|
-
size: resolveValueFormatter(valueFormatter, sizeFormat ??
|
|
4537
|
+
x: resolveValueFormatter(valueFormatter, xFormat ?? format, locale),
|
|
4538
|
+
y: resolveValueFormatter(valueFormatter, yFormat ?? format, locale),
|
|
4539
|
+
size: resolveValueFormatter(valueFormatter, sizeFormat ?? format, locale)
|
|
4266
4540
|
}),
|
|
4267
|
-
[valueFormatter, xFormat, yFormat, sizeFormat,
|
|
4541
|
+
[valueFormatter, xFormat, yFormat, sizeFormat, format, locale]
|
|
4268
4542
|
);
|
|
4269
4543
|
const axisFormatters = useMemo(
|
|
4270
4544
|
() => ({
|
|
4271
|
-
x: resolveAxisFormatter(valueFormatter, xFormat ??
|
|
4272
|
-
y: resolveAxisFormatter(valueFormatter, yFormat ??
|
|
4545
|
+
x: resolveAxisFormatter(valueFormatter, xFormat ?? format, locale),
|
|
4546
|
+
y: resolveAxisFormatter(valueFormatter, yFormat ?? format, locale)
|
|
4273
4547
|
}),
|
|
4274
|
-
[valueFormatter, xFormat, yFormat,
|
|
4548
|
+
[valueFormatter, xFormat, yFormat, format, locale]
|
|
4275
4549
|
);
|
|
4276
4550
|
const points = useMemo(
|
|
4277
4551
|
() => scatterPoints(data, { x, y, size, index, series: seriesKey, labelKey }),
|
|
4278
4552
|
[data, x, y, size, index, seriesKey, labelKey]
|
|
4279
4553
|
);
|
|
4280
|
-
const series = useMemo(() => scatterSeries(points), [points]);
|
|
4554
|
+
const series = useMemo(() => scatterSeries(points, void 0, otherSeriesLabel(locale)), [points, locale]);
|
|
4281
4555
|
const palette = useMemo(
|
|
4282
4556
|
() => resolveChartColors(scatterSeriesColors(series, colors).map(chartFillName), tokens),
|
|
4283
4557
|
[series, colors, tokens]
|
|
@@ -4313,14 +4587,14 @@ function ScatterChartImpl({
|
|
|
4313
4587
|
[series, palette, x, y, size, seriesKey, seriesLabel, highlightList, referenceLines, labelKey, tokens, labels, formatters, axisFormatters, fitToData, showLegend, showTooltip, actions, plotWidth, chartOptions, minValue, maxValue, xMinValue, xMaxValue]
|
|
4314
4588
|
);
|
|
4315
4589
|
const dataTable = useMemo(
|
|
4316
|
-
() => scatterDataTable(points, { x, y, size, index: index ?? labelKey, series: seriesKey, formatters, labels, referenceLines }),
|
|
4317
|
-
[points, x, y, size, index, labelKey, seriesKey, formatters, labels, referenceLines]
|
|
4590
|
+
() => scatterDataTable(points, { x, y, size, index: index ?? labelKey, series: seriesKey, formatters, labels, referenceLines, locale }),
|
|
4591
|
+
[points, x, y, size, index, labelKey, seriesKey, formatters, labels, referenceLines, locale]
|
|
4318
4592
|
);
|
|
4319
4593
|
const resolvedSummary = useMemo(
|
|
4320
|
-
() => summary === "auto" ? buildScatterSummary(points, y, formatters.y, title, labels) : summary,
|
|
4321
|
-
[summary, points, y, formatters, title, labels]
|
|
4594
|
+
() => summary === "auto" ? buildScatterSummary(points, y, formatters.y, title, labels, locale) : summary,
|
|
4595
|
+
[summary, points, y, formatters, title, labels, locale]
|
|
4322
4596
|
);
|
|
4323
|
-
const label2 = ariaLabel ??
|
|
4597
|
+
const label2 = ariaLabel ?? textOf2(locale).chart(labelOf(y, labels), labelOf(x, labels));
|
|
4324
4598
|
return /* @__PURE__ */ jsx(
|
|
4325
4599
|
ChartFrame,
|
|
4326
4600
|
{
|
|
@@ -4345,7 +4619,12 @@ ScatterChart.displayName = "ScatterChart";
|
|
|
4345
4619
|
function legendColors(categories, colors) {
|
|
4346
4620
|
return seriesColorsFor(categories, colors, CHART_OTHER_COLOR).map((color) => chartFillToCss(color));
|
|
4347
4621
|
}
|
|
4348
|
-
var
|
|
4622
|
+
var TEXT11 = {
|
|
4623
|
+
ja: { legend: "\u51E1\u4F8B" },
|
|
4624
|
+
en: { legend: "Legend" }
|
|
4625
|
+
};
|
|
4626
|
+
var Legend = forwardRef(function Legend2({ categories, colors, labels, layout = "horizontal", ariaLabel, className }, ref) {
|
|
4627
|
+
const t = TEXT11[uiLanguage(useLocale())];
|
|
4349
4628
|
if (categories.length === 0) return null;
|
|
4350
4629
|
const swatches = legendColors(categories, colors);
|
|
4351
4630
|
return /* @__PURE__ */ jsx(
|
|
@@ -4354,7 +4633,7 @@ var Legend = forwardRef(function Legend2({ categories, colors, labels, layout =
|
|
|
4354
4633
|
ref,
|
|
4355
4634
|
"data-slot": "legend",
|
|
4356
4635
|
"data-layout": layout,
|
|
4357
|
-
"aria-label": ariaLabel,
|
|
4636
|
+
"aria-label": ariaLabel ?? t.legend,
|
|
4358
4637
|
className: cn("m-0 flex list-none gap-x-4 gap-y-1 p-0 text-xs", layout === "vertical" ? "flex-col" : "flex-row flex-wrap", className),
|
|
4359
4638
|
children: categories.map((category, i) => /* @__PURE__ */ jsxs("li", { "data-slot": "legend-item", className: "flex min-w-0 items-center gap-1.5", children: [
|
|
4360
4639
|
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "size-2.5 shrink-0 rounded-[2px]", style: { background: swatches[i] } }),
|
|
@@ -4452,9 +4731,27 @@ var funnelConversionVariants = cva("flex items-center text-muted-foreground", {
|
|
|
4452
4731
|
direction: "vertical"
|
|
4453
4732
|
}
|
|
4454
4733
|
});
|
|
4455
|
-
function resolveFunnelFormatter(valueFormatter, formatValue2,
|
|
4456
|
-
return resolveValueFormatter(valueFormatter ?? formatValue2,
|
|
4734
|
+
function resolveFunnelFormatter(valueFormatter, formatValue2, format, locale) {
|
|
4735
|
+
return resolveValueFormatter(valueFormatter ?? formatValue2, format, locale);
|
|
4457
4736
|
}
|
|
4737
|
+
var TEXT12 = {
|
|
4738
|
+
ja: {
|
|
4739
|
+
step: "\u30B9\u30C6\u30C3\u30D7",
|
|
4740
|
+
value: "\u5024",
|
|
4741
|
+
previous: "\u524D\u671F",
|
|
4742
|
+
previousHeader: "\u524D\u671F",
|
|
4743
|
+
change: (label2, points) => `(${label2}\u6BD4 ${points})`,
|
|
4744
|
+
funnel: "\u30D5\u30A1\u30CD\u30EB"
|
|
4745
|
+
},
|
|
4746
|
+
en: {
|
|
4747
|
+
step: "Step",
|
|
4748
|
+
value: "Value",
|
|
4749
|
+
previous: "prior period",
|
|
4750
|
+
previousHeader: "Prior period",
|
|
4751
|
+
change: (label2, points) => `(vs. ${label2} ${points})`,
|
|
4752
|
+
funnel: "Funnel"
|
|
4753
|
+
}
|
|
4754
|
+
};
|
|
4458
4755
|
function lowestConversionStep(values) {
|
|
4459
4756
|
if (values.length < 3) return -1;
|
|
4460
4757
|
let lowest = -1;
|
|
@@ -4536,7 +4833,9 @@ function FunnelStepsImpl({
|
|
|
4536
4833
|
}, ref) {
|
|
4537
4834
|
const [mounted, setMounted] = useState(false);
|
|
4538
4835
|
const isHorizontal = direction === "horizontal";
|
|
4539
|
-
const
|
|
4836
|
+
const locale = useLocale();
|
|
4837
|
+
const t = TEXT12[uiLanguage(locale)];
|
|
4838
|
+
const format = resolveFunnelFormatter(valueFormatter, formatValue2, valueFormat, locale);
|
|
4540
4839
|
useEffect(() => {
|
|
4541
4840
|
if (animate) setMounted(true);
|
|
4542
4841
|
}, [animate]);
|
|
@@ -4548,15 +4847,19 @@ function FunnelStepsImpl({
|
|
|
4548
4847
|
const maxValue = steps.length > 0 ? steps[0].value : 0;
|
|
4549
4848
|
const values = steps.map((s) => s.value);
|
|
4550
4849
|
const previous = comparison?.values;
|
|
4551
|
-
const comparisonLabel2 = comparison?.label ??
|
|
4850
|
+
const comparisonLabel2 = comparison?.label ?? t.previous;
|
|
4552
4851
|
const showRates = showConversion || previous !== void 0;
|
|
4553
4852
|
const focus = !showRates ? -1 : previous ? worstChangeStep(values, previous) : lowestConversionStep(values);
|
|
4554
4853
|
const dataTable = chartDataTable(
|
|
4555
4854
|
steps.map((step, i) => ({ label: step.label, value: step.value, previous: previous?.[i] ?? null })),
|
|
4556
4855
|
"label",
|
|
4557
4856
|
previous ? ["value", "previous"] : ["value"],
|
|
4558
|
-
|
|
4559
|
-
{
|
|
4857
|
+
format,
|
|
4858
|
+
{
|
|
4859
|
+
label: labels?.[index] ?? t.step,
|
|
4860
|
+
value: categories?.[0] && labels?.[categories[0]] || t.value,
|
|
4861
|
+
previous: comparison?.label ?? t.previousHeader
|
|
4862
|
+
}
|
|
4560
4863
|
);
|
|
4561
4864
|
const list = /* @__PURE__ */ jsx("div", { "data-slot": "funnel-steps", role: "list", className: funnelStepsVariants({ size, direction }), ...props, children: steps.map((step, index2) => {
|
|
4562
4865
|
const percentage = maxValue > 0 ? step.value / maxValue * 100 : 0;
|
|
@@ -4582,7 +4885,7 @@ function FunnelStepsImpl({
|
|
|
4582
4885
|
{
|
|
4583
4886
|
role: "listitem",
|
|
4584
4887
|
className: "flex min-w-0 flex-1 flex-col items-center gap-1",
|
|
4585
|
-
"aria-label": `${step.label}: ${
|
|
4888
|
+
"aria-label": `${step.label}: ${format(step.value)}`,
|
|
4586
4889
|
children: [
|
|
4587
4890
|
/* @__PURE__ */ jsx(
|
|
4588
4891
|
"span",
|
|
@@ -4592,7 +4895,7 @@ function FunnelStepsImpl({
|
|
|
4592
4895
|
"text-muted-foreground tabular-nums",
|
|
4593
4896
|
size === "sm" ? "text-xs" : "text-sm"
|
|
4594
4897
|
),
|
|
4595
|
-
children:
|
|
4898
|
+
children: format(step.value)
|
|
4596
4899
|
}
|
|
4597
4900
|
),
|
|
4598
4901
|
/* @__PURE__ */ jsx("div", { className: funnelBarContainerHorizontalVariants({ size }), children: /* @__PURE__ */ jsx(
|
|
@@ -4624,10 +4927,10 @@ function FunnelStepsImpl({
|
|
|
4624
4927
|
)
|
|
4625
4928
|
]
|
|
4626
4929
|
}
|
|
4627
|
-
) : /* @__PURE__ */ jsxs("div", { role: "listitem", "aria-label": `${step.label}: ${
|
|
4930
|
+
) : /* @__PURE__ */ jsxs("div", { role: "listitem", "aria-label": `${step.label}: ${format(step.value)}`, children: [
|
|
4628
4931
|
/* @__PURE__ */ jsxs("div", { className: funnelLabelVariants({ size }), children: [
|
|
4629
4932
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: step.label }),
|
|
4630
|
-
/* @__PURE__ */ jsx("span", { "data-slot": "funnel-value", className: "tabular-nums", children:
|
|
4933
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "funnel-value", className: "tabular-nums", children: format(step.value) })
|
|
4631
4934
|
] }),
|
|
4632
4935
|
/* @__PURE__ */ jsx("div", { className: "relative w-full overflow-hidden rounded-sm bg-muted", children: /* @__PURE__ */ jsx(
|
|
4633
4936
|
"div",
|
|
@@ -4651,13 +4954,7 @@ function FunnelStepsImpl({
|
|
|
4651
4954
|
children: [
|
|
4652
4955
|
"\u2192 ",
|
|
4653
4956
|
computeConversionRate(steps[index2 + 1].value, step.value),
|
|
4654
|
-
previous && /* @__PURE__ */
|
|
4655
|
-
"(",
|
|
4656
|
-
comparisonLabel2,
|
|
4657
|
-
"\u6BD4 ",
|
|
4658
|
-
formatPoints(conversionChange(values, previous, index2 + 1)),
|
|
4659
|
-
")"
|
|
4660
|
-
] })
|
|
4957
|
+
previous && /* @__PURE__ */ jsx("span", { "data-slot": "funnel-change", className: "ml-1 tabular-nums", children: t.change(comparisonLabel2, formatPoints(conversionChange(values, previous, index2 + 1), locale)) })
|
|
4661
4958
|
]
|
|
4662
4959
|
}
|
|
4663
4960
|
) })
|
|
@@ -4674,7 +4971,7 @@ function FunnelStepsImpl({
|
|
|
4674
4971
|
emptyState,
|
|
4675
4972
|
height: ready ? "auto" : FRAME_HEIGHT[size ?? "md"],
|
|
4676
4973
|
variant: "list",
|
|
4677
|
-
ariaLabel: ariaLabel ??
|
|
4974
|
+
ariaLabel: ariaLabel ?? t.funnel,
|
|
4678
4975
|
plotRole: "group",
|
|
4679
4976
|
dataTable,
|
|
4680
4977
|
className,
|
|
@@ -4791,8 +5088,26 @@ function heatmapCellFontSize(plotWidth, columns, rowNames, texts) {
|
|
|
4791
5088
|
if (text + HEATMAP_CELL_PADDING <= cell) return 12;
|
|
4792
5089
|
return text * 10 / 12 + HEATMAP_CELL_PADDING <= cell ? 10 : null;
|
|
4793
5090
|
}
|
|
5091
|
+
var TEXT13 = {
|
|
5092
|
+
ja: {
|
|
5093
|
+
join: "\u30FB",
|
|
5094
|
+
flagged: "\u8981\u6CE8\u610F",
|
|
5095
|
+
item: "\u9805\u76EE",
|
|
5096
|
+
top: (y, x, value) => `\u6700\u5927\u306F ${y} ${x} \u306E ${value}`,
|
|
5097
|
+
chart: (y, x) => `${y}\xD7${x}\u306E\u30D2\u30FC\u30C8\u30DE\u30C3\u30D7`
|
|
5098
|
+
},
|
|
5099
|
+
en: {
|
|
5100
|
+
join: ", ",
|
|
5101
|
+
flagged: "Needs attention",
|
|
5102
|
+
item: "Item",
|
|
5103
|
+
top: (y, x, value) => `Highest: ${y} ${x} (${value})`,
|
|
5104
|
+
chart: (y, x) => `Heatmap of ${y} \xD7 ${x}`
|
|
5105
|
+
}
|
|
5106
|
+
};
|
|
5107
|
+
var textOf3 = (locale) => TEXT13[uiLanguage(resolveLocale(locale))];
|
|
4794
5108
|
function buildHeatmapOption(config) {
|
|
4795
5109
|
const { model, labels, valueFormatter } = config;
|
|
5110
|
+
const t = textOf3(config.locale);
|
|
4796
5111
|
const label2 = (key) => labels?.[key] ?? key;
|
|
4797
5112
|
const present = model.cells.filter((c) => c.value !== null);
|
|
4798
5113
|
const missing = model.cells.filter((c) => c.value === null);
|
|
@@ -4806,9 +5121,9 @@ function buildHeatmapOption(config) {
|
|
|
4806
5121
|
const extras = (config.details ?? []).map((key) => {
|
|
4807
5122
|
const n = cell.row ? toChartNumber(cell.row[key]) : null;
|
|
4808
5123
|
return `${escapeHtml2(label2(key))} ${n === null ? EMPTY_VALUE : escapeHtml2(valueFormatter(n))}`;
|
|
4809
|
-
}).join(
|
|
4810
|
-
const flag = cell.flagged ?
|
|
4811
|
-
return `${head} ${main}${extras ?
|
|
5124
|
+
}).join(t.join);
|
|
5125
|
+
const flag = cell.flagged ? `${t.join}${t.flagged}` : "";
|
|
5126
|
+
return `${head} ${main}${extras ? `${t.join}${extras}` : ""}${flag}`;
|
|
4812
5127
|
};
|
|
4813
5128
|
const cellFont = config.plotWidth ? heatmapCellFontSize(
|
|
4814
5129
|
config.plotWidth,
|
|
@@ -4906,7 +5221,7 @@ function mergeDeep(a, b) {
|
|
|
4906
5221
|
}
|
|
4907
5222
|
return out;
|
|
4908
5223
|
}
|
|
4909
|
-
function heatmapDataTable(model, names, formatter, labels) {
|
|
5224
|
+
function heatmapDataTable(model, names, formatter, labels, locale) {
|
|
4910
5225
|
const label2 = (key) => labels?.[key] ?? key;
|
|
4911
5226
|
const rows = model.ys.map((yk, yi) => [
|
|
4912
5227
|
label2(yk),
|
|
@@ -4915,15 +5230,15 @@ function heatmapDataTable(model, names, formatter, labels) {
|
|
|
4915
5230
|
return v === null || v === void 0 ? EMPTY_VALUE : formatter(v);
|
|
4916
5231
|
})
|
|
4917
5232
|
]);
|
|
4918
|
-
return { caption: `${label2(names.y)}\xD7${label2(names.x)}`, columns: [labels?.[names.y] ??
|
|
5233
|
+
return { caption: `${label2(names.y)}\xD7${label2(names.x)}`, columns: [labels?.[names.y] ?? textOf3(locale).item, ...model.xs.map(label2)], rows };
|
|
4919
5234
|
}
|
|
4920
|
-
function buildHeatmapSummary(model, formatter, title, labels) {
|
|
5235
|
+
function buildHeatmapSummary(model, formatter, title, labels, locale) {
|
|
4921
5236
|
let best;
|
|
4922
5237
|
for (const cell of model.cells) if (cell.value !== null && (!best || cell.value > best.value)) best = cell;
|
|
4923
5238
|
if (!best) return void 0;
|
|
4924
5239
|
const label2 = (key) => labels?.[key] ?? key;
|
|
4925
5240
|
const head = title ? `${title}: ` : "";
|
|
4926
|
-
return `${head}
|
|
5241
|
+
return `${head}${textOf3(locale).top(label2(model.ys[best.yi]), label2(model.xs[best.xi]), formatter(best.value))}`;
|
|
4927
5242
|
}
|
|
4928
5243
|
function colorsFor(tokens, tone) {
|
|
4929
5244
|
const [color = "", flag = "", muted = ""] = resolveChartColors([tone, "negative", "var(--muted-foreground)"], tokens);
|
|
@@ -4938,7 +5253,7 @@ function HeatmapImpl({
|
|
|
4938
5253
|
xLabels,
|
|
4939
5254
|
yLabels,
|
|
4940
5255
|
labels,
|
|
4941
|
-
format
|
|
5256
|
+
format,
|
|
4942
5257
|
valueFormatter,
|
|
4943
5258
|
tone = "chart-1",
|
|
4944
5259
|
scale,
|
|
@@ -4962,7 +5277,8 @@ function HeatmapImpl({
|
|
|
4962
5277
|
...rest
|
|
4963
5278
|
}, ref) {
|
|
4964
5279
|
const { ref: frameRef, surface, width: plotWidth, tokens } = useChartSurface(ref);
|
|
4965
|
-
const
|
|
5280
|
+
const locale = useLocale();
|
|
5281
|
+
const formatter = useMemo(() => resolveValueFormatter(valueFormatter, format ?? "number", locale), [valueFormatter, format, locale]);
|
|
4966
5282
|
const model = useMemo(
|
|
4967
5283
|
() => buildHeatmapModel({ data, x, y, value, xLabels, yLabels, flag, scale, minValue, maxValue }),
|
|
4968
5284
|
[data, x, y, value, xLabels, yLabels, flag, scale?.min, scale?.max, minValue, maxValue]
|
|
@@ -4983,16 +5299,17 @@ function HeatmapImpl({
|
|
|
4983
5299
|
showValues,
|
|
4984
5300
|
showTooltip,
|
|
4985
5301
|
plotWidth,
|
|
4986
|
-
chartOptions
|
|
5302
|
+
chartOptions,
|
|
5303
|
+
locale
|
|
4987
5304
|
}),
|
|
4988
|
-
[model, x, y, value, colors, surface, tokens, labels, formatter, details, showValues, showTooltip, plotWidth, chartOptions]
|
|
5305
|
+
[model, x, y, value, colors, surface, tokens, labels, formatter, details, showValues, showTooltip, plotWidth, chartOptions, locale]
|
|
4989
5306
|
);
|
|
4990
|
-
const dataTable = useMemo(() => heatmapDataTable(model, { x, y }, formatter, labels), [model, x, y, formatter, labels]);
|
|
5307
|
+
const dataTable = useMemo(() => heatmapDataTable(model, { x, y }, formatter, labels, locale), [model, x, y, formatter, labels, locale]);
|
|
4991
5308
|
const resolvedSummary = useMemo(
|
|
4992
|
-
() => summary === "auto" ? buildHeatmapSummary(model, formatter, title, labels) : summary,
|
|
4993
|
-
[summary, model, formatter, title, labels]
|
|
5309
|
+
() => summary === "auto" ? buildHeatmapSummary(model, formatter, title, labels, locale) : summary,
|
|
5310
|
+
[summary, model, formatter, title, labels, locale]
|
|
4994
5311
|
);
|
|
4995
|
-
const label2 = ariaLabel ??
|
|
5312
|
+
const label2 = ariaLabel ?? textOf3(locale).chart(labels?.[y] ?? y, labels?.[x] ?? x);
|
|
4996
5313
|
const legend = showLegend ? /* @__PURE__ */ jsx(HeatmapLegend, { model, formatter, tone }) : null;
|
|
4997
5314
|
return /* @__PURE__ */ jsx(
|
|
4998
5315
|
ChartFrame,
|
|
@@ -5030,31 +5347,68 @@ function HeatmapLegend({
|
|
|
5030
5347
|
}
|
|
5031
5348
|
var Heatmap = forwardRef(HeatmapImpl);
|
|
5032
5349
|
Heatmap.displayName = "Heatmap";
|
|
5033
|
-
|
|
5034
|
-
|
|
5350
|
+
var TEXT14 = {
|
|
5351
|
+
ja: {
|
|
5352
|
+
tones: { positive: "\u826F\u597D", warning: "\u6CE8\u610F", negative: "\u8981\u5BFE\u5FDC", neutral: "\u4E2D\u7ACB" },
|
|
5353
|
+
toneNote: (label2) => `\uFF08${label2}\uFF09`,
|
|
5354
|
+
selectAll: "\u5168\u3066\u9078\u629E",
|
|
5355
|
+
selectRow: "\u884C\u3092\u9078\u629E",
|
|
5356
|
+
trend: (points, first, last, min, max) => `${points}\u70B9\u306E\u63A8\u79FB\u3001${first}\u304B\u3089${last}\u3001\u6700\u5C0F${min}\u3001\u6700\u5927${max}`,
|
|
5357
|
+
noData: "\u30C7\u30FC\u30BF\u304C\u3042\u308A\u307E\u305B\u3093",
|
|
5358
|
+
pageSize: (size) => `${size}\u4EF6`,
|
|
5359
|
+
range: (total, start, end) => `${total}\u4EF6\u4E2D ${start} - ${end} \u3092\u8868\u793A`,
|
|
5360
|
+
first: "\u6700\u521D",
|
|
5361
|
+
previous: "\u524D\u3078",
|
|
5362
|
+
next: "\u6B21\u3078",
|
|
5363
|
+
last: "\u6700\u5F8C",
|
|
5364
|
+
columns: "\u8868\u793A\u3059\u308B\u5217",
|
|
5365
|
+
exportCsv: "CSV \u3092\u66F8\u304D\u51FA\u3059"
|
|
5366
|
+
},
|
|
5367
|
+
en: {
|
|
5368
|
+
tones: { positive: "Good", warning: "Caution", negative: "Needs action", neutral: "Neutral" },
|
|
5369
|
+
toneNote: (label2) => ` (${label2})`,
|
|
5370
|
+
selectAll: "Select all",
|
|
5371
|
+
selectRow: "Select row",
|
|
5372
|
+
trend: (points, first, last, min, max) => `Trend over ${points} points: ${first} to ${last}, min ${min}, max ${max}`,
|
|
5373
|
+
noData: "No results.",
|
|
5374
|
+
pageSize: (size) => `${size} / page`,
|
|
5375
|
+
range: (total, start, end) => `Showing ${start}\u2013${end} of ${total}`,
|
|
5376
|
+
first: "First",
|
|
5377
|
+
previous: "Previous",
|
|
5378
|
+
next: "Next",
|
|
5379
|
+
last: "Last",
|
|
5380
|
+
columns: "Columns",
|
|
5381
|
+
exportCsv: "Export CSV"
|
|
5382
|
+
}
|
|
5383
|
+
};
|
|
5384
|
+
var useText = () => TEXT14[uiLanguage(useLocale())];
|
|
5385
|
+
function resolveFormat(format, row) {
|
|
5386
|
+
return typeof format === "function" ? format(row) : format;
|
|
5035
5387
|
}
|
|
5036
5388
|
function isMissingCell(value) {
|
|
5037
5389
|
return value === null || value === void 0 || value === "" || typeof value === "number" && Number.isNaN(value);
|
|
5038
5390
|
}
|
|
5039
|
-
function formatCellText(value, row, meta) {
|
|
5391
|
+
function formatCellText(value, row, meta, locale) {
|
|
5040
5392
|
if (isMissingCell(value)) return meta.nullLabel ?? EMPTY_VALUE;
|
|
5041
5393
|
if (meta.dateFormat && (value instanceof Date || typeof value === "string" || typeof value === "number")) {
|
|
5042
|
-
const text = formatDate(value, meta.dateFormat,
|
|
5394
|
+
const text = formatDate(value, meta.dateFormat, locale, { timeZone: meta.timeZone });
|
|
5043
5395
|
return text === EMPTY_VALUE ? String(value) : text;
|
|
5044
5396
|
}
|
|
5045
5397
|
if (typeof value !== "number") return String(value);
|
|
5046
|
-
return formatValue(value, resolveFormat(meta.format, row));
|
|
5398
|
+
return formatValue(value, resolveFormat(meta.format, row), locale);
|
|
5047
5399
|
}
|
|
5048
5400
|
var THRESHOLD_TONE_STYLES = {
|
|
5049
|
-
positive: { Icon: CircleCheck, text: "text-positive"
|
|
5050
|
-
warning: { Icon: TriangleAlert, text: "text-warning"
|
|
5051
|
-
negative: { Icon: CircleX, text: "text-negative"
|
|
5052
|
-
neutral: { Icon: Minus, text: "text-neutral"
|
|
5401
|
+
positive: { Icon: CircleCheck, text: "text-positive" },
|
|
5402
|
+
warning: { Icon: TriangleAlert, text: "text-warning" },
|
|
5403
|
+
negative: { Icon: CircleX, text: "text-negative" },
|
|
5404
|
+
neutral: { Icon: Minus, text: "text-neutral" }
|
|
5053
5405
|
};
|
|
5054
5406
|
function ThresholdCell({ value, text, thresholds }) {
|
|
5407
|
+
const t = useText();
|
|
5055
5408
|
const tone = typeof value === "number" ? toneForValue(value, thresholds) : void 0;
|
|
5056
5409
|
if (!tone) return /* @__PURE__ */ jsx("div", { className: "text-right tabular-nums", children: text });
|
|
5057
|
-
const { Icon, text: toneClass
|
|
5410
|
+
const { Icon, text: toneClass } = THRESHOLD_TONE_STYLES[tone];
|
|
5411
|
+
const label2 = t.tones[tone];
|
|
5058
5412
|
return /* @__PURE__ */ jsxs(
|
|
5059
5413
|
"div",
|
|
5060
5414
|
{
|
|
@@ -5064,11 +5418,7 @@ function ThresholdCell({ value, text, thresholds }) {
|
|
|
5064
5418
|
children: [
|
|
5065
5419
|
/* @__PURE__ */ jsx(Icon, { className: "size-3.5 shrink-0", "aria-hidden": "true" }),
|
|
5066
5420
|
/* @__PURE__ */ jsx("span", { children: text }),
|
|
5067
|
-
/* @__PURE__ */
|
|
5068
|
-
"\uFF08",
|
|
5069
|
-
label2,
|
|
5070
|
-
"\uFF09"
|
|
5071
|
-
] })
|
|
5421
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t.toneNote(label2) })
|
|
5072
5422
|
]
|
|
5073
5423
|
}
|
|
5074
5424
|
);
|
|
@@ -5123,6 +5473,8 @@ function DataTable({
|
|
|
5123
5473
|
className,
|
|
5124
5474
|
children
|
|
5125
5475
|
}) {
|
|
5476
|
+
const locale = useLocale();
|
|
5477
|
+
const t = TEXT14[uiLanguage(locale)];
|
|
5126
5478
|
const [sorting, setSorting] = useControlledState(sortingProp, [], onSortingChange);
|
|
5127
5479
|
const [columnFilters, setColumnFilters] = useControlledState(
|
|
5128
5480
|
columnFiltersProp,
|
|
@@ -5161,7 +5513,7 @@ function DataTable({
|
|
|
5161
5513
|
...column,
|
|
5162
5514
|
cell: ({ row, getValue }) => {
|
|
5163
5515
|
const value = getValue();
|
|
5164
|
-
const text = formatCellText(value, row.original, meta2 ?? {});
|
|
5516
|
+
const text = formatCellText(value, row.original, meta2 ?? {}, locale);
|
|
5165
5517
|
if (thresholds) return /* @__PURE__ */ jsx(ThresholdCell, { value, text, thresholds });
|
|
5166
5518
|
if (aligned) return /* @__PURE__ */ jsx("div", { className: "text-right tabular-nums", children: text });
|
|
5167
5519
|
if (meta2?.dateFormat) return /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: text });
|
|
@@ -5178,7 +5530,7 @@ function DataTable({
|
|
|
5178
5530
|
checked: table2.getIsAllPageRowsSelected(),
|
|
5179
5531
|
indeterminate: table2.getIsSomePageRowsSelected(),
|
|
5180
5532
|
onCheckedChange: (checked) => table2.toggleAllPageRowsSelected(checked),
|
|
5181
|
-
"aria-label":
|
|
5533
|
+
"aria-label": t.selectAll
|
|
5182
5534
|
}
|
|
5183
5535
|
),
|
|
5184
5536
|
cell: ({ row }) => /* @__PURE__ */ jsx(
|
|
@@ -5186,14 +5538,14 @@ function DataTable({
|
|
|
5186
5538
|
{
|
|
5187
5539
|
checked: row.getIsSelected(),
|
|
5188
5540
|
onCheckedChange: (checked) => row.toggleSelected(checked),
|
|
5189
|
-
"aria-label":
|
|
5541
|
+
"aria-label": t.selectRow
|
|
5190
5542
|
}
|
|
5191
5543
|
),
|
|
5192
5544
|
enableSorting: false,
|
|
5193
5545
|
enableHiding: false
|
|
5194
5546
|
};
|
|
5195
5547
|
return [selectionColumn, ...formatted];
|
|
5196
|
-
}, [columns, enableRowSelection]);
|
|
5548
|
+
}, [columns, enableRowSelection, locale, t]);
|
|
5197
5549
|
const autoResetPage = enablePagination && pageCount === void 0 && rowCount === void 0;
|
|
5198
5550
|
const resetKey = useRef(null);
|
|
5199
5551
|
useEffect(() => {
|
|
@@ -5359,6 +5711,7 @@ function SortIcon({ sorted }) {
|
|
|
5359
5711
|
var DataTableContent = forwardRef(
|
|
5360
5712
|
({ className, ...props }, ref) => {
|
|
5361
5713
|
const { table, visibleColumnCount, isLoading, enablePagination } = useDataTable();
|
|
5714
|
+
const t = useText();
|
|
5362
5715
|
const { comparisonOf, comparisonIds } = pairComparisons(table.getVisibleLeafColumns());
|
|
5363
5716
|
return /* @__PURE__ */ jsx(
|
|
5364
5717
|
"div",
|
|
@@ -5439,7 +5792,7 @@ var DataTableContent = forwardRef(
|
|
|
5439
5792
|
{
|
|
5440
5793
|
colSpan: visibleColumnCount,
|
|
5441
5794
|
className: "h-24 text-center text-muted-foreground",
|
|
5442
|
-
children:
|
|
5795
|
+
children: t.noData
|
|
5443
5796
|
}
|
|
5444
5797
|
) }) })
|
|
5445
5798
|
] })
|
|
@@ -5451,6 +5804,7 @@ DataTableContent.displayName = "DataTableContent";
|
|
|
5451
5804
|
var DataTablePagination = forwardRef(
|
|
5452
5805
|
({ pageSizeOptions = [10, 20, 50], className, ...props }, ref) => {
|
|
5453
5806
|
const { table, isLoading } = useDataTable();
|
|
5807
|
+
const t = useText();
|
|
5454
5808
|
const totalRows = table.options.rowCount !== void 0 ? table.getRowCount() : table.getFilteredRowModel().rows.length;
|
|
5455
5809
|
const currentPageSize = table.getState().pagination.pageSize;
|
|
5456
5810
|
const currentPageIndex = table.getState().pagination.pageIndex;
|
|
@@ -5458,7 +5812,7 @@ var DataTablePagination = forwardRef(
|
|
|
5458
5812
|
const rangeEnd = Math.min((currentPageIndex + 1) * currentPageSize, totalRows);
|
|
5459
5813
|
const pageSizeItems = pageSizeOptions.map((size) => ({
|
|
5460
5814
|
value: String(size),
|
|
5461
|
-
label:
|
|
5815
|
+
label: t.pageSize(size)
|
|
5462
5816
|
}));
|
|
5463
5817
|
return /* @__PURE__ */ jsxs(
|
|
5464
5818
|
"div",
|
|
@@ -5470,14 +5824,7 @@ var DataTablePagination = forwardRef(
|
|
|
5470
5824
|
...props,
|
|
5471
5825
|
children: [
|
|
5472
5826
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
5473
|
-
/* @__PURE__ */
|
|
5474
|
-
totalRows,
|
|
5475
|
-
"\u4EF6\u4E2D ",
|
|
5476
|
-
rangeStart,
|
|
5477
|
-
" - ",
|
|
5478
|
-
rangeEnd,
|
|
5479
|
-
" \u3092\u8868\u793A"
|
|
5480
|
-
] }),
|
|
5827
|
+
/* @__PURE__ */ jsx("span", { children: t.range(totalRows, rangeStart, rangeEnd) }),
|
|
5481
5828
|
/* @__PURE__ */ jsxs(
|
|
5482
5829
|
Select,
|
|
5483
5830
|
{
|
|
@@ -5485,7 +5832,7 @@ var DataTablePagination = forwardRef(
|
|
|
5485
5832
|
value: String(currentPageSize),
|
|
5486
5833
|
onValueChange: (value) => table.setPageSize(Number(value)),
|
|
5487
5834
|
children: [
|
|
5488
|
-
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-[80px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
5835
|
+
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "min-w-[80px]", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
5489
5836
|
/* @__PURE__ */ jsx(SelectContent, { children: pageSizeItems.map((item) => /* @__PURE__ */ jsx(SelectItem, { value: item.value, children: item.label }, item.value)) })
|
|
5490
5837
|
]
|
|
5491
5838
|
}
|
|
@@ -5499,7 +5846,7 @@ var DataTablePagination = forwardRef(
|
|
|
5499
5846
|
size: "sm",
|
|
5500
5847
|
onClick: () => table.firstPage(),
|
|
5501
5848
|
disabled: isLoading || !table.getCanPreviousPage(),
|
|
5502
|
-
children:
|
|
5849
|
+
children: t.first
|
|
5503
5850
|
}
|
|
5504
5851
|
),
|
|
5505
5852
|
/* @__PURE__ */ jsx(
|
|
@@ -5509,7 +5856,7 @@ var DataTablePagination = forwardRef(
|
|
|
5509
5856
|
size: "sm",
|
|
5510
5857
|
onClick: () => table.previousPage(),
|
|
5511
5858
|
disabled: isLoading || !table.getCanPreviousPage(),
|
|
5512
|
-
children:
|
|
5859
|
+
children: t.previous
|
|
5513
5860
|
}
|
|
5514
5861
|
),
|
|
5515
5862
|
/* @__PURE__ */ jsx(
|
|
@@ -5519,7 +5866,7 @@ var DataTablePagination = forwardRef(
|
|
|
5519
5866
|
size: "sm",
|
|
5520
5867
|
onClick: () => table.nextPage(),
|
|
5521
5868
|
disabled: isLoading || !table.getCanNextPage(),
|
|
5522
|
-
children:
|
|
5869
|
+
children: t.next
|
|
5523
5870
|
}
|
|
5524
5871
|
),
|
|
5525
5872
|
/* @__PURE__ */ jsx(
|
|
@@ -5529,7 +5876,7 @@ var DataTablePagination = forwardRef(
|
|
|
5529
5876
|
size: "sm",
|
|
5530
5877
|
onClick: () => table.lastPage(),
|
|
5531
5878
|
disabled: isLoading || !table.getCanNextPage(),
|
|
5532
|
-
children:
|
|
5879
|
+
children: t.last
|
|
5533
5880
|
}
|
|
5534
5881
|
)
|
|
5535
5882
|
] })
|
|
@@ -5541,6 +5888,7 @@ var DataTablePagination = forwardRef(
|
|
|
5541
5888
|
DataTablePagination.displayName = "DataTablePagination";
|
|
5542
5889
|
var DataTableColumnVisibility = forwardRef(({ columnLabels, className }, ref) => {
|
|
5543
5890
|
const { table } = useDataTable();
|
|
5891
|
+
const t = useText();
|
|
5544
5892
|
const hideableColumns = table.getAllColumns().filter((column) => column.getCanHide());
|
|
5545
5893
|
if (hideableColumns.length === 0) return null;
|
|
5546
5894
|
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
@@ -5550,7 +5898,7 @@ var DataTableColumnVisibility = forwardRef(({ columnLabels, className }, ref) =>
|
|
|
5550
5898
|
ref,
|
|
5551
5899
|
render: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: cn(className) }),
|
|
5552
5900
|
"data-slot": "data-table-column-visibility",
|
|
5553
|
-
"aria-label":
|
|
5901
|
+
"aria-label": t.columns,
|
|
5554
5902
|
children: /* @__PURE__ */ jsx(Columns3, { className: "size-4", "aria-hidden": "true" })
|
|
5555
5903
|
}
|
|
5556
5904
|
),
|
|
@@ -5585,7 +5933,8 @@ function toCsv(header, rows, options = {}) {
|
|
|
5585
5933
|
];
|
|
5586
5934
|
return (bom ? "\uFEFF" : "") + lines.join("\r\n");
|
|
5587
5935
|
}
|
|
5588
|
-
function tableToCsv(table, { values = "display", scope = "filtered" } = {}) {
|
|
5936
|
+
function tableToCsv(table, { values = "display", scope = "filtered", locale: localeArg } = {}) {
|
|
5937
|
+
const locale = resolveLocale(localeArg);
|
|
5589
5938
|
const columns = table.getVisibleLeafColumns().filter((column) => column.id !== "_select");
|
|
5590
5939
|
const rows = scope === "page" ? table.getRowModel().rows : table.getSortedRowModel().rows;
|
|
5591
5940
|
const header = columns.map(
|
|
@@ -5595,7 +5944,7 @@ function tableToCsv(table, { values = "display", scope = "filtered" } = {}) {
|
|
|
5595
5944
|
(row) => columns.map((column) => {
|
|
5596
5945
|
const value = row.getValue(column.id);
|
|
5597
5946
|
const meta = column.columnDef.meta;
|
|
5598
|
-
if (values === "display" && (meta?.format || meta?.dateFormat)) return formatCellText(value, row.original, meta);
|
|
5947
|
+
if (values === "display" && (meta?.format || meta?.dateFormat)) return formatCellText(value, row.original, meta, locale);
|
|
5599
5948
|
if (value === null || value === void 0) return "";
|
|
5600
5949
|
if (typeof value === "number" || typeof value === "string") return value;
|
|
5601
5950
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -5608,12 +5957,13 @@ function DataTableExport({
|
|
|
5608
5957
|
fileName = "export.csv",
|
|
5609
5958
|
values = "display",
|
|
5610
5959
|
scope = "filtered",
|
|
5611
|
-
children
|
|
5960
|
+
children,
|
|
5612
5961
|
className
|
|
5613
5962
|
}) {
|
|
5614
5963
|
const { table, isLoading } = useDataTable();
|
|
5964
|
+
const locale = useLocale();
|
|
5615
5965
|
const onClick = () => {
|
|
5616
|
-
const csv = tableToCsv(table, { values, scope });
|
|
5966
|
+
const csv = tableToCsv(table, { values, scope, locale });
|
|
5617
5967
|
const url = URL.createObjectURL(new Blob([csv], { type: "text/csv;charset=utf-8" }));
|
|
5618
5968
|
const a = document.createElement("a");
|
|
5619
5969
|
a.href = url;
|
|
@@ -5633,7 +5983,7 @@ function DataTableExport({
|
|
|
5633
5983
|
disabled: isLoading,
|
|
5634
5984
|
children: [
|
|
5635
5985
|
/* @__PURE__ */ jsx(Download, { className: "size-4", "aria-hidden": "true" }),
|
|
5636
|
-
children
|
|
5986
|
+
children ?? TEXT14[uiLanguage(locale)].exportCsv
|
|
5637
5987
|
]
|
|
5638
5988
|
}
|
|
5639
5989
|
);
|
|
@@ -5668,24 +6018,44 @@ function DataTablePreset({
|
|
|
5668
6018
|
}
|
|
5669
6019
|
DataTablePreset.displayName = "DataTablePreset";
|
|
5670
6020
|
var FilterBarContext = createContext(null);
|
|
6021
|
+
var TEXT15 = {
|
|
6022
|
+
ja: {
|
|
6023
|
+
filters: "\u30D5\u30A3\u30EB\u30BF\u30FC",
|
|
6024
|
+
selected: (count) => ` (${count}\u4EF6\u9078\u629E\u4E2D)`,
|
|
6025
|
+
remove: (filter, option) => `${filter}: ${option} \u3092\u524A\u9664`,
|
|
6026
|
+
clear: "\u30AF\u30EA\u30A2",
|
|
6027
|
+
clearAll: "\u3059\u3079\u3066\u306E\u30D5\u30A3\u30EB\u30BF\u30FC\u3092\u30AF\u30EA\u30A2"
|
|
6028
|
+
},
|
|
6029
|
+
en: {
|
|
6030
|
+
filters: "Filters",
|
|
6031
|
+
selected: (count) => ` (${count} selected)`,
|
|
6032
|
+
remove: (filter, option) => `Remove ${filter}: ${option}`,
|
|
6033
|
+
clear: "Clear",
|
|
6034
|
+
clearAll: "Clear all filters"
|
|
6035
|
+
}
|
|
6036
|
+
};
|
|
6037
|
+
var useText2 = () => TEXT15[uiLanguage(useLocale())];
|
|
5671
6038
|
function useFilterBar() {
|
|
5672
6039
|
const ctx = useContext(FilterBarContext);
|
|
5673
6040
|
if (!ctx) throw new Error("useFilterBar must be used within <FilterBar>");
|
|
5674
6041
|
return ctx;
|
|
5675
6042
|
}
|
|
5676
6043
|
var FilterBar = forwardRef(
|
|
5677
|
-
({ value, onChange, onClear, className, children, ...props }, ref) =>
|
|
5678
|
-
|
|
5679
|
-
{
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
6044
|
+
({ value, onChange, onClear, className, children, ...props }, ref) => {
|
|
6045
|
+
const t = useText2();
|
|
6046
|
+
return /* @__PURE__ */ jsx(FilterBarContext.Provider, { value: { value, onChange, onClear }, children: /* @__PURE__ */ jsx(
|
|
6047
|
+
"div",
|
|
6048
|
+
{
|
|
6049
|
+
ref,
|
|
6050
|
+
role: "search",
|
|
6051
|
+
"aria-label": t.filters,
|
|
6052
|
+
"data-slot": "filter-bar",
|
|
6053
|
+
className: cn("flex flex-wrap items-center gap-2", className),
|
|
6054
|
+
...props,
|
|
6055
|
+
children
|
|
6056
|
+
}
|
|
6057
|
+
) });
|
|
6058
|
+
}
|
|
5689
6059
|
);
|
|
5690
6060
|
FilterBar.displayName = "FilterBar";
|
|
5691
6061
|
var ALL_VALUE = "__squadkit_all__";
|
|
@@ -5727,6 +6097,7 @@ function FilterBarMultiSelect({
|
|
|
5727
6097
|
className
|
|
5728
6098
|
}) {
|
|
5729
6099
|
const { value, onChange } = useFilterBar();
|
|
6100
|
+
const t = useText2();
|
|
5730
6101
|
const selected = value[filterKey] ?? [];
|
|
5731
6102
|
const handleToggle = (option) => {
|
|
5732
6103
|
const next = selected.includes(option) ? selected.filter((v) => v !== option) : [...selected, option];
|
|
@@ -5737,7 +6108,7 @@ function FilterBarMultiSelect({
|
|
|
5737
6108
|
PopoverTrigger,
|
|
5738
6109
|
{
|
|
5739
6110
|
render: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", className: cn("h-8 gap-1", className) }),
|
|
5740
|
-
"aria-label": `${placeholder ?? label2}${selected.length > 0 ?
|
|
6111
|
+
"aria-label": `${placeholder ?? label2}${selected.length > 0 ? t.selected(selected.length) : ""}`,
|
|
5741
6112
|
"data-slot": "filter-bar-multi-select",
|
|
5742
6113
|
children: [
|
|
5743
6114
|
placeholder ?? label2,
|
|
@@ -5769,6 +6140,7 @@ function FilterBarMultiSelect({
|
|
|
5769
6140
|
FilterBarMultiSelect.displayName = "FilterBarMultiSelect";
|
|
5770
6141
|
function FilterBarActiveChips({ filters, className }) {
|
|
5771
6142
|
const { value, onChange } = useFilterBar();
|
|
6143
|
+
const t = useText2();
|
|
5772
6144
|
const getActiveChips = () => {
|
|
5773
6145
|
const chips = [];
|
|
5774
6146
|
const pushRaw = (key, v) => {
|
|
@@ -5839,7 +6211,7 @@ function FilterBarActiveChips({ filters, className }) {
|
|
|
5839
6211
|
type: "button",
|
|
5840
6212
|
className: "ml-0.5 rounded-full p-0.5 hover:bg-muted-foreground/20",
|
|
5841
6213
|
onClick: () => handleRemoveFilter(chip.key, chip.optionValue),
|
|
5842
|
-
"aria-label":
|
|
6214
|
+
"aria-label": t.remove(chip.filterLabel, chip.optionLabel),
|
|
5843
6215
|
children: /* @__PURE__ */ jsx(X, { className: "size-3", "aria-hidden": "true" })
|
|
5844
6216
|
}
|
|
5845
6217
|
)
|
|
@@ -5849,8 +6221,9 @@ function FilterBarActiveChips({ filters, className }) {
|
|
|
5849
6221
|
)) });
|
|
5850
6222
|
}
|
|
5851
6223
|
FilterBarActiveChips.displayName = "FilterBarActiveChips";
|
|
5852
|
-
function FilterBarClearButton({ label: label2
|
|
6224
|
+
function FilterBarClearButton({ label: label2, className }) {
|
|
5853
6225
|
const { value, onClear } = useFilterBar();
|
|
6226
|
+
const t = useText2();
|
|
5854
6227
|
const hasActiveFilters = Object.values(value).some(
|
|
5855
6228
|
(v) => Array.isArray(v) ? v.length > 0 : v !== void 0 && v !== ""
|
|
5856
6229
|
);
|
|
@@ -5862,9 +6235,9 @@ function FilterBarClearButton({ label: label2 = "\u30AF\u30EA\u30A2", className
|
|
|
5862
6235
|
size: "sm",
|
|
5863
6236
|
className: cn("h-7 px-2 text-xs", className),
|
|
5864
6237
|
onClick: onClear,
|
|
5865
|
-
"aria-label":
|
|
6238
|
+
"aria-label": t.clearAll,
|
|
5866
6239
|
"data-slot": "filter-bar-clear-button",
|
|
5867
|
-
children: label2
|
|
6240
|
+
children: label2 ?? t.clear
|
|
5868
6241
|
}
|
|
5869
6242
|
);
|
|
5870
6243
|
}
|
|
@@ -5912,13 +6285,16 @@ function FilterBarPreset({
|
|
|
5912
6285
|
] });
|
|
5913
6286
|
}
|
|
5914
6287
|
FilterBarPreset.displayName = "FilterBarPreset";
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
6288
|
+
function normalizeFiscalYearStartMonth(month, locale) {
|
|
6289
|
+
return typeof month === "number" && Number.isInteger(month) && month >= 1 && month <= 12 ? month : defaultFiscalYearStartMonth(locale);
|
|
6290
|
+
}
|
|
6291
|
+
function fiscalPeriodRange(date, {
|
|
6292
|
+
unit,
|
|
6293
|
+
fiscalYearStartMonth,
|
|
6294
|
+
offset = 0,
|
|
6295
|
+
locale
|
|
6296
|
+
}) {
|
|
6297
|
+
const startMonth = normalizeFiscalYearStartMonth(fiscalYearStartMonth, locale);
|
|
5922
6298
|
const length = unit === "year" ? 12 : 3;
|
|
5923
6299
|
const sinceYearStart = (date.getMonth() - (startMonth - 1) + 12) % 12;
|
|
5924
6300
|
const into = unit === "year" ? sinceYearStart : sinceYearStart % 3;
|
|
@@ -5961,16 +6337,20 @@ var PRESET_LABELS = {
|
|
|
5961
6337
|
lastFiscalYear: "Last fiscal year"
|
|
5962
6338
|
}
|
|
5963
6339
|
};
|
|
5964
|
-
var
|
|
5965
|
-
|
|
5966
|
-
|
|
6340
|
+
var TEXT16 = {
|
|
6341
|
+
ja: { placeholder: "\u671F\u9593\u3092\u9078\u629E", rangeSeparator: " - " },
|
|
6342
|
+
en: { placeholder: "Pick a date range", rangeSeparator: " \u2013 " }
|
|
6343
|
+
};
|
|
6344
|
+
var calendarLocale = (locale) => uiLanguage(locale) === "ja" ? ja : void 0;
|
|
5967
6345
|
function createDatePresets({
|
|
5968
|
-
locale
|
|
5969
|
-
fiscalYearStartMonth
|
|
6346
|
+
locale: localeArg,
|
|
6347
|
+
fiscalYearStartMonth,
|
|
5970
6348
|
now = () => /* @__PURE__ */ new Date()
|
|
5971
6349
|
} = {}) {
|
|
5972
|
-
const
|
|
5973
|
-
const
|
|
6350
|
+
const locale = resolveLocale(localeArg);
|
|
6351
|
+
const t = PRESET_LABELS[uiLanguage(locale)];
|
|
6352
|
+
const startMonth = normalizeFiscalYearStartMonth(fiscalYearStartMonth, locale);
|
|
6353
|
+
const WEEK_OPTIONS = { weekStartsOn: weekStartsOn(locale) };
|
|
5974
6354
|
const lastDays = (days) => () => {
|
|
5975
6355
|
const today = now();
|
|
5976
6356
|
return { from: startOfDay(subDays(today, days - 1)), to: endOfDay(today) };
|
|
@@ -6039,24 +6419,26 @@ function findMatchingPreset(presets, value) {
|
|
|
6039
6419
|
return range.from != null && range.to != null && isSameDay(range.from, from) && isSameDay(range.to, to);
|
|
6040
6420
|
});
|
|
6041
6421
|
}
|
|
6042
|
-
var defaultPresets = createDatePresets();
|
|
6422
|
+
var defaultPresets = createDatePresets({ locale: FALLBACK_LOCALE });
|
|
6043
6423
|
var DateRangePicker = forwardRef(
|
|
6044
6424
|
function DateRangePicker2({
|
|
6045
6425
|
value,
|
|
6046
6426
|
onChange,
|
|
6047
6427
|
presets: presetsProp,
|
|
6048
6428
|
showPresets = true,
|
|
6049
|
-
locale
|
|
6050
|
-
fiscalYearStartMonth
|
|
6429
|
+
locale: localeProp,
|
|
6430
|
+
fiscalYearStartMonth,
|
|
6051
6431
|
maxDate,
|
|
6052
6432
|
minDate,
|
|
6053
|
-
placeholder
|
|
6433
|
+
placeholder,
|
|
6054
6434
|
disabled = false,
|
|
6055
6435
|
className,
|
|
6056
6436
|
align = "start"
|
|
6057
6437
|
}, ref) {
|
|
6058
6438
|
const [open, setOpen] = useState(false);
|
|
6059
6439
|
const isMobile = useIsMobile();
|
|
6440
|
+
const locale = useLocale(localeProp);
|
|
6441
|
+
const t = TEXT16[uiLanguage(locale)];
|
|
6060
6442
|
const presets = useMemo(
|
|
6061
6443
|
() => presetsProp ?? createDatePresets({ locale, fiscalYearStartMonth }),
|
|
6062
6444
|
[presetsProp, locale, fiscalYearStartMonth]
|
|
@@ -6075,9 +6457,9 @@ var DateRangePicker = forwardRef(
|
|
|
6075
6457
|
[onChange]
|
|
6076
6458
|
);
|
|
6077
6459
|
const formatDateRange2 = () => {
|
|
6078
|
-
if (!value?.from) return placeholder;
|
|
6079
|
-
if (!value.to) return
|
|
6080
|
-
return `${
|
|
6460
|
+
if (!value?.from) return placeholder ?? t.placeholder;
|
|
6461
|
+
if (!value.to) return formatDate(value.from, "date", locale);
|
|
6462
|
+
return `${formatDate(value.from, "date", locale)}${t.rangeSeparator}${formatDate(value.to, "date", locale)}`;
|
|
6081
6463
|
};
|
|
6082
6464
|
const selectedPreset = findMatchingPreset(presets, value);
|
|
6083
6465
|
const presetLabel = selectedPreset?.label;
|
|
@@ -6138,7 +6520,7 @@ var DateRangePicker = forwardRef(
|
|
|
6138
6520
|
mode: "range",
|
|
6139
6521
|
defaultMonth,
|
|
6140
6522
|
locale: calendarLocale(locale),
|
|
6141
|
-
weekStartsOn:
|
|
6523
|
+
weekStartsOn: weekStartsOn(locale),
|
|
6142
6524
|
numberOfMonths: isMobile ? 1 : 2,
|
|
6143
6525
|
selected: calendarSelected,
|
|
6144
6526
|
onSelect: handleCalendarSelect,
|
|
@@ -6273,6 +6655,10 @@ function RemoveButton({ label: label2, onRemove, iconClassName }) {
|
|
|
6273
6655
|
}
|
|
6274
6656
|
);
|
|
6275
6657
|
}
|
|
6658
|
+
var TEXT17 = {
|
|
6659
|
+
ja: { placeholder: "\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044", search: "\u691C\u7D22...", empty: "\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F", clear: "\u30AF\u30EA\u30A2" },
|
|
6660
|
+
en: { placeholder: "Select an option", search: "Search...", empty: "No results found.", clear: "Clear" }
|
|
6661
|
+
};
|
|
6276
6662
|
var NO_OPTIONS2 = [];
|
|
6277
6663
|
var SearchableSelect = forwardRef(
|
|
6278
6664
|
function SearchableSelect2({
|
|
@@ -6280,15 +6666,16 @@ var SearchableSelect = forwardRef(
|
|
|
6280
6666
|
value,
|
|
6281
6667
|
onChange,
|
|
6282
6668
|
onSearch,
|
|
6283
|
-
placeholder
|
|
6284
|
-
searchPlaceholder
|
|
6285
|
-
emptyText
|
|
6669
|
+
placeholder,
|
|
6670
|
+
searchPlaceholder,
|
|
6671
|
+
emptyText,
|
|
6286
6672
|
isLoading = false,
|
|
6287
6673
|
disabled = false,
|
|
6288
6674
|
clearable = true,
|
|
6289
6675
|
className
|
|
6290
6676
|
}, ref) {
|
|
6291
6677
|
const [open, setOpen] = useState(false);
|
|
6678
|
+
const t = TEXT17[uiLanguage(useLocale())];
|
|
6292
6679
|
const allOptions = useMemo(() => flattenOptions(options), [options]);
|
|
6293
6680
|
const selectedOption = useMemo(
|
|
6294
6681
|
() => allOptions.find((opt) => opt.value === value),
|
|
@@ -6317,9 +6704,9 @@ var SearchableSelect = forwardRef(
|
|
|
6317
6704
|
role: "combobox",
|
|
6318
6705
|
"aria-expanded": open,
|
|
6319
6706
|
children: [
|
|
6320
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption ? selectedOption.label : placeholder }),
|
|
6707
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption ? selectedOption.label : placeholder ?? t.placeholder }),
|
|
6321
6708
|
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
6322
|
-
clearable && value && /* @__PURE__ */ jsx(RemoveButton, { label:
|
|
6709
|
+
clearable && value && /* @__PURE__ */ jsx(RemoveButton, { label: t.clear, onRemove: () => onChange?.(void 0) }),
|
|
6323
6710
|
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" })
|
|
6324
6711
|
] })
|
|
6325
6712
|
]
|
|
@@ -6333,14 +6720,30 @@ var SearchableSelect = forwardRef(
|
|
|
6333
6720
|
onSelect: handleSelect,
|
|
6334
6721
|
onSearch,
|
|
6335
6722
|
isLoading,
|
|
6336
|
-
searchPlaceholder,
|
|
6337
|
-
emptyText
|
|
6723
|
+
searchPlaceholder: searchPlaceholder ?? t.search,
|
|
6724
|
+
emptyText: emptyText ?? t.empty
|
|
6338
6725
|
}
|
|
6339
6726
|
) })
|
|
6340
6727
|
] }) });
|
|
6341
6728
|
}
|
|
6342
6729
|
);
|
|
6343
6730
|
SearchableSelect.displayName = "SearchableSelect";
|
|
6731
|
+
var TEXT18 = {
|
|
6732
|
+
ja: {
|
|
6733
|
+
placeholder: "\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
6734
|
+
search: "\u691C\u7D22...",
|
|
6735
|
+
empty: "\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F",
|
|
6736
|
+
remove: (label2) => `${label2}\u3092\u524A\u9664`,
|
|
6737
|
+
more: (count) => `+${count}\u4EF6`
|
|
6738
|
+
},
|
|
6739
|
+
en: {
|
|
6740
|
+
placeholder: "Select options",
|
|
6741
|
+
search: "Search...",
|
|
6742
|
+
empty: "No results found.",
|
|
6743
|
+
remove: (label2) => `Remove ${label2}`,
|
|
6744
|
+
more: (count) => `+${count} more`
|
|
6745
|
+
}
|
|
6746
|
+
};
|
|
6344
6747
|
var NO_OPTIONS3 = [];
|
|
6345
6748
|
var NO_VALUES = [];
|
|
6346
6749
|
var MultiSelect = forwardRef(function MultiSelect2({
|
|
@@ -6349,15 +6752,16 @@ var MultiSelect = forwardRef(function MultiSelect2({
|
|
|
6349
6752
|
onChange,
|
|
6350
6753
|
onSearch,
|
|
6351
6754
|
maxCount = 3,
|
|
6352
|
-
placeholder
|
|
6353
|
-
searchPlaceholder
|
|
6354
|
-
emptyText
|
|
6755
|
+
placeholder,
|
|
6756
|
+
searchPlaceholder,
|
|
6757
|
+
emptyText,
|
|
6355
6758
|
isLoading = false,
|
|
6356
6759
|
disabled = false,
|
|
6357
6760
|
className
|
|
6358
6761
|
}, ref) {
|
|
6359
6762
|
const [open, setOpen] = useState(false);
|
|
6360
6763
|
const listId = useId();
|
|
6764
|
+
const t = TEXT18[uiLanguage(useLocale())];
|
|
6361
6765
|
const allOptions = useMemo(() => flattenOptions(options), [options]);
|
|
6362
6766
|
const selectedOptions = useMemo(
|
|
6363
6767
|
() => allOptions.filter((opt) => value.includes(opt.value)),
|
|
@@ -6385,23 +6789,19 @@ var MultiSelect = forwardRef(function MultiSelect2({
|
|
|
6385
6789
|
className
|
|
6386
6790
|
),
|
|
6387
6791
|
children: [
|
|
6388
|
-
/* @__PURE__ */ jsx("span", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-1", children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6792
|
+
/* @__PURE__ */ jsx("span", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-1", children: selectedOptions.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder ?? t.placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6389
6793
|
visibleBadges.map((option) => /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "shrink-0 gap-1 pr-1", children: [
|
|
6390
6794
|
/* @__PURE__ */ jsx("span", { className: "max-w-[120px] truncate", children: option.label }),
|
|
6391
6795
|
/* @__PURE__ */ jsx(
|
|
6392
6796
|
RemoveButton,
|
|
6393
6797
|
{
|
|
6394
|
-
label:
|
|
6798
|
+
label: t.remove(option.label),
|
|
6395
6799
|
onRemove: () => onChange?.(value.filter((v) => v !== option.value)),
|
|
6396
6800
|
iconClassName: "size-3"
|
|
6397
6801
|
}
|
|
6398
6802
|
)
|
|
6399
6803
|
] }, option.value)),
|
|
6400
|
-
overflowCount > 0 && /* @__PURE__ */
|
|
6401
|
-
"+",
|
|
6402
|
-
overflowCount,
|
|
6403
|
-
"\u4EF6"
|
|
6404
|
-
] })
|
|
6804
|
+
overflowCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: t.more(overflowCount) })
|
|
6405
6805
|
] }) }),
|
|
6406
6806
|
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 shrink-0 opacity-50" })
|
|
6407
6807
|
]
|
|
@@ -6415,8 +6815,8 @@ var MultiSelect = forwardRef(function MultiSelect2({
|
|
|
6415
6815
|
onSelect: handleSelect,
|
|
6416
6816
|
onSearch,
|
|
6417
6817
|
isLoading,
|
|
6418
|
-
searchPlaceholder,
|
|
6419
|
-
emptyText
|
|
6818
|
+
searchPlaceholder: searchPlaceholder ?? t.search,
|
|
6819
|
+
emptyText: emptyText ?? t.empty
|
|
6420
6820
|
}
|
|
6421
6821
|
) })
|
|
6422
6822
|
] }) });
|
|
@@ -6505,14 +6905,17 @@ function inferPeriodGrain(period) {
|
|
|
6505
6905
|
return void 0;
|
|
6506
6906
|
}
|
|
6507
6907
|
var RECORD_MIN_POINTS = 6;
|
|
6508
|
-
var
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6908
|
+
var RECORD_TEXT = {
|
|
6909
|
+
ja: (span, grain, lower) => {
|
|
6910
|
+
const units = { day: "\u65E5", week: "\u9031", month: "\u304B\u6708", quarter: "\u56DB\u534A\u671F", year: "\u5E74" };
|
|
6911
|
+
return `\u904E\u53BB ${span} ${units[grain]}\u3067${lower ? "\u6700\u4F4E" : "\u6700\u9AD8"}`;
|
|
6912
|
+
},
|
|
6913
|
+
en: (span, grain, lower) => {
|
|
6914
|
+
const units = { day: "days", week: "weeks", month: "months", quarter: "quarters", year: "years" };
|
|
6915
|
+
return `${lower ? "Lowest" : "Highest"} in ${span} ${units[grain]}`;
|
|
6916
|
+
}
|
|
6514
6917
|
};
|
|
6515
|
-
function detectRecord(history, grain = "month", polarity = "higher-is-better") {
|
|
6918
|
+
function detectRecord(history, grain = "month", polarity = "higher-is-better", locale) {
|
|
6516
6919
|
if (!history) return null;
|
|
6517
6920
|
const points = history.filter(isFiniteNumber);
|
|
6518
6921
|
if (points.length < RECORD_MIN_POINTS) return null;
|
|
@@ -6525,7 +6928,7 @@ function detectRecord(history, grain = "month", polarity = "higher-is-better") {
|
|
|
6525
6928
|
span,
|
|
6526
6929
|
grain,
|
|
6527
6930
|
kind: lower ? "lowest" : "highest",
|
|
6528
|
-
label:
|
|
6931
|
+
label: RECORD_TEXT[uiLanguage(resolveLocale(locale))](span, grain, lower)
|
|
6529
6932
|
};
|
|
6530
6933
|
}
|
|
6531
6934
|
var deltaVariants = cva(
|
|
@@ -6554,13 +6957,29 @@ var deltaVariants = cva(
|
|
|
6554
6957
|
}
|
|
6555
6958
|
);
|
|
6556
6959
|
var DELTA_NOT_COMPARABLE = EMPTY_VALUE;
|
|
6557
|
-
|
|
6960
|
+
var ARIA_TEXT = {
|
|
6961
|
+
ja: {
|
|
6962
|
+
none: (label2) => `${label2} \u6BD4\u8F03\u3067\u304D\u307E\u305B\u3093`,
|
|
6963
|
+
flat: (label2) => `${label2} \u6A2A\u3070\u3044`,
|
|
6964
|
+
points: " \u30DD\u30A4\u30F3\u30C8",
|
|
6965
|
+
change: (label2, amount, up) => `${label2} ${amount} ${up ? "\u5897\u52A0" : "\u6E1B\u5C11"}`
|
|
6966
|
+
},
|
|
6967
|
+
en: {
|
|
6968
|
+
none: (label2) => `${label2}: not comparable`,
|
|
6969
|
+
flat: (label2) => `Flat ${label2}`,
|
|
6970
|
+
points: " points",
|
|
6971
|
+
change: (label2, amount, up) => `${up ? "Up" : "Down"} ${amount} ${label2}`
|
|
6972
|
+
}
|
|
6973
|
+
};
|
|
6974
|
+
function deltaAriaLabel(result, locale, change = "relative", format, digits) {
|
|
6975
|
+
const resolved = resolveLocale(locale);
|
|
6976
|
+
const t = ARIA_TEXT[uiLanguage(resolved)];
|
|
6558
6977
|
const { label: label2, direction, ratio } = result;
|
|
6559
|
-
if (direction === "none" || ratio === null) return
|
|
6560
|
-
if (direction === "flat") return
|
|
6561
|
-
const amount = formatChangeAmount(result, change,
|
|
6562
|
-
if (amount === null) return
|
|
6563
|
-
return
|
|
6978
|
+
if (direction === "none" || ratio === null) return t.none(label2);
|
|
6979
|
+
if (direction === "flat") return t.flat(label2);
|
|
6980
|
+
const amount = formatChangeAmount(result, change, resolved, format, digits);
|
|
6981
|
+
if (amount === null) return t.none(label2);
|
|
6982
|
+
return t.change(label2, change === "points" ? amount.replace(/pt$/, t.points) : amount, direction === "up");
|
|
6564
6983
|
}
|
|
6565
6984
|
var Delta = forwardRef(
|
|
6566
6985
|
({
|
|
@@ -6569,23 +6988,28 @@ var Delta = forwardRef(
|
|
|
6569
6988
|
betterWhen,
|
|
6570
6989
|
polarity,
|
|
6571
6990
|
neutralBand,
|
|
6572
|
-
format
|
|
6991
|
+
format,
|
|
6573
6992
|
change,
|
|
6574
6993
|
digits,
|
|
6575
|
-
locale
|
|
6994
|
+
locale: localeProp,
|
|
6576
6995
|
showLabel = true,
|
|
6577
6996
|
variant = "badge",
|
|
6578
6997
|
className,
|
|
6579
6998
|
...props
|
|
6580
6999
|
}, ref) => {
|
|
7000
|
+
const locale = useLocale(localeProp);
|
|
6581
7001
|
if (!comparison) return null;
|
|
6582
|
-
const result = computeComparison(value, comparison, {
|
|
6583
|
-
|
|
6584
|
-
|
|
7002
|
+
const result = computeComparison(value, comparison, {
|
|
7003
|
+
polarity: betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarity,
|
|
7004
|
+
neutralBand,
|
|
7005
|
+
locale
|
|
7006
|
+
});
|
|
7007
|
+
const display = change ?? defaultChangeDisplay(format);
|
|
7008
|
+
const formatDigits = typeof format === "object" && format !== null && "digits" in format ? format.digits : void 0;
|
|
6585
7009
|
const changeDigits = display === "points" ? digits ?? formatDigits : digits;
|
|
6586
7010
|
const comparable = result.direction !== "none";
|
|
6587
7011
|
const Icon = result.direction === "up" ? ArrowUp : result.direction === "down" ? ArrowDown : ArrowRight;
|
|
6588
|
-
const text = formatChange(result, display, locale,
|
|
7012
|
+
const text = formatChange(result, display, locale, format, changeDigits);
|
|
6589
7013
|
return /* @__PURE__ */ jsxs(
|
|
6590
7014
|
"span",
|
|
6591
7015
|
{
|
|
@@ -6594,7 +7018,7 @@ var Delta = forwardRef(
|
|
|
6594
7018
|
"data-slot": "delta",
|
|
6595
7019
|
"data-direction": result.direction,
|
|
6596
7020
|
"data-sentiment": result.sentiment,
|
|
6597
|
-
"aria-label": deltaAriaLabel(result, locale, display,
|
|
7021
|
+
"aria-label": deltaAriaLabel(result, locale, display, format, changeDigits),
|
|
6598
7022
|
className: cn(
|
|
6599
7023
|
deltaVariants({ variant, sentiment: result.sentiment }),
|
|
6600
7024
|
!comparable && "text-muted-foreground",
|
|
@@ -6619,7 +7043,69 @@ var LONG_VALUE_CHARS = 10;
|
|
|
6619
7043
|
var DELTA_UNDER_PLACEMENT = "col-start-1 row-span-1 row-start-3 justify-self-start";
|
|
6620
7044
|
var KPI_FOOTER_CLASS = "flex-col items-start gap-2 rounded-none border-t-0 bg-transparent pt-0 text-sm";
|
|
6621
7045
|
var PLACEHOLDER = /\{(\w+)\}/g;
|
|
6622
|
-
var
|
|
7046
|
+
var TEXT19 = {
|
|
7047
|
+
ja: {
|
|
7048
|
+
target: "\u76EE\u6A19",
|
|
7049
|
+
provisional: "\u901F\u5831",
|
|
7050
|
+
joiner: "\u30FB",
|
|
7051
|
+
countFrom: (count) => `${count}\u4EF6\u304B\u3089\u96C6\u8A08`,
|
|
7052
|
+
excluded: (count) => `${count}\u4EF6\u3092\u9664\u5916`,
|
|
7053
|
+
noBaseline: (baseline) => `${baseline}\u306E\u5B9F\u7E3E\u304C\u306A\u3044\u305F\u3081\u3001\u6BD4\u8F03\u3067\u304D\u307E\u305B\u3093\u3002`,
|
|
7054
|
+
previous: (baseline, value) => `${baseline} ${value}`,
|
|
7055
|
+
noPrevious: (baseline) => `${baseline}\u306E\u5B9F\u7E3E\u306A\u3057`,
|
|
7056
|
+
barLead: (tl, pct) => `${tl}\u306E ${pct}`,
|
|
7057
|
+
pace: (pct) => `\u3053\u306E\u30DA\u30FC\u30B9\u306A\u3089 ${pct}`,
|
|
7058
|
+
provisionalSuffix: "\uFF08\u78BA\u5B9A\u524D\uFF09",
|
|
7059
|
+
provisionalReached: (tl, target) => `${tl} ${target} \u306B\u5230\u9054\uFF08\u78BA\u5B9A\u524D\uFF09`,
|
|
7060
|
+
provisionalSoFar: (tl, target, pct) => `${tl} ${target} \u306B\u5BFE\u3057\u3066\u73FE\u6642\u70B9 ${pct}\uFF08\u78BA\u5B9A\u524D\uFF09`,
|
|
7061
|
+
provisionalToGo: (tl, target, distance) => `${tl} ${target} \u307E\u3067\u3042\u3068 ${distance}\uFF08\u78BA\u5B9A\u524D\uFF09`,
|
|
7062
|
+
provisionalToGoRate: (tl, distance, pct) => `${tl}\u307E\u3067\u3042\u3068 ${distance}\uFF08\u73FE\u6642\u70B9 ${pct}\u30FB\u78BA\u5B9A\u524D\uFF09`,
|
|
7063
|
+
met: (tl, target) => `${tl} ${target} \u3092\u9054\u6210`,
|
|
7064
|
+
toGo: (tl, target, distance) => `${tl} ${target} \u307E\u3067\u3042\u3068 ${distance}`,
|
|
7065
|
+
reached: (tl, target) => `${tl} ${target} \u306B\u5230\u9054`,
|
|
7066
|
+
reachedRate: (tl, target, pct) => `${tl} ${target} \u306B\u5230\u9054\uFF08${pct} \u9054\u6210\uFF09`,
|
|
7067
|
+
toGoRate: (tl, distance, pct) => `${tl}\u307E\u3067\u3042\u3068 ${distance}\uFF08${pct} \u9054\u6210\uFF09`,
|
|
7068
|
+
progressLabel: (tl) => `${tl}\u306B\u5BFE\u3059\u308B\u9032\u6357`,
|
|
7069
|
+
progressValue: (tl, target, value, pct) => `${tl} ${target} \u306B\u5BFE\u3057\u3066 ${value}\uFF08${pct}\uFF09`,
|
|
7070
|
+
history: (label2, points) => `${label2}\u306E\u63A8\u79FB\uFF08\u76F4\u8FD1 ${points} \u70B9\uFF09`,
|
|
7071
|
+
updatedRelative: (relative2) => `${relative2}\u306B\u66F4\u65B0`,
|
|
7072
|
+
updatedAbsolute: (absolute2) => `${absolute2} \u306B\u66F4\u65B0`,
|
|
7073
|
+
updatedBoth: (absolute2, relative2) => `${absolute2} \u306B\u66F4\u65B0\uFF08${relative2}\uFF09`,
|
|
7074
|
+
summaryExample: "{label}\u306F\u76EE\u6A19\u306E {achievement} \u307E\u3067\u6765\u3066\u3044\u307E\u3059\u3002"
|
|
7075
|
+
},
|
|
7076
|
+
en: {
|
|
7077
|
+
target: "Target",
|
|
7078
|
+
provisional: "Preliminary",
|
|
7079
|
+
joiner: " \xB7 ",
|
|
7080
|
+
countFrom: (count) => `Based on ${count} records`,
|
|
7081
|
+
excluded: (count) => `${count} excluded`,
|
|
7082
|
+
noBaseline: (baseline) => `No ${baseline} data to compare against.`,
|
|
7083
|
+
previous: (baseline, value) => `${capitalize(baseline)}: ${value}`,
|
|
7084
|
+
noPrevious: (baseline) => `No ${baseline} data`,
|
|
7085
|
+
barLead: (tl, pct) => `${tl}: ${pct}`,
|
|
7086
|
+
pace: (pct) => `On pace for ${pct}`,
|
|
7087
|
+
provisionalSuffix: " (preliminary)",
|
|
7088
|
+
provisionalReached: (tl, target) => `${tl} ${target}: reached (preliminary)`,
|
|
7089
|
+
provisionalSoFar: (tl, target, pct) => `${tl} ${target}: ${pct} so far (preliminary)`,
|
|
7090
|
+
provisionalToGo: (tl, target, distance) => `${tl} ${target}: ${distance} to go (preliminary)`,
|
|
7091
|
+
provisionalToGoRate: (tl, distance, pct) => `${tl}: ${distance} to go (${pct} so far, preliminary)`,
|
|
7092
|
+
met: (tl, target) => `${tl} ${target}: met`,
|
|
7093
|
+
toGo: (tl, target, distance) => `${tl} ${target}: ${distance} to go`,
|
|
7094
|
+
reached: (tl, target) => `${tl} ${target}: reached`,
|
|
7095
|
+
reachedRate: (tl, target, pct) => `${tl} ${target}: reached (${pct} achieved)`,
|
|
7096
|
+
toGoRate: (tl, distance, pct) => `${tl}: ${distance} to go (${pct} achieved)`,
|
|
7097
|
+
progressLabel: (tl) => `Progress toward ${tl}`,
|
|
7098
|
+
progressValue: (tl, target, value, pct) => `${value} of ${tl} ${target} (${pct})`,
|
|
7099
|
+
history: (label2, points) => `${label2} trend (last ${points} points)`,
|
|
7100
|
+
updatedRelative: (relative2) => `Updated ${relative2}`,
|
|
7101
|
+
updatedAbsolute: (absolute2) => `Updated ${absolute2}`,
|
|
7102
|
+
updatedBoth: (absolute2, relative2) => `Updated ${absolute2} (${relative2})`,
|
|
7103
|
+
summaryExample: "{label} is at {achievement} of target."
|
|
7104
|
+
}
|
|
7105
|
+
};
|
|
7106
|
+
function capitalize(text) {
|
|
7107
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
7108
|
+
}
|
|
6623
7109
|
var isMissing = (v) => v === null || v === void 0 || v === "";
|
|
6624
7110
|
function fillKpiTemplate(template, values, fallback) {
|
|
6625
7111
|
let missing = false;
|
|
@@ -6647,11 +7133,11 @@ function isProduction() {
|
|
|
6647
7133
|
return true;
|
|
6648
7134
|
}
|
|
6649
7135
|
}
|
|
6650
|
-
function warnShallowSummary(template) {
|
|
7136
|
+
function warnShallowSummary(template, t) {
|
|
6651
7137
|
if (shallowSummaryWarned || isProduction() || !isShallowSummary(template)) return;
|
|
6652
7138
|
shallowSummaryWarned = true;
|
|
6653
7139
|
console.warn(
|
|
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. "{
|
|
7140
|
+
`[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. "${t.summaryExample}").`
|
|
6655
7141
|
);
|
|
6656
7142
|
}
|
|
6657
7143
|
function digitGroups(text) {
|
|
@@ -6660,8 +7146,8 @@ function digitGroups(text) {
|
|
|
6660
7146
|
function KpiCard({
|
|
6661
7147
|
label: label2,
|
|
6662
7148
|
value,
|
|
6663
|
-
format
|
|
6664
|
-
locale
|
|
7149
|
+
format,
|
|
7150
|
+
locale: localeProp,
|
|
6665
7151
|
comparison: comparisonProp,
|
|
6666
7152
|
comparisons,
|
|
6667
7153
|
provisional,
|
|
@@ -6672,7 +7158,7 @@ function KpiCard({
|
|
|
6672
7158
|
showPrevious = true,
|
|
6673
7159
|
summary,
|
|
6674
7160
|
target,
|
|
6675
|
-
targetLabel
|
|
7161
|
+
targetLabel,
|
|
6676
7162
|
targetDisplay,
|
|
6677
7163
|
period,
|
|
6678
7164
|
history,
|
|
@@ -6688,10 +7174,12 @@ function KpiCard({
|
|
|
6688
7174
|
className,
|
|
6689
7175
|
...props
|
|
6690
7176
|
}) {
|
|
7177
|
+
const locale = useLocale(localeProp);
|
|
7178
|
+
const t = TEXT19[uiLanguage(locale)];
|
|
6691
7179
|
const allComparisons = [...comparisonProp ? [comparisonProp] : [], ...comparisons ?? []];
|
|
6692
7180
|
const comparison = allComparisons[0];
|
|
6693
7181
|
const isProvisional = provisional !== void 0 && provisional !== false;
|
|
6694
|
-
const provisionalLabel = typeof provisional === "object" && provisional.label ? provisional.label :
|
|
7182
|
+
const provisionalLabel = typeof provisional === "object" && provisional.label ? provisional.label : t.provisional;
|
|
6695
7183
|
const sample = useSampleMark();
|
|
6696
7184
|
const polarity = betterWhen ? betterWhen === "down" ? "lower-is-better" : "higher-is-better" : polarityProp;
|
|
6697
7185
|
const neutral = polarity === "neutral";
|
|
@@ -6699,11 +7187,11 @@ function KpiCard({
|
|
|
6699
7187
|
const stacked = allComparisons.length > 1;
|
|
6700
7188
|
const hasTarget = target !== void 0;
|
|
6701
7189
|
const grain = comparison?.grain ?? historyGrain ?? inferPeriodGrain(period);
|
|
6702
|
-
const record = isProvisional || neutral ? null : detectRecord(history, historyGrain ?? grain, polarity);
|
|
7190
|
+
const record = isProvisional || neutral ? null : detectRecord(history, historyGrain ?? grain, polarity, locale);
|
|
6703
7191
|
const sourceParts = source ? [
|
|
6704
7192
|
source.period !== void 0 ? formatDatesInText(source.period, locale) : void 0,
|
|
6705
|
-
source.count !== void 0 ?
|
|
6706
|
-
source.excluded !== void 0 && Number.isFinite(source.excluded) && source.excluded > 0 ?
|
|
7193
|
+
source.count !== void 0 ? t.countFrom(formatValue(source.count, "number", locale)) : void 0,
|
|
7194
|
+
source.excluded !== void 0 && Number.isFinite(source.excluded) && source.excluded > 0 ? t.excluded(formatValue(source.excluded, "number", locale)) : void 0,
|
|
6707
7195
|
source.name,
|
|
6708
7196
|
source.note
|
|
6709
7197
|
].filter((p) => typeof p === "string" && p !== "") : [];
|
|
@@ -6711,11 +7199,11 @@ function KpiCard({
|
|
|
6711
7199
|
const historyPoints = (history ?? []).filter((v) => typeof v === "number" && Number.isFinite(v));
|
|
6712
7200
|
const small = size === "sm";
|
|
6713
7201
|
const showSparkline = !small && showHistory && historyPoints.length >= SPARKLINE_MIN_POINTS;
|
|
6714
|
-
const isRate = formatKind(
|
|
7202
|
+
const isRate = formatKind(format) === "percent";
|
|
6715
7203
|
const byPoints = (targetDisplay ?? (isRate ? "points" : "achievement")) === "points";
|
|
6716
7204
|
const lower = polarity === "lower-is-better";
|
|
6717
7205
|
const targetBar = hasTarget && !neutral && !byPoints && !lower;
|
|
6718
|
-
if (summary !== void 0) warnShallowSummary(summary);
|
|
7206
|
+
if (summary !== void 0) warnShallowSummary(summary, t);
|
|
6719
7207
|
const cardClass = cn("row-span-2 grid content-start gap-y-0 grid-rows-subgrid", className);
|
|
6720
7208
|
const valueSize = small ? "text-xl @[218px]/card:text-2xl" : "text-2xl @[218px]/card:text-4xl";
|
|
6721
7209
|
if (isLoading) {
|
|
@@ -6757,15 +7245,15 @@ function KpiCard({
|
|
|
6757
7245
|
}
|
|
6758
7246
|
);
|
|
6759
7247
|
}
|
|
6760
|
-
const fmt = (v) => formatValue(v,
|
|
7248
|
+
const fmt = (v) => formatValue(v, format, locale);
|
|
6761
7249
|
const fmtDistance = (v) => isRate ? formatPoints(v, locale, { signDisplay: "never" }) : fmt(v);
|
|
6762
7250
|
const pct = (v) => formatValue(v, { type: "percent", digits: 0 }, locale);
|
|
6763
|
-
const tl = targetLabel;
|
|
6764
|
-
const display = change ?? defaultChangeDisplay(
|
|
6765
|
-
const digits = display === "points" && typeof
|
|
7251
|
+
const tl = targetLabel ?? t.target;
|
|
7252
|
+
const display = change ?? defaultChangeDisplay(format);
|
|
7253
|
+
const digits = display === "points" && typeof format === "object" && format !== null && "digits" in format ? format.digits : void 0;
|
|
6766
7254
|
const graded = comparison ? { ...comparison, grain } : void 0;
|
|
6767
|
-
const result = graded ? computeComparison(value, graded, { polarity, neutralBand }) : null;
|
|
6768
|
-
const baseline = graded ? comparisonBaseline(graded.vs, grain, graded.label, graded.toDate) : null;
|
|
7255
|
+
const result = graded ? computeComparison(value, graded, { polarity, neutralBand, locale }) : null;
|
|
7256
|
+
const baseline = graded ? comparisonBaseline(graded.vs, grain, graded.label, graded.toDate, locale) : null;
|
|
6769
7257
|
const progress = hasTarget && !neutral ? computeTargetProgress(value, target, { period, now, polarity }) : null;
|
|
6770
7258
|
const projectedValue = !isRate && !byPoints && progress?.projected != null && progress.elapsed ? value / progress.elapsed : null;
|
|
6771
7259
|
const summaryText = summary ? fillKpiTemplate(
|
|
@@ -6773,14 +7261,14 @@ function KpiCard({
|
|
|
6773
7261
|
{
|
|
6774
7262
|
value: fmt(value),
|
|
6775
7263
|
label: label2,
|
|
6776
|
-
delta: result ? formatChange(result, display, locale,
|
|
6777
|
-
difference: result?.difference != null ? isRate ? formatPoints(result.difference, locale) : formatDelta(result.difference,
|
|
7264
|
+
delta: result ? formatChange(result, display, locale, format, digits) : null,
|
|
7265
|
+
difference: result?.difference != null ? isRate ? formatPoints(result.difference, locale) : formatDelta(result.difference, format, locale) : null,
|
|
6778
7266
|
previous: result?.previous != null ? fmt(result.previous) : null,
|
|
6779
7267
|
target: hasTarget ? fmt(target) : null,
|
|
6780
7268
|
achievement: progress ? byPoints ? formatPoints(value - target, locale) : pct(progress.achievement) : null,
|
|
6781
7269
|
remaining: progress ? fmtDistance(progress.remaining) : null
|
|
6782
7270
|
},
|
|
6783
|
-
result && result.direction === "none" && baseline ?
|
|
7271
|
+
result && result.direction === "none" && baseline ? t.noBaseline(baseline) : null
|
|
6784
7272
|
) : null;
|
|
6785
7273
|
const bar = targetBar && progress ? progressBar() : null;
|
|
6786
7274
|
function progressBar() {
|
|
@@ -6788,9 +7276,9 @@ function KpiCard({
|
|
|
6788
7276
|
const projected = projectedValue !== null && projectedValue > actual ? projectedValue : actual;
|
|
6789
7277
|
const scale = Math.max(target, actual, projected);
|
|
6790
7278
|
const at = (v) => scale > 0 ? v / scale * 100 : 0;
|
|
6791
|
-
const parts = [
|
|
7279
|
+
const parts = [t.barLead(tl, pct(progress.achievement))];
|
|
6792
7280
|
if (projectedValue !== null && progress.projected != null)
|
|
6793
|
-
parts.push(
|
|
7281
|
+
parts.push(t.pace(formatValue(progress.projected, { type: "percent", digits: 0 }, locale)));
|
|
6794
7282
|
return {
|
|
6795
7283
|
actualAt: at(actual),
|
|
6796
7284
|
projectedAt: at(projected),
|
|
@@ -6803,13 +7291,13 @@ function KpiCard({
|
|
|
6803
7291
|
if (hasTarget && !bar) {
|
|
6804
7292
|
if (!progress) targetText = `${tl} ${fmt(target)}`;
|
|
6805
7293
|
else if (isProvisional)
|
|
6806
|
-
targetText = progress.achieved ? byPoints ?
|
|
7294
|
+
targetText = progress.achieved ? byPoints ? t.provisionalReached(tl, fmt(target)) : t.provisionalSoFar(tl, fmt(target), pct(progress.achievement)) : byPoints ? t.provisionalToGo(tl, fmt(target), fmtDistance(progress.remaining)) : t.provisionalToGoRate(tl, fmtDistance(progress.remaining), pct(progress.achievement));
|
|
6807
7295
|
else if (lower)
|
|
6808
|
-
targetText = progress.achieved ?
|
|
7296
|
+
targetText = progress.achieved ? t.met(tl, fmt(target)) : t.toGo(tl, fmt(target), fmtDistance(progress.remaining));
|
|
6809
7297
|
else if (byPoints)
|
|
6810
|
-
targetText = progress.achieved ?
|
|
7298
|
+
targetText = progress.achieved ? t.reached(tl, fmt(target)) : t.toGo(tl, fmt(target), fmtDistance(progress.remaining));
|
|
6811
7299
|
else
|
|
6812
|
-
targetText = progress.achieved ?
|
|
7300
|
+
targetText = progress.achieved ? t.reachedRate(tl, fmt(target), pct(progress.achievement)) : t.toGoRate(tl, fmtDistance(progress.remaining), pct(progress.achievement));
|
|
6813
7301
|
}
|
|
6814
7302
|
const hasFooter = Boolean(summaryText) || record !== null || Boolean(targetText) || sourceParts.length > 0 || hasUpdated || showSparkline;
|
|
6815
7303
|
const deltas = allComparisons.map((c, i) => /* @__PURE__ */ jsx(
|
|
@@ -6819,7 +7307,7 @@ function KpiCard({
|
|
|
6819
7307
|
comparison: i === 0 ? graded ?? c : { ...c, grain: c.grain ?? grain },
|
|
6820
7308
|
polarity,
|
|
6821
7309
|
neutralBand,
|
|
6822
|
-
format
|
|
7310
|
+
format,
|
|
6823
7311
|
change: display,
|
|
6824
7312
|
digits,
|
|
6825
7313
|
locale
|
|
@@ -6852,18 +7340,18 @@ function KpiCard({
|
|
|
6852
7340
|
}
|
|
6853
7341
|
),
|
|
6854
7342
|
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 })),
|
|
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 ?
|
|
7343
|
+
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 ? t.previous(baseline ?? "", fmt(result.previous)) : t.noPrevious(baseline ?? "") }),
|
|
6856
7344
|
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: [
|
|
6857
7345
|
/* @__PURE__ */ jsxs(
|
|
6858
7346
|
"div",
|
|
6859
7347
|
{
|
|
6860
7348
|
"data-slot": "kpi-card-target-bar",
|
|
6861
7349
|
role: "progressbar",
|
|
6862
|
-
"aria-label":
|
|
7350
|
+
"aria-label": t.progressLabel(tl),
|
|
6863
7351
|
"aria-valuemin": 0,
|
|
6864
7352
|
"aria-valuemax": target,
|
|
6865
7353
|
"aria-valuenow": Math.min(Math.max(value, 0), target),
|
|
6866
|
-
"aria-valuetext":
|
|
7354
|
+
"aria-valuetext": t.progressValue(tl, fmt(target), fmt(value), pct(progress.achievement)),
|
|
6867
7355
|
className: "relative h-2 w-full overflow-hidden rounded-full bg-muted",
|
|
6868
7356
|
children: [
|
|
6869
7357
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 left-0 bg-chart-1", style: { width: `${bar.actualAt}%` } }),
|
|
@@ -6890,15 +7378,15 @@ function KpiCard({
|
|
|
6890
7378
|
"p",
|
|
6891
7379
|
{
|
|
6892
7380
|
"data-slot": "kpi-card-target",
|
|
6893
|
-
title: [bar.lead, bar.pace].filter(Boolean).join(
|
|
7381
|
+
title: [bar.lead, bar.pace].filter(Boolean).join(t.joiner),
|
|
6894
7382
|
className: "truncate text-sm text-muted-foreground tabular-nums",
|
|
6895
7383
|
children: [
|
|
6896
7384
|
bar.lead,
|
|
6897
7385
|
bar.pace && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6898
|
-
|
|
7386
|
+
t.joiner,
|
|
6899
7387
|
/* @__PURE__ */ jsx("span", { "data-slot": "kpi-card-projection", "data-estimate": "", children: bar.pace })
|
|
6900
7388
|
] }),
|
|
6901
|
-
isProvisional &&
|
|
7389
|
+
isProvisional && t.provisionalSuffix
|
|
6902
7390
|
]
|
|
6903
7391
|
}
|
|
6904
7392
|
)
|
|
@@ -6912,12 +7400,12 @@ function KpiCard({
|
|
|
6912
7400
|
"p",
|
|
6913
7401
|
{
|
|
6914
7402
|
"data-slot": "kpi-card-source",
|
|
6915
|
-
title: sourceParts.join(
|
|
7403
|
+
title: sourceParts.join(t.joiner),
|
|
6916
7404
|
className: "line-clamp-2 w-full text-xs leading-normal text-muted-foreground tabular-nums",
|
|
6917
|
-
children: sourceParts.join(
|
|
7405
|
+
children: sourceParts.join(t.joiner)
|
|
6918
7406
|
}
|
|
6919
7407
|
),
|
|
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) }),
|
|
7408
|
+
hasUpdated && /* @__PURE__ */ jsx("p", { "data-slot": "kpi-card-updated", className: "text-xs leading-normal text-muted-foreground", children: updatedAtText(updatedAt, updatedAtDisplay, locale, t, now, timeZone) }),
|
|
6921
7409
|
showSparkline && // mt-auto: the footers of a row are as tall as the tallest, so the sparklines share one bottom edge.
|
|
6922
7410
|
/* @__PURE__ */ jsx("div", { "data-slot": "kpi-card-history", className: "mt-auto w-full pt-2 text-chart-1", children: /* @__PURE__ */ jsx(
|
|
6923
7411
|
Sparkline,
|
|
@@ -6926,18 +7414,30 @@ function KpiCard({
|
|
|
6926
7414
|
height: SPARKLINE_HEIGHT,
|
|
6927
7415
|
color: "text-chart-1",
|
|
6928
7416
|
highlight: "latest",
|
|
6929
|
-
"aria-label":
|
|
7417
|
+
"aria-label": t.history(label2, historyPoints.length)
|
|
6930
7418
|
}
|
|
6931
7419
|
) })
|
|
6932
7420
|
] })
|
|
6933
7421
|
] });
|
|
6934
7422
|
}
|
|
6935
|
-
function updatedAtText(updatedAt, display, locale, now, timeZone) {
|
|
7423
|
+
function updatedAtText(updatedAt, display, locale, t, now, timeZone) {
|
|
6936
7424
|
const relative2 = formatRelativeTime(updatedAt, { now, locale });
|
|
6937
|
-
if (display === "relative") return
|
|
7425
|
+
if (display === "relative") return t.updatedRelative(relative2);
|
|
6938
7426
|
const absolute2 = formatDate(updatedAt, "datetime", locale, { timeZone });
|
|
6939
|
-
return display === "absolute" ?
|
|
7427
|
+
return display === "absolute" ? t.updatedAbsolute(absolute2) : t.updatedBoth(absolute2, relative2);
|
|
6940
7428
|
}
|
|
7429
|
+
var TEXT20 = {
|
|
7430
|
+
ja: {
|
|
7431
|
+
flat: (value) => `\u5909\u5316\u306A\u3057 ${value}%`,
|
|
7432
|
+
up: (value) => `${value}% \u5897\u52A0`,
|
|
7433
|
+
down: (value) => `${value}% \u6E1B\u5C11`
|
|
7434
|
+
},
|
|
7435
|
+
en: {
|
|
7436
|
+
flat: (value) => `No change ${value}%`,
|
|
7437
|
+
up: (value) => `Up ${value}%`,
|
|
7438
|
+
down: (value) => `Down ${value}%`
|
|
7439
|
+
}
|
|
7440
|
+
};
|
|
6941
7441
|
var trendIndicatorVariants = cva("inline-flex items-center gap-0.5 text-sm font-medium", {
|
|
6942
7442
|
variants: {
|
|
6943
7443
|
sentiment: {
|
|
@@ -6955,7 +7455,8 @@ var TrendIndicator = forwardRef(
|
|
|
6955
7455
|
const isGood = direction === "neutral" ? null : direction === "up" === positiveIsGood;
|
|
6956
7456
|
const sentiment = isGood === null ? "neutral" : isGood ? "positive" : "negative";
|
|
6957
7457
|
const Icon = direction === "up" ? ArrowUp : direction === "down" ? ArrowDown : Minus;
|
|
6958
|
-
const
|
|
7458
|
+
const t = TEXT20[uiLanguage(useLocale())];
|
|
7459
|
+
const ariaLabel = direction === "neutral" ? t.flat(value) : direction === "up" ? t.up(value) : t.down(value);
|
|
6959
7460
|
return /* @__PURE__ */ jsxs(
|
|
6960
7461
|
"span",
|
|
6961
7462
|
{
|
|
@@ -6975,21 +7476,49 @@ var TrendIndicator = forwardRef(
|
|
|
6975
7476
|
}
|
|
6976
7477
|
);
|
|
6977
7478
|
TrendIndicator.displayName = "TrendIndicator";
|
|
7479
|
+
var STATUS_LABELS = {
|
|
7480
|
+
ja: {
|
|
7481
|
+
success: "\u6B63\u5E38",
|
|
7482
|
+
partial: "\u4E00\u90E8\u5931\u6557",
|
|
7483
|
+
failed: "\u5931\u6557",
|
|
7484
|
+
delayed: "\u9045\u5EF6",
|
|
7485
|
+
running: "\u5B9F\u884C\u4E2D",
|
|
7486
|
+
stopped: "\u505C\u6B62\u4E2D",
|
|
7487
|
+
active: "\u6709\u52B9",
|
|
7488
|
+
inactive: "\u7121\u52B9",
|
|
7489
|
+
warning: "\u8B66\u544A",
|
|
7490
|
+
error: "\u30A8\u30E9\u30FC",
|
|
7491
|
+
pending: "\u4FDD\u7559\u4E2D"
|
|
7492
|
+
},
|
|
7493
|
+
en: {
|
|
7494
|
+
success: "Healthy",
|
|
7495
|
+
partial: "Partially failed",
|
|
7496
|
+
failed: "Failed",
|
|
7497
|
+
delayed: "Delayed",
|
|
7498
|
+
running: "Running",
|
|
7499
|
+
stopped: "Stopped",
|
|
7500
|
+
active: "Active",
|
|
7501
|
+
inactive: "Inactive",
|
|
7502
|
+
warning: "Warning",
|
|
7503
|
+
error: "Error",
|
|
7504
|
+
pending: "Pending"
|
|
7505
|
+
}
|
|
7506
|
+
};
|
|
6978
7507
|
var STATUS_VOCABULARY = {
|
|
6979
|
-
success: { label:
|
|
6980
|
-
partial: { label:
|
|
6981
|
-
failed: { label:
|
|
6982
|
-
delayed: { label:
|
|
6983
|
-
running: { label:
|
|
6984
|
-
stopped: { label:
|
|
6985
|
-
active: { label:
|
|
6986
|
-
inactive: { label:
|
|
6987
|
-
warning: { label:
|
|
6988
|
-
error: { label:
|
|
6989
|
-
pending: { label:
|
|
7508
|
+
success: { label: STATUS_LABELS.en.success, tone: "positive" },
|
|
7509
|
+
partial: { label: STATUS_LABELS.en.partial, tone: "warning" },
|
|
7510
|
+
failed: { label: STATUS_LABELS.en.failed, tone: "negative" },
|
|
7511
|
+
delayed: { label: STATUS_LABELS.en.delayed, tone: "warning" },
|
|
7512
|
+
running: { label: STATUS_LABELS.en.running, tone: "info" },
|
|
7513
|
+
stopped: { label: STATUS_LABELS.en.stopped, tone: "neutral" },
|
|
7514
|
+
active: { label: STATUS_LABELS.en.active, tone: "positive" },
|
|
7515
|
+
inactive: { label: STATUS_LABELS.en.inactive, tone: "neutral" },
|
|
7516
|
+
warning: { label: STATUS_LABELS.en.warning, tone: "warning" },
|
|
7517
|
+
error: { label: STATUS_LABELS.en.error, tone: "negative" },
|
|
7518
|
+
pending: { label: STATUS_LABELS.en.pending, tone: "info" }
|
|
6990
7519
|
};
|
|
6991
|
-
function statusLabel(status) {
|
|
6992
|
-
return Object.hasOwn(STATUS_VOCABULARY, status) ?
|
|
7520
|
+
function statusLabel(status, locale) {
|
|
7521
|
+
return Object.hasOwn(STATUS_VOCABULARY, status) ? STATUS_LABELS[uiLanguage(resolveLocale(locale))][status] : status;
|
|
6993
7522
|
}
|
|
6994
7523
|
var defaultColorMap = Object.fromEntries(
|
|
6995
7524
|
Object.entries(STATUS_VOCABULARY).map(([key, { tone }]) => [key, tone])
|
|
@@ -7014,9 +7543,10 @@ var resolveTone = (color) => {
|
|
|
7014
7543
|
return legacyColorTones[color] ?? "neutral";
|
|
7015
7544
|
};
|
|
7016
7545
|
var StatusBadge = forwardRef(function StatusBadge2({ status, label: label2, colorMap, className }, ref) {
|
|
7546
|
+
const locale = useLocale();
|
|
7017
7547
|
const mergedColorMap = { ...defaultColorMap, ...colorMap };
|
|
7018
7548
|
const style = toneStyles[resolveTone(mergedColorMap[status])];
|
|
7019
|
-
const displayLabel = label2 ?? statusLabel(status);
|
|
7549
|
+
const displayLabel = label2 ?? statusLabel(status, locale);
|
|
7020
7550
|
return /* @__PURE__ */ jsxs(
|
|
7021
7551
|
Badge,
|
|
7022
7552
|
{
|
|
@@ -7047,5 +7577,5 @@ var Placeholder = forwardRef(function Placeholder2({ className, ...props }, ref)
|
|
|
7047
7577
|
Placeholder.displayName = "Placeholder";
|
|
7048
7578
|
|
|
7049
7579
|
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-
|
|
7051
|
-
//# sourceMappingURL=chunk-
|
|
7580
|
+
//# sourceMappingURL=chunk-77CISBMG.js.map
|
|
7581
|
+
//# sourceMappingURL=chunk-77CISBMG.js.map
|