@krizaka/charts 0.0.0-stage → 0.1.0
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/LICENSE +202 -0
- package/README.md +47 -2
- package/dist/bar.d.ts +17 -0
- package/dist/bar.js +16 -0
- package/dist/bar.js.map +1 -0
- package/dist/candlestick-IG626XL4.js +13 -0
- package/dist/candlestick-IG626XL4.js.map +1 -0
- package/dist/candlestick.d.ts +42 -0
- package/dist/candlestick.js +13 -0
- package/dist/candlestick.js.map +1 -0
- package/dist/canvas-4MSYDVFO.js +14 -0
- package/dist/canvas-4MSYDVFO.js.map +1 -0
- package/dist/cartesian-BRhNQ3ib.d.ts +34 -0
- package/dist/chart.d.ts +58 -0
- package/dist/chart.js +11 -0
- package/dist/chart.js.map +1 -0
- package/dist/chunk-3CJHBJXA.js +186 -0
- package/dist/chunk-3CJHBJXA.js.map +1 -0
- package/dist/chunk-6FINSUOS.js +49 -0
- package/dist/chunk-6FINSUOS.js.map +1 -0
- package/dist/chunk-7CSAGFBW.js +166 -0
- package/dist/chunk-7CSAGFBW.js.map +1 -0
- package/dist/chunk-7TIFCK5E.js +103 -0
- package/dist/chunk-7TIFCK5E.js.map +1 -0
- package/dist/chunk-AHQXJSAQ.js +38 -0
- package/dist/chunk-AHQXJSAQ.js.map +1 -0
- package/dist/chunk-ANUCSRUN.js +43 -0
- package/dist/chunk-ANUCSRUN.js.map +1 -0
- package/dist/chunk-BISL7DYW.js +66 -0
- package/dist/chunk-BISL7DYW.js.map +1 -0
- package/dist/chunk-BZ5CQFPH.js +19 -0
- package/dist/chunk-BZ5CQFPH.js.map +1 -0
- package/dist/chunk-DWJPPEMC.js +455 -0
- package/dist/chunk-DWJPPEMC.js.map +1 -0
- package/dist/chunk-DZB6HEVO.js +73 -0
- package/dist/chunk-DZB6HEVO.js.map +1 -0
- package/dist/chunk-EK3Z647J.js +133 -0
- package/dist/chunk-EK3Z647J.js.map +1 -0
- package/dist/chunk-I5QUZVU2.js +234 -0
- package/dist/chunk-I5QUZVU2.js.map +1 -0
- package/dist/chunk-OB5EFDDH.js +118 -0
- package/dist/chunk-OB5EFDDH.js.map +1 -0
- package/dist/chunk-OER6ETT4.js +155 -0
- package/dist/chunk-OER6ETT4.js.map +1 -0
- package/dist/chunk-PTSB3H5Q.js +205 -0
- package/dist/chunk-PTSB3H5Q.js.map +1 -0
- package/dist/chunk-TPJDOB7R.js +15 -0
- package/dist/chunk-TPJDOB7R.js.map +1 -0
- package/dist/chunk-UNK4MJVG.js +378 -0
- package/dist/chunk-UNK4MJVG.js.map +1 -0
- package/dist/chunk-VKO2OYYM.js +88 -0
- package/dist/chunk-VKO2OYYM.js.map +1 -0
- package/dist/chunk-VKTZD7UT.js +107 -0
- package/dist/chunk-VKTZD7UT.js.map +1 -0
- package/dist/chunk-W5FX4TU3.js +102 -0
- package/dist/chunk-W5FX4TU3.js.map +1 -0
- package/dist/chunk-WBH2QU77.js +178 -0
- package/dist/chunk-WBH2QU77.js.map +1 -0
- package/dist/chunk-WIRCIOLH.js +145 -0
- package/dist/chunk-WIRCIOLH.js.map +1 -0
- package/dist/chunk-XAJ3KCC4.js +116 -0
- package/dist/chunk-XAJ3KCC4.js.map +1 -0
- package/dist/chunk-XC6BQ3RN.js +92 -0
- package/dist/chunk-XC6BQ3RN.js.map +1 -0
- package/dist/chunk-XLLYNNC6.js +89 -0
- package/dist/chunk-XLLYNNC6.js.map +1 -0
- package/dist/chunk-XR4ZJDOV.js +15 -0
- package/dist/chunk-XR4ZJDOV.js.map +1 -0
- package/dist/context-BgYUymEO.d.ts +163 -0
- package/dist/frame-I7_xYGy5.d.ts +45 -0
- package/dist/full-S2MBPEEP.js +11 -0
- package/dist/full-S2MBPEEP.js.map +1 -0
- package/dist/funnel-QU5ZPC52.js +13 -0
- package/dist/funnel-QU5ZPC52.js.map +1 -0
- package/dist/funnel.d.ts +26 -0
- package/dist/funnel.js +13 -0
- package/dist/funnel.js.map +1 -0
- package/dist/gauge.d.ts +38 -0
- package/dist/gauge.js +12 -0
- package/dist/gauge.js.map +1 -0
- package/dist/geo.d.ts +37 -0
- package/dist/geo.js +13 -0
- package/dist/geo.js.map +1 -0
- package/dist/globe.d.ts +36 -0
- package/dist/globe.js +12 -0
- package/dist/globe.js.map +1 -0
- package/dist/heatmap-JWQOKUGM.js +13 -0
- package/dist/heatmap-JWQOKUGM.js.map +1 -0
- package/dist/heatmap.d.ts +47 -0
- package/dist/heatmap.js +15 -0
- package/dist/heatmap.js.map +1 -0
- package/dist/host-_F8RgiIz.d.ts +15 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/line.d.ts +25 -0
- package/dist/line.js +18 -0
- package/dist/line.js.map +1 -0
- package/dist/native.d.ts +300 -0
- package/dist/native.js +875 -0
- package/dist/native.js.map +1 -0
- package/dist/pie.d.ts +37 -0
- package/dist/pie.js +16 -0
- package/dist/pie.js.map +1 -0
- package/dist/provider.d.ts +73 -0
- package/dist/provider.js +24 -0
- package/dist/provider.js.map +1 -0
- package/dist/radar-75GRJ2IK.js +13 -0
- package/dist/radar-75GRJ2IK.js.map +1 -0
- package/dist/radar.d.ts +22 -0
- package/dist/radar.js +13 -0
- package/dist/radar.js.map +1 -0
- package/dist/sankey-XQTX2EG6.js +13 -0
- package/dist/sankey-XQTX2EG6.js.map +1 -0
- package/dist/sankey.d.ts +28 -0
- package/dist/sankey.js +13 -0
- package/dist/sankey.js.map +1 -0
- package/dist/scatter-XSNG4OKD.js +13 -0
- package/dist/scatter-XSNG4OKD.js.map +1 -0
- package/dist/scatter.d.ts +41 -0
- package/dist/scatter.js +15 -0
- package/dist/scatter.js.map +1 -0
- package/dist/sparkline.d.ts +26 -0
- package/dist/sparkline.js +15 -0
- package/dist/sparkline.js.map +1 -0
- package/dist/svg-BJUHYX3B.js +14 -0
- package/dist/svg-BJUHYX3B.js.map +1 -0
- package/dist/treemap-OMGGGB5U.js +13 -0
- package/dist/treemap-OMGGGB5U.js.map +1 -0
- package/dist/treemap.d.ts +24 -0
- package/dist/treemap.js +14 -0
- package/dist/treemap.js.map +1 -0
- package/dist/world-110m-DVFWXS42.js +18 -0
- package/dist/world-110m-DVFWXS42.js.map +1 -0
- package/package.json +518 -3
- package/registry/area-chart.json +784 -0
- package/registry/bar-chart.json +783 -0
- package/registry/calendar-heatmap.json +459 -0
- package/registry/candlestick.json +552 -0
- package/registry/chart.json +440 -0
- package/registry/charts-provider.json +190 -0
- package/registry/examples/area-chart/credits-usage.d.ts +4 -0
- package/registry/examples/area-chart/credits-usage.js +38 -0
- package/registry/examples/area-chart/credits-usage.tsx +32 -0
- package/registry/examples/area-chart/native/credits-usage.d.ts +4 -0
- package/registry/examples/area-chart/native/credits-usage.dark.png +0 -0
- package/registry/examples/area-chart/native/credits-usage.js +33 -0
- package/registry/examples/area-chart/native/credits-usage.light.png +0 -0
- package/registry/examples/area-chart/native/credits-usage.tsx +27 -0
- package/registry/examples/area-chart/storage.d.ts +4 -0
- package/registry/examples/area-chart/storage.js +27 -0
- package/registry/examples/area-chart/storage.tsx +21 -0
- package/registry/examples/bar-chart/jobs-by-status.d.ts +4 -0
- package/registry/examples/bar-chart/jobs-by-status.js +37 -0
- package/registry/examples/bar-chart/jobs-by-status.tsx +31 -0
- package/registry/examples/bar-chart/native/jobs-by-status.d.ts +4 -0
- package/registry/examples/bar-chart/native/jobs-by-status.dark.png +0 -0
- package/registry/examples/bar-chart/native/jobs-by-status.js +32 -0
- package/registry/examples/bar-chart/native/jobs-by-status.light.png +0 -0
- package/registry/examples/bar-chart/native/jobs-by-status.tsx +26 -0
- package/registry/examples/bar-chart/plans-by-quarter.d.ts +4 -0
- package/registry/examples/bar-chart/plans-by-quarter.js +31 -0
- package/registry/examples/bar-chart/plans-by-quarter.tsx +26 -0
- package/registry/examples/bar-chart/top-supporters.d.ts +4 -0
- package/registry/examples/bar-chart/top-supporters.js +32 -0
- package/registry/examples/bar-chart/top-supporters.tsx +27 -0
- package/registry/examples/calendar-heatmap/publishing.d.ts +4 -0
- package/registry/examples/calendar-heatmap/publishing.js +28 -0
- package/registry/examples/calendar-heatmap/publishing.tsx +23 -0
- package/registry/examples/candlestick/auction-bids.d.ts +4 -0
- package/registry/examples/candlestick/auction-bids.js +37 -0
- package/registry/examples/candlestick/auction-bids.tsx +32 -0
- package/registry/examples/chart/polar-uploads.d.ts +4 -0
- package/registry/examples/chart/polar-uploads.js +34 -0
- package/registry/examples/chart/polar-uploads.tsx +30 -0
- package/registry/examples/charts-provider/french-orazaka.d.ts +4 -0
- package/registry/examples/charts-provider/french-orazaka.js +26 -0
- package/registry/examples/charts-provider/french-orazaka.tsx +22 -0
- package/registry/examples/charts-provider/native/french-orazaka.d.ts +4 -0
- package/registry/examples/charts-provider/native/french-orazaka.dark.png +0 -0
- package/registry/examples/charts-provider/native/french-orazaka.js +17 -0
- package/registry/examples/charts-provider/native/french-orazaka.light.png +0 -0
- package/registry/examples/charts-provider/native/french-orazaka.tsx +17 -0
- package/registry/examples/funnel/signup.d.ts +4 -0
- package/registry/examples/funnel/signup.js +30 -0
- package/registry/examples/funnel/signup.tsx +24 -0
- package/registry/examples/gauge/challenge-goal.d.ts +4 -0
- package/registry/examples/gauge/challenge-goal.js +24 -0
- package/registry/examples/gauge/challenge-goal.tsx +18 -0
- package/registry/examples/gauge/credits-quota.d.ts +4 -0
- package/registry/examples/gauge/credits-quota.js +26 -0
- package/registry/examples/gauge/credits-quota.tsx +19 -0
- package/registry/examples/gauge/native/credits-quota.d.ts +4 -0
- package/registry/examples/gauge/native/credits-quota.dark.png +0 -0
- package/registry/examples/gauge/native/credits-quota.js +25 -0
- package/registry/examples/gauge/native/credits-quota.light.png +0 -0
- package/registry/examples/gauge/native/credits-quota.tsx +18 -0
- package/registry/examples/geo-map/viewers.d.ts +4 -0
- package/registry/examples/geo-map/viewers.js +43 -0
- package/registry/examples/geo-map/viewers.tsx +29 -0
- package/registry/examples/globe/deployment-regions.d.ts +4 -0
- package/registry/examples/globe/deployment-regions.js +36 -0
- package/registry/examples/globe/deployment-regions.tsx +30 -0
- package/registry/examples/heatmap/upload-activity.d.ts +4 -0
- package/registry/examples/heatmap/upload-activity.js +30 -0
- package/registry/examples/heatmap/upload-activity.tsx +25 -0
- package/registry/examples/line-chart/creator-earnings.d.ts +4 -0
- package/registry/examples/line-chart/creator-earnings.js +35 -0
- package/registry/examples/line-chart/creator-earnings.tsx +30 -0
- package/registry/examples/line-chart/forecast.d.ts +4 -0
- package/registry/examples/line-chart/forecast.js +36 -0
- package/registry/examples/line-chart/forecast.tsx +30 -0
- package/registry/examples/line-chart/live-jobs.d.ts +4 -0
- package/registry/examples/line-chart/live-jobs.js +21 -0
- package/registry/examples/line-chart/live-jobs.tsx +23 -0
- package/registry/examples/line-chart/native/creator-earnings.d.ts +4 -0
- package/registry/examples/line-chart/native/creator-earnings.dark.png +0 -0
- package/registry/examples/line-chart/native/creator-earnings.js +32 -0
- package/registry/examples/line-chart/native/creator-earnings.light.png +0 -0
- package/registry/examples/line-chart/native/creator-earnings.tsx +26 -0
- package/registry/examples/line-chart/states.d.ts +4 -0
- package/registry/examples/line-chart/states.js +16 -0
- package/registry/examples/line-chart/states.tsx +13 -0
- package/registry/examples/pie-chart/credit-spend.d.ts +4 -0
- package/registry/examples/pie-chart/credit-spend.js +30 -0
- package/registry/examples/pie-chart/credit-spend.tsx +24 -0
- package/registry/examples/pie-chart/native/credit-spend.d.ts +4 -0
- package/registry/examples/pie-chart/native/credit-spend.dark.png +0 -0
- package/registry/examples/pie-chart/native/credit-spend.js +17 -0
- package/registry/examples/pie-chart/native/credit-spend.light.png +0 -0
- package/registry/examples/pie-chart/native/credit-spend.tsx +12 -0
- package/registry/examples/pie-chart/storage-by-kind.d.ts +4 -0
- package/registry/examples/pie-chart/storage-by-kind.js +31 -0
- package/registry/examples/pie-chart/storage-by-kind.tsx +26 -0
- package/registry/examples/radar-chart/model-comparison.d.ts +4 -0
- package/registry/examples/radar-chart/model-comparison.js +33 -0
- package/registry/examples/radar-chart/model-comparison.tsx +28 -0
- package/registry/examples/sankey/credit-flow.d.ts +4 -0
- package/registry/examples/sankey/credit-flow.js +37 -0
- package/registry/examples/sankey/credit-flow.tsx +32 -0
- package/registry/examples/scatter-chart/watch-time.d.ts +4 -0
- package/registry/examples/scatter-chart/watch-time.js +36 -0
- package/registry/examples/scatter-chart/watch-time.tsx +31 -0
- package/registry/examples/sparkline/bars.d.ts +4 -0
- package/registry/examples/sparkline/bars.js +12 -0
- package/registry/examples/sparkline/bars.tsx +7 -0
- package/registry/examples/sparkline/native/stat-trend.d.ts +4 -0
- package/registry/examples/sparkline/native/stat-trend.dark.png +0 -0
- package/registry/examples/sparkline/native/stat-trend.js +12 -0
- package/registry/examples/sparkline/native/stat-trend.light.png +0 -0
- package/registry/examples/sparkline/native/stat-trend.tsx +7 -0
- package/registry/examples/sparkline/stat-trend.d.ts +4 -0
- package/registry/examples/sparkline/stat-trend.js +18 -0
- package/registry/examples/sparkline/stat-trend.tsx +15 -0
- package/registry/examples/sparkline/table-rows.d.ts +4 -0
- package/registry/examples/sparkline/table-rows.js +23 -0
- package/registry/examples/sparkline/table-rows.tsx +26 -0
- package/registry/examples/treemap/storage.d.ts +4 -0
- package/registry/examples/treemap/storage.js +17 -0
- package/registry/examples/treemap/storage.tsx +13 -0
- package/registry/funnel.json +486 -0
- package/registry/gauge.json +599 -0
- package/registry/geo-map.json +483 -0
- package/registry/globe.json +468 -0
- package/registry/heatmap.json +530 -0
- package/registry/index.json +420 -0
- package/registry/line-chart.json +792 -0
- package/registry/pie-chart.json +1287 -0
- package/registry/radar-chart.json +458 -0
- package/registry/sankey.json +502 -0
- package/registry/scatter-chart.json +558 -0
- package/registry/sparkline.json +562 -0
- package/registry/treemap.json +431 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/gauge/gauge.tsx"],"sourcesContent":["\"use client\";\n// One value against its range: a 240° arc, the value written in the middle, an optional target tick and coloured\n// zones (a quota that turns to warning, then danger). Plain SVG; exposed as a `meter` (value, range and its words).\nimport { useMemo } from \"react\";\n\nimport { valueFormatter } from \"../core/format\";\nimport { fill } from \"../core/labels\";\nimport { polar, strokeArcPath } from \"../core/shape\";\nimport type { Threshold, Tone, ValueFormat } from \"../core/types\";\nimport { ChartFrame, type ChartFrameProps, useSettings } from \"../web/frame\";\nimport { colorOf } from \"../web/parts\";\n\nexport interface GaugeZone {\n /** The zone runs from the previous one's end (or `min`) to this value. */\n readonly to: number;\n readonly tone: Tone;\n /** Its name, in the summary and the table (“Over quota”). */\n readonly label?: string;\n}\n\nexport interface GaugeProps extends Omit<ChartFrameProps, \"dataTable\" | \"exportable\"> {\n /** The value. */\n/** The value. */\n value: number;\n /** The start of the range. Default 0. */\n/** The start of the range. Default 0. */\n min?: number;\n /** The end of the range. Default 100. */\n/** The end of the range. Default 100. */\n max?: number;\n /** How the value is written. */\n/** How the value and the range are written. */\n format?: ValueFormat;\n /** The words under the value (“of 50 000 credits”). */\n caption?: string;\n /** A tick on the arc: the objective. */\n target?: Threshold;\n /** Coloured zones along the arc: the value takes the tone of the zone it is in. */\n zones?: readonly GaugeZone[];\n /** The tone of the value without zones. Default `\"accent\"`. */\n/** The tone of the value without zones. Default `\"accent\"`. */\n tone?: Tone;\n}\n\nconst START = (-120 * Math.PI) / 180;\nconst END = (120 * Math.PI) / 180;\n\n/** One figure against its range — credits used of a plan, a challenge's progress, a load. */\nexport function Gauge(props: GaugeProps) {\n const { value, min = 0, max = 100, format, caption, target, zones = [], tone = \"accent\" } = props;\n const { locale, labels } = useSettings(props);\n const fmt = useMemo(() => valueFormatter(format, locale, labels.noValue), [format, locale, labels.noValue]);\n const clamped = Math.min(max, Math.max(min, value));\n const ratio = max > min ? (clamped - min) / (max - min) : 0;\n const zone = zones.find((z) => clamped <= z.to) ?? zones[zones.length - 1];\n const color = colorOf(zone?.tone ?? tone, 1);\n const text = fmt(value);\n const summary = [\n `${labels.kinds.gauge}: ${text} (${min === 0 ? \"\" : `${fmt(min)} – `}${fmt(max)})${zone?.label ? `, ${zone.label}` : \"\"}.`,\n target ? `${fill(labels.summaryThreshold, { label: target.label, value: fmt(target.value) })}.` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n const table = { columns: [labels.category, labels.value], rows: [[props.title, text], [\"min\", fmt(min)], [\"max\", fmt(max)], ...(target ? [[target.label, fmt(target.value)]] : [])] };\n const at = (v: number) => START + ((Math.min(max, Math.max(min, v)) - min) / (max - min || 1)) * (END - START);\n\n return (\n <ChartFrame kind=\"gauge\" frame={{ ...props, dataTable: false }} defaultHeight={180} table={table} summary={summary} isEmpty={false} navigable={false}>\n {(width, height) => {\n // The arc spans 240°: its lowest points sit at half the radius below the centre, the range labels under them.\n const radius = Math.max(20, Math.min(width / 2 - 12, (height - 30) / 1.58));\n const cx = width / 2;\n const cy = 8 + radius;\n const stroke = Math.max(8, radius * 0.16);\n let from = min;\n return (\n <div role=\"meter\" aria-label={props.title} aria-valuemin={min} aria-valuemax={max} aria-valuenow={clamped} aria-valuetext={caption ? `${text} ${caption}` : text} style={{ height: \"100%\" }}>\n <svg className=\"kzc-svg\" width={width} height={height} viewBox={`0 0 ${width} ${height}`} aria-hidden>\n <path d={strokeArcPath(cx, cy, radius, START, END)} style={{ fill: \"none\", stroke: \"var(--kz-surface-3)\", strokeWidth: stroke, strokeLinecap: \"round\" }} />\n {zones.map((z, i) => {\n const d = strokeArcPath(cx, cy, radius + stroke / 2 + 4, at(from), at(z.to));\n from = z.to;\n return <path key={i} d={d} data-tone={z.tone} style={{ fill: \"none\", stroke: \"var(--kzc-tone)\", strokeWidth: 3, opacity: 0.7 }} />;\n })}\n {ratio > 0 && (\n <path d={strokeArcPath(cx, cy, radius, START, at(clamped))} pathLength={1} className=\"kzc-line kzc-enter-line\" style={{ stroke: color, strokeWidth: stroke }} />\n )}\n {target && (\n <g data-tone={target.tone ?? \"neutral\"}>\n <line\n x1={polar(cx, cy, radius - stroke, at(target.value))[0]}\n y1={polar(cx, cy, radius - stroke, at(target.value))[1]}\n x2={polar(cx, cy, radius + stroke, at(target.value))[0]}\n y2={polar(cx, cy, radius + stroke, at(target.value))[1]}\n style={{ stroke: \"var(--kzc-text)\", strokeWidth: 2, strokeLinecap: \"round\" }}\n />\n </g>\n )}\n <text x={cx} y={cy} textAnchor=\"middle\" dominantBaseline=\"central\" className=\"kzc-strong\" style={{ fontSize: Math.max(12, Math.min(32, radius / 2.6, (radius * 1.45) / (text.length * 0.58))) }}>\n {text}\n </text>\n {caption && (\n <text x={cx} y={cy + Math.max(16, radius / 3.2)} textAnchor=\"middle\" dominantBaseline=\"central\">\n {caption}\n </text>\n )}\n <text x={polar(cx, cy, radius, START)[0]} y={polar(cx, cy, radius, START)[1] + stroke + 6} textAnchor=\"middle\">\n {fmt(min)}\n </text>\n <text x={polar(cx, cy, radius, END)[0]} y={polar(cx, cy, radius, END)[1] + stroke + 6} textAnchor=\"middle\">\n {fmt(max)}\n </text>\n </svg>\n </div>\n );\n }}\n </ChartFrame>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
EChartHost,
|
|
4
|
+
baseOption,
|
|
5
|
+
tooltipHtml,
|
|
6
|
+
valueAxis
|
|
7
|
+
} from "./chunk-I5QUZVU2.js";
|
|
8
|
+
import {
|
|
9
|
+
read
|
|
10
|
+
} from "./chunk-W5FX4TU3.js";
|
|
11
|
+
import {
|
|
12
|
+
valueFormatter
|
|
13
|
+
} from "./chunk-XLLYNNC6.js";
|
|
14
|
+
import {
|
|
15
|
+
Legend,
|
|
16
|
+
useSettings
|
|
17
|
+
} from "./chunk-DWJPPEMC.js";
|
|
18
|
+
import {
|
|
19
|
+
fill
|
|
20
|
+
} from "./chunk-3CJHBJXA.js";
|
|
21
|
+
|
|
22
|
+
// src/scatter/scatter-chart.tsx
|
|
23
|
+
import { formatNumber } from "@krizaka/intl";
|
|
24
|
+
import { useCallback, useMemo } from "react";
|
|
25
|
+
import { jsx } from "react/jsx-runtime";
|
|
26
|
+
var engine = () => import("./scatter-XSNG4OKD.js");
|
|
27
|
+
function correlation(points) {
|
|
28
|
+
const n = points.length;
|
|
29
|
+
if (n < 3) return null;
|
|
30
|
+
const mx = points.reduce((s, p) => s + p.x, 0) / n;
|
|
31
|
+
const my = points.reduce((s, p) => s + p.y, 0) / n;
|
|
32
|
+
let sxy = 0;
|
|
33
|
+
let sxx = 0;
|
|
34
|
+
let syy = 0;
|
|
35
|
+
for (const p of points) {
|
|
36
|
+
sxy += (p.x - mx) * (p.y - my);
|
|
37
|
+
sxx += (p.x - mx) ** 2;
|
|
38
|
+
syy += (p.y - my) ** 2;
|
|
39
|
+
}
|
|
40
|
+
return sxx && syy ? sxy / Math.sqrt(sxx * syy) : null;
|
|
41
|
+
}
|
|
42
|
+
function ScatterChart(props) {
|
|
43
|
+
const { data, x, y, size, group, name, xFormat, yFormat, sizeFormat, xLabel, yLabel, sizeLabel, thresholds = [] } = props;
|
|
44
|
+
const { locale, labels } = useSettings(props);
|
|
45
|
+
const fmt = useMemo(
|
|
46
|
+
() => ({
|
|
47
|
+
x: valueFormatter(xFormat, locale, labels.noValue),
|
|
48
|
+
xAxis: valueFormatter(xFormat, locale, labels.noValue, true),
|
|
49
|
+
y: valueFormatter(yFormat, locale, labels.noValue),
|
|
50
|
+
yAxis: valueFormatter(yFormat, locale, labels.noValue, true),
|
|
51
|
+
size: valueFormatter(sizeFormat, locale, labels.noValue)
|
|
52
|
+
}),
|
|
53
|
+
[xFormat, yFormat, sizeFormat, locale, labels.noValue]
|
|
54
|
+
);
|
|
55
|
+
const points = useMemo(
|
|
56
|
+
() => data.map((d, i) => ({ x: Number(read(x, d, i)), y: Number(read(y, d, i)), s: size ? Number(read(size, d, i)) : null, g: group ? String(read(group, d, i)) : "", n: name ? String(read(name, d, i)) : "" })).filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)),
|
|
57
|
+
[data, x, y, size, group, name]
|
|
58
|
+
);
|
|
59
|
+
const groups = useMemo(() => [...new Set(points.map((p) => p.g))], [points]);
|
|
60
|
+
const isEmpty = points.length === 0;
|
|
61
|
+
const r = correlation(points);
|
|
62
|
+
const range = (values, write) => `${write(Math.min(...values))} \u2013 ${write(Math.max(...values))}`;
|
|
63
|
+
const summary = isEmpty ? labels.empty : [
|
|
64
|
+
fill(labels.summaryIntro, { kind: labels.kinds.scatter, count: points.length }),
|
|
65
|
+
`${xLabel}: ${range(points.map((p) => p.x), fmt.x)}; ${yLabel}: ${range(points.map((p) => p.y), fmt.y)}${r === null ? "" : `; ${fill(labels.summaryCorrelation, { r: formatNumber(r, { locale, maximumFractionDigits: 2, minimumFractionDigits: 2 }) })}`}.`
|
|
66
|
+
].join(" ");
|
|
67
|
+
const bySeries = useMemo(() => groups.map((g) => points.filter((p) => p.g === g)), [groups, points]);
|
|
68
|
+
const items = bySeries.flatMap(
|
|
69
|
+
(list, s) => list.map((p, i) => ({ seriesIndex: s, dataIndex: i, text: `${p.n || p.g}${p.n || p.g ? ": " : ""}${xLabel} ${fmt.x(p.x)}, ${yLabel} ${fmt.y(p.y)}${p.s != null && sizeLabel ? `, ${sizeLabel} ${fmt.size(p.s)}` : ""}` }))
|
|
70
|
+
);
|
|
71
|
+
const maxSize = Math.max(0, ...points.map((p) => p.s ?? 0));
|
|
72
|
+
const build = useCallback(
|
|
73
|
+
(theme) => {
|
|
74
|
+
const base = baseOption(theme, true);
|
|
75
|
+
return {
|
|
76
|
+
...base,
|
|
77
|
+
tooltip: {
|
|
78
|
+
...base.tooltip,
|
|
79
|
+
trigger: "item",
|
|
80
|
+
formatter: (p) => {
|
|
81
|
+
const point = bySeries[p.seriesIndex][p.dataIndex];
|
|
82
|
+
return tooltipHtml(point.n || point.g || void 0, [
|
|
83
|
+
{ label: xLabel, value: fmt.x(point.x), color: theme.palette[p.seriesIndex % 8] },
|
|
84
|
+
{ label: yLabel, value: fmt.y(point.y) },
|
|
85
|
+
...point.s != null && sizeLabel ? [{ label: sizeLabel, value: fmt.size(point.s) }] : []
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
grid: { left: 8, right: 16, top: 16, bottom: 28, containLabel: true },
|
|
90
|
+
xAxis: { ...valueAxis(theme, (v) => fmt.xAxis(v)), scale: true, name: xLabel, nameLocation: "middle", nameGap: 26, nameTextStyle: { color: theme.text2 } },
|
|
91
|
+
yAxis: { ...valueAxis(theme, (v) => fmt.yAxis(v)), scale: true },
|
|
92
|
+
series: bySeries.map((list, s) => ({
|
|
93
|
+
type: "scatter",
|
|
94
|
+
name: groups[s],
|
|
95
|
+
data: list.map((p) => [p.x, p.y, p.s ?? 0]),
|
|
96
|
+
symbolSize: (value) => size && maxSize ? 6 + Math.sqrt((value[2] ?? 0) / maxSize) * 30 : 9,
|
|
97
|
+
itemStyle: { color: theme.palette[s % 8], opacity: size ? 0.7 : 0.9, borderColor: theme.surface, borderWidth: 1.5 },
|
|
98
|
+
emphasis: { itemStyle: { opacity: 1, borderColor: theme.text, borderWidth: 2 } },
|
|
99
|
+
markLine: s === 0 && thresholds.length ? {
|
|
100
|
+
symbol: "none",
|
|
101
|
+
silent: true,
|
|
102
|
+
data: thresholds.map((t) => ({ yAxis: t.value, label: { formatter: fill(labels.summaryThreshold, { label: t.label, value: fmt.y(t.value) }), color: theme.text, position: "insideEndTop", fontWeight: 600 }, lineStyle: { color: theme.text2, type: [6, 4], width: 1.5 } }))
|
|
103
|
+
} : void 0
|
|
104
|
+
}))
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
[bySeries, groups, fmt, xLabel, yLabel, sizeLabel, size, maxSize, thresholds, labels.summaryThreshold]
|
|
108
|
+
);
|
|
109
|
+
return /* @__PURE__ */ jsx(
|
|
110
|
+
EChartHost,
|
|
111
|
+
{
|
|
112
|
+
kind: "scatter",
|
|
113
|
+
frame: props,
|
|
114
|
+
defaultHeight: 320,
|
|
115
|
+
table: {
|
|
116
|
+
columns: [labels.category, xLabel, yLabel, ...size ? [sizeLabel ?? labels.value] : []],
|
|
117
|
+
rows: points.map((p, i) => [p.n || p.g || String(i + 1), fmt.x(p.x), fmt.y(p.y), ...size ? [fmt.size(p.s)] : []])
|
|
118
|
+
},
|
|
119
|
+
summary,
|
|
120
|
+
isEmpty,
|
|
121
|
+
legend: group ? /* @__PURE__ */ jsx(Legend, { items: groups.map((g, i) => ({ label: g, color: `var(--kzc-${i % 8 + 1})` })) }) : null,
|
|
122
|
+
engine,
|
|
123
|
+
build,
|
|
124
|
+
items
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
correlation,
|
|
131
|
+
ScatterChart
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=chunk-EK3Z647J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scatter/scatter-chart.tsx"],"sourcesContent":["\"use client\";\n// The relation between two measures — a video's length against its watch time, a job's input size against its\n// duration — a bubble's area for a third, a colour per group. The summary says what the eye looks for: the ranges and\n// the correlation (Pearson's r). The canvas renderer takes tens of thousands of points. ECharts, loaded when the chart\n// nears the screen.\nimport { formatNumber } from \"@krizaka/intl\";\nimport { useCallback, useMemo } from \"react\";\n\nimport { read } from \"../core/data\";\nimport { valueFormatter } from \"../core/format\";\nimport { fill } from \"../core/labels\";\nimport type { Accessor, Datum, Threshold, ValueFormat } from \"../core/types\";\nimport { EChartHost, type EngineProps, type WalkItem } from \"../echarts/host\";\nimport { baseOption, type ResolvedTheme, tooltipHtml, valueAxis } from \"../echarts/theme\";\nimport type { ChartFrameProps } from \"../web/frame\";\nimport { useSettings } from \"../web/frame\";\nimport { Legend } from \"../web/parts\";\n\nconst engine = () => import(\"../echarts/engines/scatter\");\n\nexport interface ScatterChartProps<T extends Datum> extends ChartFrameProps, EngineProps {\n /** One row per point. */\n data: readonly T[];\n /** The fields of the two measures. */\n x: Accessor<T, number>;\n/** The field of the vertical measure. */\n y: Accessor<T, number>;\n /** A third measure, drawn as the bubble's area. */\n size?: Accessor<T, number>;\n /** The field of a point's group: one colour per group (three at most read apart for everyone). */\n group?: Accessor<T, string>;\n /** The field naming a point (the tooltip's title). */\n name?: Accessor<T, string>;\n /** How each measure is written. */\n xFormat?: ValueFormat;\n/** How the vertical measure is written. */\n yFormat?: ValueFormat;\n/** How the third measure (the bubbles) is written. */\n sizeFormat?: ValueFormat;\n /** The names of the measures: the axes, the tooltip, the table. */\n xLabel: string;\n/** The name of the vertical measure. */\n yLabel: string;\n/** The name of the third measure. */\n sizeLabel?: string;\n /** Horizontal lines at a y value. */\n thresholds?: readonly Threshold[];\n}\n\n/** Pearson's correlation coefficient, or null under three points or without variance. */\nexport function correlation(points: readonly { x: number; y: number }[]): number | null {\n const n = points.length;\n if (n < 3) return null;\n const mx = points.reduce((s, p) => s + p.x, 0) / n;\n const my = points.reduce((s, p) => s + p.y, 0) / n;\n let sxy = 0;\n let sxx = 0;\n let syy = 0;\n for (const p of points) {\n sxy += (p.x - mx) * (p.y - my);\n sxx += (p.x - mx) ** 2;\n syy += (p.y - my) ** 2;\n }\n return sxx && syy ? sxy / Math.sqrt(sxx * syy) : null;\n}\n\nexport function ScatterChart<T extends Datum>(props: ScatterChartProps<T>) {\n const { data, x, y, size, group, name, xFormat, yFormat, sizeFormat, xLabel, yLabel, sizeLabel, thresholds = [] } = props;\n const { locale, labels } = useSettings(props);\n const fmt = useMemo(\n () => ({\n x: valueFormatter(xFormat, locale, labels.noValue),\n xAxis: valueFormatter(xFormat, locale, labels.noValue, true),\n y: valueFormatter(yFormat, locale, labels.noValue),\n yAxis: valueFormatter(yFormat, locale, labels.noValue, true),\n size: valueFormatter(sizeFormat, locale, labels.noValue),\n }),\n [xFormat, yFormat, sizeFormat, locale, labels.noValue],\n );\n const points = useMemo(\n () =>\n data\n .map((d, i) => ({ x: Number(read(x, d, i)), y: Number(read(y, d, i)), s: size ? Number(read(size, d, i)) : null, g: group ? String(read(group, d, i)) : \"\", n: name ? String(read(name, d, i)) : \"\" }))\n .filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)),\n [data, x, y, size, group, name],\n );\n const groups = useMemo(() => [...new Set(points.map((p) => p.g))], [points]);\n const isEmpty = points.length === 0;\n const r = correlation(points);\n const range = (values: number[], write: (v: number) => string) => `${write(Math.min(...values))} – ${write(Math.max(...values))}`;\n const summary = isEmpty\n ? labels.empty\n : [\n fill(labels.summaryIntro, { kind: labels.kinds.scatter, count: points.length }),\n `${xLabel}: ${range(points.map((p) => p.x), fmt.x)}; ${yLabel}: ${range(points.map((p) => p.y), fmt.y)}${r === null ? \"\" : `; ${fill(labels.summaryCorrelation, { r: formatNumber(r, { locale, maximumFractionDigits: 2, minimumFractionDigits: 2 }) })}`}.`,\n ].join(\" \");\n const bySeries = useMemo(() => groups.map((g) => points.filter((p) => p.g === g)), [groups, points]);\n const items: WalkItem[] = bySeries.flatMap((list, s) =>\n list.map((p, i) => ({ seriesIndex: s, dataIndex: i, text: `${p.n || p.g}${p.n || p.g ? \": \" : \"\"}${xLabel} ${fmt.x(p.x)}, ${yLabel} ${fmt.y(p.y)}${p.s != null && sizeLabel ? `, ${sizeLabel} ${fmt.size(p.s)}` : \"\"}` })),\n );\n const maxSize = Math.max(0, ...points.map((p) => p.s ?? 0));\n\n const build = useCallback(\n (theme: ResolvedTheme) => {\n const base = baseOption(theme, true);\n return {\n ...base,\n tooltip: {\n ...(base.tooltip as object),\n trigger: \"item\",\n formatter: (p: { seriesIndex: number; dataIndex: number }) => {\n const point = bySeries[p.seriesIndex]![p.dataIndex]!;\n return tooltipHtml(point.n || point.g || undefined, [\n { label: xLabel, value: fmt.x(point.x), color: theme.palette[p.seriesIndex % 8] },\n { label: yLabel, value: fmt.y(point.y) },\n ...(point.s != null && sizeLabel ? [{ label: sizeLabel, value: fmt.size(point.s) }] : []),\n ]);\n },\n },\n grid: { left: 8, right: 16, top: 16, bottom: 28, containLabel: true },\n xAxis: { ...valueAxis(theme, (v: number) => fmt.xAxis(v)), scale: true, name: xLabel, nameLocation: \"middle\", nameGap: 26, nameTextStyle: { color: theme.text2 } },\n yAxis: { ...valueAxis(theme, (v: number) => fmt.yAxis(v)), scale: true },\n series: bySeries.map((list, s) => ({\n type: \"scatter\",\n name: groups[s],\n data: list.map((p) => [p.x, p.y, p.s ?? 0]),\n symbolSize: (value: number[]) => (size && maxSize ? 6 + Math.sqrt((value[2] ?? 0) / maxSize) * 30 : 9),\n itemStyle: { color: theme.palette[s % 8], opacity: size ? 0.7 : 0.9, borderColor: theme.surface, borderWidth: 1.5 },\n emphasis: { itemStyle: { opacity: 1, borderColor: theme.text, borderWidth: 2 } },\n markLine:\n s === 0 && thresholds.length\n ? {\n symbol: \"none\",\n silent: true,\n data: thresholds.map((t) => ({ yAxis: t.value, label: { formatter: fill(labels.summaryThreshold, { label: t.label, value: fmt.y(t.value) }), color: theme.text, position: \"insideEndTop\", fontWeight: 600 }, lineStyle: { color: theme.text2, type: [6, 4], width: 1.5 } })),\n }\n : undefined,\n })),\n };\n },\n [bySeries, groups, fmt, xLabel, yLabel, sizeLabel, size, maxSize, thresholds, labels.summaryThreshold],\n );\n\n return (\n <EChartHost\n kind=\"scatter\"\n frame={props}\n defaultHeight={320}\n table={{\n columns: [labels.category, xLabel, yLabel, ...(size ? [sizeLabel ?? labels.value] : [])],\n rows: points.map((p, i) => [p.n || p.g || String(i + 1), fmt.x(p.x), fmt.y(p.y), ...(size ? [fmt.size(p.s)] : [])]),\n }}\n summary={summary}\n isEmpty={isEmpty}\n legend={group ? <Legend items={groups.map((g, i) => ({ label: g, color: `var(--kzc-${(i % 8) + 1})` }))} /> : null}\n engine={engine}\n build={build}\n items={items}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ChartFrame,
|
|
4
|
+
resolveColor,
|
|
5
|
+
useInView,
|
|
6
|
+
useReducedMotion,
|
|
7
|
+
useThemeVersion
|
|
8
|
+
} from "./chunk-DWJPPEMC.js";
|
|
9
|
+
import {
|
|
10
|
+
sequential
|
|
11
|
+
} from "./chunk-3CJHBJXA.js";
|
|
12
|
+
|
|
13
|
+
// src/echarts/theme.ts
|
|
14
|
+
var ROLES = {
|
|
15
|
+
text: "--kz-text-primary",
|
|
16
|
+
text2: "--kz-text-secondary",
|
|
17
|
+
text3: "--kz-text-muted",
|
|
18
|
+
grid: "--kz-border-subtle",
|
|
19
|
+
axis: "--kz-border-default",
|
|
20
|
+
surface: "--kz-surface-1",
|
|
21
|
+
surface2: "--kz-surface-2",
|
|
22
|
+
surface3: "--kz-surface-3",
|
|
23
|
+
border: "--kz-border-default",
|
|
24
|
+
accent: "--kz-accent",
|
|
25
|
+
success: "--kz-success",
|
|
26
|
+
warning: "--kz-warning",
|
|
27
|
+
danger: "--kz-danger",
|
|
28
|
+
info: "--kz-info",
|
|
29
|
+
low: "--kzc-low",
|
|
30
|
+
high: "--kzc-high"
|
|
31
|
+
};
|
|
32
|
+
function resolveTheme(el) {
|
|
33
|
+
const color = (name) => resolveColor(`var(${name})`, el);
|
|
34
|
+
const roles = Object.fromEntries(Object.entries(ROLES).map(([key, name]) => [key, color(name)]));
|
|
35
|
+
const palette = Array.from({ length: 8 }, (_, i) => color(`--kzc-${i + 1}`));
|
|
36
|
+
const font = getComputedStyle(el).fontFamily || "system-ui, sans-serif";
|
|
37
|
+
return { ...roles, palette, ramp: sequential(palette[0], roles.surface, 5), font };
|
|
38
|
+
}
|
|
39
|
+
function baseOption(theme, animate) {
|
|
40
|
+
return {
|
|
41
|
+
color: [...theme.palette],
|
|
42
|
+
backgroundColor: "transparent",
|
|
43
|
+
textStyle: { color: theme.text2, fontFamily: theme.font, fontSize: 11 },
|
|
44
|
+
animation: animate,
|
|
45
|
+
animationDuration: 700,
|
|
46
|
+
animationEasing: "cubicOut",
|
|
47
|
+
animationDurationUpdate: 300,
|
|
48
|
+
tooltip: {
|
|
49
|
+
confine: true,
|
|
50
|
+
backgroundColor: theme.surface2,
|
|
51
|
+
borderColor: theme.border,
|
|
52
|
+
borderWidth: 1,
|
|
53
|
+
padding: [8, 10],
|
|
54
|
+
textStyle: { color: theme.text, fontFamily: theme.font, fontSize: 12 },
|
|
55
|
+
extraCssText: "border-radius:10px;box-shadow:var(--kz-shadow-lg);min-width:140px;"
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function valueAxis(theme, formatter) {
|
|
60
|
+
return {
|
|
61
|
+
type: "value",
|
|
62
|
+
axisLine: { show: false },
|
|
63
|
+
axisTick: { show: false },
|
|
64
|
+
splitLine: { lineStyle: { color: theme.grid, width: 1 } },
|
|
65
|
+
axisLabel: { color: theme.text2, formatter }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function categoryAxis(theme, data) {
|
|
69
|
+
return {
|
|
70
|
+
type: "category",
|
|
71
|
+
data,
|
|
72
|
+
axisLine: { lineStyle: { color: theme.axis } },
|
|
73
|
+
axisTick: { show: false },
|
|
74
|
+
axisLabel: { color: theme.text2, hideOverlap: true },
|
|
75
|
+
splitLine: { show: false }
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
var escape = (text) => text.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
|
|
79
|
+
function tooltipHtml(title, rows, note) {
|
|
80
|
+
const head = title ? `<p class="kzc-tip-title">${escape(title)}</p>` : "";
|
|
81
|
+
const body = rows.map((row) => `<p class="kzc-tip-row">${row.color ? `<span class="kzc-key" style="background:${escape(row.color)}"></span>` : "<span></span>"}<span>${escape(row.label)}</span><b>${escape(row.value)}</b></p>`).join("");
|
|
82
|
+
return `${head}${body}${note ? `<p class="kzc-tip-note">${escape(note)}</p>` : ""}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/echarts/host.tsx
|
|
86
|
+
import { useEffect, useRef, useState } from "react";
|
|
87
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
88
|
+
var RENDERERS = {
|
|
89
|
+
svg: () => import("./svg-BJUHYX3B.js"),
|
|
90
|
+
canvas: () => import("./canvas-4MSYDVFO.js")
|
|
91
|
+
};
|
|
92
|
+
var install = (module) => {
|
|
93
|
+
const fn = module?.install;
|
|
94
|
+
if (typeof fn === "function") fn();
|
|
95
|
+
};
|
|
96
|
+
function EChartHost({ kind, frame, defaultHeight, table, summary, isEmpty, legend, engine, build, items = [], onItem }) {
|
|
97
|
+
const instance = useRef(null);
|
|
98
|
+
const [active, setActive] = useState(null);
|
|
99
|
+
const [failed, setFailed] = useState(false);
|
|
100
|
+
const renderer = frame.renderer ?? "svg";
|
|
101
|
+
const onKeyDown = (event) => {
|
|
102
|
+
const n = items.length;
|
|
103
|
+
if (!n) return;
|
|
104
|
+
if (event.key === "Enter" && active !== null && onItem) {
|
|
105
|
+
onItem(items[active]);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const moves = {
|
|
109
|
+
ArrowRight: () => ((active ?? -1) + 1) % n,
|
|
110
|
+
ArrowDown: () => ((active ?? -1) + 1) % n,
|
|
111
|
+
ArrowLeft: () => ((active ?? 0) - 1 + n) % n,
|
|
112
|
+
ArrowUp: () => ((active ?? 0) - 1 + n) % n,
|
|
113
|
+
Home: () => 0,
|
|
114
|
+
End: () => n - 1,
|
|
115
|
+
Escape: () => null
|
|
116
|
+
};
|
|
117
|
+
const move = moves[event.key];
|
|
118
|
+
if (!move) return;
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
setActive(move());
|
|
121
|
+
};
|
|
122
|
+
const exportImage = (format) => {
|
|
123
|
+
const chart = instance.current;
|
|
124
|
+
if (!chart) return null;
|
|
125
|
+
const dom = chart.getDom();
|
|
126
|
+
const background = resolveTheme(dom).surface;
|
|
127
|
+
return chart.getDataURL({ type: format === "svg" && renderer === "svg" ? "svg" : "png", pixelRatio: 2, backgroundColor: background });
|
|
128
|
+
};
|
|
129
|
+
return /* @__PURE__ */ jsx(
|
|
130
|
+
ChartFrame,
|
|
131
|
+
{
|
|
132
|
+
kind,
|
|
133
|
+
frame: { ...frame, error: frame.error ?? (failed || void 0) },
|
|
134
|
+
defaultHeight,
|
|
135
|
+
table,
|
|
136
|
+
summary,
|
|
137
|
+
isEmpty,
|
|
138
|
+
legend,
|
|
139
|
+
announcement: active === null ? "" : items[active]?.text ?? "",
|
|
140
|
+
handlers: { onKeyDown, onBlur: () => setActive(null) },
|
|
141
|
+
navigable: items.length > 0,
|
|
142
|
+
exportImage,
|
|
143
|
+
children: (width, height) => /* @__PURE__ */ jsx(
|
|
144
|
+
Host,
|
|
145
|
+
{
|
|
146
|
+
width,
|
|
147
|
+
height,
|
|
148
|
+
renderer,
|
|
149
|
+
engine,
|
|
150
|
+
build,
|
|
151
|
+
active: active === null ? null : items[active] ?? null,
|
|
152
|
+
instance,
|
|
153
|
+
onItem,
|
|
154
|
+
onFail: () => setFailed(true)
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
function Host({ width, height, renderer, engine, build, active, instance, onItem, onFail }) {
|
|
161
|
+
const ref = useRef(null);
|
|
162
|
+
const near = useInView(ref, { once: true, margin: "200px" });
|
|
163
|
+
const reduced = useReducedMotion();
|
|
164
|
+
const themeVersion = useThemeVersion();
|
|
165
|
+
const [ready, setReady] = useState(false);
|
|
166
|
+
const [drawn, setDrawn] = useState(false);
|
|
167
|
+
const size = useRef({ width, height });
|
|
168
|
+
const itemRef = useRef(onItem);
|
|
169
|
+
const failRef = useRef(onFail);
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
size.current = { width, height };
|
|
172
|
+
itemRef.current = onItem;
|
|
173
|
+
failRef.current = onFail;
|
|
174
|
+
});
|
|
175
|
+
useEffect(() => {
|
|
176
|
+
if (!near) return void 0;
|
|
177
|
+
let alive = true;
|
|
178
|
+
Promise.all([engine(), RENDERERS[renderer]()]).then(
|
|
179
|
+
([module, painter]) => {
|
|
180
|
+
if (!alive || !ref.current) return;
|
|
181
|
+
install(module);
|
|
182
|
+
painter.install();
|
|
183
|
+
const { init } = painter;
|
|
184
|
+
const chart = init(ref.current, null, { renderer, ...size.current });
|
|
185
|
+
chart.on("finished", () => setDrawn(true));
|
|
186
|
+
chart.on("click", (params) => {
|
|
187
|
+
const p = params;
|
|
188
|
+
if (p.seriesIndex != null && p.dataIndex != null) itemRef.current?.({ seriesIndex: p.seriesIndex, dataIndex: p.dataIndex });
|
|
189
|
+
});
|
|
190
|
+
instance.current = chart;
|
|
191
|
+
setReady(true);
|
|
192
|
+
},
|
|
193
|
+
() => alive && failRef.current()
|
|
194
|
+
);
|
|
195
|
+
return () => {
|
|
196
|
+
alive = false;
|
|
197
|
+
instance.current?.dispose();
|
|
198
|
+
instance.current = null;
|
|
199
|
+
setReady(false);
|
|
200
|
+
};
|
|
201
|
+
}, [near, renderer, engine, instance]);
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
if (ready) instance.current?.resize({ width, height });
|
|
204
|
+
}, [ready, width, height, instance]);
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
const chart = instance.current;
|
|
207
|
+
if (!ready || !chart || !ref.current) return;
|
|
208
|
+
const option = build(resolveTheme(ref.current), { width, height });
|
|
209
|
+
chart.setOption({ ...option, animation: !reduced && option.animation !== false }, { notMerge: true });
|
|
210
|
+
}, [ready, build, themeVersion, reduced, width, height, instance]);
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
const chart = instance.current;
|
|
213
|
+
if (!ready || !chart) return;
|
|
214
|
+
chart.dispatchAction({ type: "downplay" });
|
|
215
|
+
if (active) {
|
|
216
|
+
const target = { seriesIndex: active.seriesIndex, dataIndex: active.dataIndex, ...active.dataType ? { dataType: active.dataType } : {} };
|
|
217
|
+
chart.dispatchAction({ type: "highlight", ...target });
|
|
218
|
+
chart.dispatchAction({ type: "showTip", ...target });
|
|
219
|
+
} else chart.dispatchAction({ type: "hideTip" });
|
|
220
|
+
}, [ready, active, instance]);
|
|
221
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
222
|
+
!drawn && /* @__PURE__ */ jsx("div", { className: "kzc-skeleton", "aria-hidden": true, children: [0.55, 0.8, 0.45, 0.95, 0.7, 0.6].map((h, i) => /* @__PURE__ */ jsx("i", { style: { height: `${h * 100}%` } }, i)) }),
|
|
223
|
+
/* @__PURE__ */ jsx("div", { ref, className: "kzc-host", "data-pending": drawn ? void 0 : "", "aria-hidden": true })
|
|
224
|
+
] });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export {
|
|
228
|
+
baseOption,
|
|
229
|
+
valueAxis,
|
|
230
|
+
categoryAxis,
|
|
231
|
+
tooltipHtml,
|
|
232
|
+
EChartHost
|
|
233
|
+
};
|
|
234
|
+
//# sourceMappingURL=chunk-I5QUZVU2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/echarts/theme.ts","../src/echarts/host.tsx"],"sourcesContent":["\"use client\";\n// The ECharts side of the theme: the --kz-* roles and the palette's variables resolved to plain colours on the chart's\n// own element (a canvas has no CSS variables) — so a `.brand-<id>` ancestor, a `.theme-light` island and the\n// chart's `data-brand` all apply — and the option pieces every chart shares (text, axes, grid, tooltip).\nimport type { EChartsCoreOption } from \"echarts/core\";\n\nimport { sequential } from \"../core/palette\";\nimport { resolveColor } from \"../web/frame\";\n\nexport interface ResolvedTheme {\n readonly text: string;\n readonly text2: string;\n readonly text3: string;\n readonly grid: string;\n readonly axis: string;\n readonly surface: string;\n readonly surface2: string;\n readonly surface3: string;\n readonly border: string;\n readonly accent: string;\n readonly success: string;\n readonly warning: string;\n readonly danger: string;\n readonly info: string;\n /** The categorical palette, slot 1 first. */\n readonly palette: readonly string[];\n /** A sequential ramp of the brand hue (5 steps, near the surface → full). */\n readonly ramp: readonly string[];\n /** The diverging poles. */\n readonly low: string;\n readonly high: string;\n readonly font: string;\n}\n\nconst ROLES = {\n text: \"--kz-text-primary\",\n text2: \"--kz-text-secondary\",\n text3: \"--kz-text-muted\",\n grid: \"--kz-border-subtle\",\n axis: \"--kz-border-default\",\n surface: \"--kz-surface-1\",\n surface2: \"--kz-surface-2\",\n surface3: \"--kz-surface-3\",\n border: \"--kz-border-default\",\n accent: \"--kz-accent\",\n success: \"--kz-success\",\n warning: \"--kz-warning\",\n danger: \"--kz-danger\",\n info: \"--kz-info\",\n low: \"--kzc-low\",\n high: \"--kzc-high\",\n} as const;\n\n/** The theme as the browser resolves it on `el` (call again after a theme change). */\nexport function resolveTheme(el: Element): ResolvedTheme {\n const color = (name: string) => resolveColor(`var(${name})`, el);\n const roles = Object.fromEntries(Object.entries(ROLES).map(([key, name]) => [key, color(name)])) as Record<keyof typeof ROLES, string>;\n const palette = Array.from({ length: 8 }, (_, i) => color(`--kzc-${i + 1}`));\n const font = getComputedStyle(el).fontFamily || \"system-ui, sans-serif\";\n return { ...roles, palette, ramp: sequential(palette[0]!, roles.surface, 5), font };\n}\n\n/** The option every ECharts chart starts from: colours, text, the tooltip's surface, motion. */\nexport function baseOption(theme: ResolvedTheme, animate: boolean): EChartsCoreOption {\n return {\n color: [...theme.palette],\n backgroundColor: \"transparent\",\n textStyle: { color: theme.text2, fontFamily: theme.font, fontSize: 11 },\n animation: animate,\n animationDuration: 700,\n animationEasing: \"cubicOut\",\n animationDurationUpdate: 300,\n tooltip: {\n confine: true,\n backgroundColor: theme.surface2,\n borderColor: theme.border,\n borderWidth: 1,\n padding: [8, 10],\n textStyle: { color: theme.text, fontFamily: theme.font, fontSize: 12 },\n extraCssText: \"border-radius:10px;box-shadow:var(--kz-shadow-lg);min-width:140px;\",\n },\n };\n}\n\n/** A value axis: recessive, hairline grid, text-secondary labels. */\nexport function valueAxis(theme: ResolvedTheme, formatter: (v: number) => string): Record<string, unknown> {\n return {\n type: \"value\",\n axisLine: { show: false },\n axisTick: { show: false },\n splitLine: { lineStyle: { color: theme.grid, width: 1 } },\n axisLabel: { color: theme.text2, formatter },\n };\n}\n\n/** A category axis: a baseline in the axis colour, no ticks. */\nexport function categoryAxis(theme: ResolvedTheme, data: readonly string[]): Record<string, unknown> {\n return {\n type: \"category\",\n data,\n axisLine: { lineStyle: { color: theme.axis } },\n axisTick: { show: false },\n axisLabel: { color: theme.text2, hideOverlap: true },\n splitLine: { show: false },\n };\n}\n\nconst escape = (text: string) => text.replace(/[&<>\"]/g, (c) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\" })[c]!);\n\n/** The tooltip's content in the package's markup (`kzc-tip-*`): a title, rows of key · name · value, a note. */\nexport function tooltipHtml(title: string | undefined, rows: readonly { label: string; value: string; color?: string }[], note?: string): string {\n const head = title ? `<p class=\"kzc-tip-title\">${escape(title)}</p>` : \"\";\n const body = rows\n .map((row) => `<p class=\"kzc-tip-row\">${row.color ? `<span class=\"kzc-key\" style=\"background:${escape(row.color)}\"></span>` : \"<span></span>\"}<span>${escape(row.label)}</span><b>${escape(row.value)}</b></p>`)\n .join(\"\");\n return `${head}${body}${note ? `<p class=\"kzc-tip-note\">${escape(note)}</p>` : \"\"}`;\n}\n","\"use client\";\n// The ECharts host behind Radar, Heatmap, Calendar, Sankey, Funnel, Candlestick, Treemap, Scatter and <Chart>: the same\n// frame as the SVG charts (title, summary, data table, keyboard, states, export), and an engine that is loaded only\n// when the chart comes near the screen — `echarts/core`, the one chart type and its components, one renderer (SVG by\n// default; canvas for large volumes). The option is rebuilt from the resolved theme on every theme change; motion\n// follows the reader's preference; the chart is disposed with the component.\nimport type { EChartsCoreOption, EChartsType } from \"echarts/core\";\nimport { type KeyboardEvent, type ReactNode, type RefObject, useEffect, useRef, useState } from \"react\";\n\nimport type { ChartKind } from \"../core/labels\";\nimport { ChartFrame, type ChartFrameProps, type TableModel } from \"../web/frame\";\nimport { useInView, useReducedMotion, useThemeVersion } from \"../web/hooks\";\nimport { type ResolvedTheme, resolveTheme } from \"./theme\";\n\nexport type Renderer = \"svg\" | \"canvas\";\n\n/** What the keyboard walks: one ECharts data item, and what it says. */\nexport interface WalkItem {\n readonly seriesIndex: number;\n readonly dataIndex: number;\n /** A graph's link (`edge`) rather than its node: Sankey's flows. */\n readonly dataType?: \"node\" | \"edge\";\n readonly text: string;\n}\n\nexport interface EngineProps {\n /** `svg` (default): sharp, exportable as SVG. `canvas`: for tens of thousands of marks. */\n renderer?: Renderer;\n}\n\ninterface HostProps {\n readonly kind: ChartKind;\n readonly frame: ChartFrameProps & EngineProps;\n readonly defaultHeight?: number;\n readonly table: TableModel;\n readonly summary: string;\n readonly isEmpty: boolean;\n readonly legend?: ReactNode;\n /** Loads the chart type and its components (a dynamic import of `./engines/<type>`), whose `install` registers them. */\n readonly engine: () => Promise<unknown>;\n /** The option, from the resolved theme and the size. Memoise it: a new function redraws. */\n readonly build: (theme: ResolvedTheme, size: { width: number; height: number }) => EChartsCoreOption;\n readonly items?: readonly WalkItem[];\n /** A click (or Enter) on an item. */\n readonly onItem?: (item: { seriesIndex: number; dataIndex: number }) => void;\n}\n\ntype Init = (el: HTMLElement, theme: null, options: { renderer: Renderer; width: number; height: number }) => EChartsType;\ntype RendererModule = { init: Init; install: () => void };\n\nconst RENDERERS: Record<Renderer, () => Promise<RendererModule>> = {\n svg: () => import(\"./engines/svg\") as Promise<RendererModule>,\n canvas: () => import(\"./engines/canvas\") as Promise<RendererModule>,\n};\n\n/** Calls the `install` of an engine module (a typed chart's), if it has one (a `<Chart modules>` function may not). */\nconst install = (module: unknown) => {\n const fn = (module as { install?: unknown } | null)?.install;\n if (typeof fn === \"function\") fn();\n};\n\nexport function EChartHost({ kind, frame, defaultHeight, table, summary, isEmpty, legend, engine, build, items = [], onItem }: HostProps) {\n const instance = useRef<EChartsType | null>(null);\n const [active, setActive] = useState<number | null>(null);\n const [failed, setFailed] = useState(false);\n const renderer = frame.renderer ?? \"svg\";\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const n = items.length;\n if (!n) return;\n if (event.key === \"Enter\" && active !== null && onItem) {\n onItem(items[active]!);\n return;\n }\n const moves: Record<string, () => number | null> = {\n ArrowRight: () => ((active ?? -1) + 1) % n,\n ArrowDown: () => ((active ?? -1) + 1) % n,\n ArrowLeft: () => ((active ?? 0) - 1 + n) % n,\n ArrowUp: () => ((active ?? 0) - 1 + n) % n,\n Home: () => 0,\n End: () => n - 1,\n Escape: () => null,\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n setActive(move());\n };\n\n const exportImage = (format: \"png\" | \"svg\") => {\n const chart = instance.current;\n if (!chart) return null;\n const dom = chart.getDom();\n const background = resolveTheme(dom).surface;\n return chart.getDataURL({ type: format === \"svg\" && renderer === \"svg\" ? \"svg\" : \"png\", pixelRatio: 2, backgroundColor: background });\n };\n\n return (\n <ChartFrame\n kind={kind}\n frame={{ ...frame, error: frame.error ?? (failed || undefined) }}\n defaultHeight={defaultHeight}\n table={table}\n summary={summary}\n isEmpty={isEmpty}\n legend={legend}\n announcement={active === null ? \"\" : (items[active]?.text ?? \"\")}\n handlers={{ onKeyDown, onBlur: () => setActive(null) }}\n navigable={items.length > 0}\n exportImage={exportImage}\n >\n {(width, height) => (\n <Host\n width={width}\n height={height}\n renderer={renderer}\n engine={engine}\n build={build}\n active={active === null ? null : (items[active] ?? null)}\n instance={instance}\n onItem={onItem}\n onFail={() => setFailed(true)}\n />\n )}\n </ChartFrame>\n );\n}\n\ninterface InnerProps {\n width: number;\n height: number;\n renderer: Renderer;\n engine: () => Promise<unknown>;\n build: HostProps[\"build\"];\n active: WalkItem | null;\n instance: RefObject<EChartsType | null>;\n onItem?: HostProps[\"onItem\"];\n onFail: () => void;\n}\n\nfunction Host({ width, height, renderer, engine, build, active, instance, onItem, onFail }: InnerProps) {\n const ref = useRef<HTMLDivElement | null>(null);\n const near = useInView(ref, { once: true, margin: \"200px\" });\n const reduced = useReducedMotion();\n const themeVersion = useThemeVersion();\n const [ready, setReady] = useState(false);\n const [drawn, setDrawn] = useState(false);\n // The latest size and callbacks, read by the loader without restarting it.\n const size = useRef({ width, height });\n const itemRef = useRef(onItem);\n const failRef = useRef(onFail);\n useEffect(() => {\n size.current = { width, height };\n itemRef.current = onItem;\n failRef.current = onFail;\n });\n\n // Load the engine once the chart is near the screen; init; dispose with the component.\n useEffect(() => {\n if (!near) return undefined;\n let alive = true;\n Promise.all([engine(), RENDERERS[renderer]()]).then(\n ([module, painter]) => {\n if (!alive || !ref.current) return;\n install(module);\n painter.install();\n const { init } = painter;\n const chart = init(ref.current, null, { renderer, ...size.current });\n chart.on(\"finished\", () => setDrawn(true));\n chart.on(\"click\", (params) => {\n const p = params as { seriesIndex?: number; dataIndex?: number };\n if (p.seriesIndex != null && p.dataIndex != null) itemRef.current?.({ seriesIndex: p.seriesIndex, dataIndex: p.dataIndex });\n });\n instance.current = chart;\n setReady(true);\n },\n () => alive && failRef.current(),\n );\n return () => {\n alive = false;\n instance.current?.dispose();\n instance.current = null;\n setReady(false);\n };\n }, [near, renderer, engine, instance]);\n\n useEffect(() => {\n if (ready) instance.current?.resize({ width, height });\n }, [ready, width, height, instance]);\n\n // The option: rebuilt from the theme resolved on the chart's element, on every change of data, size or theme.\n useEffect(() => {\n const chart = instance.current;\n if (!ready || !chart || !ref.current) return;\n const option = build(resolveTheme(ref.current), { width, height });\n chart.setOption({ ...option, animation: !reduced && (option.animation as boolean | undefined) !== false }, { notMerge: true });\n }, [ready, build, themeVersion, reduced, width, height, instance]);\n\n // The keyboard's active item: ECharts' own tooltip and highlight.\n useEffect(() => {\n const chart = instance.current;\n if (!ready || !chart) return;\n chart.dispatchAction({ type: \"downplay\" });\n if (active) {\n const target = { seriesIndex: active.seriesIndex, dataIndex: active.dataIndex, ...(active.dataType ? { dataType: active.dataType } : {}) };\n chart.dispatchAction({ type: \"highlight\", ...target });\n chart.dispatchAction({ type: \"showTip\", ...target });\n } else chart.dispatchAction({ type: \"hideTip\" });\n }, [ready, active, instance]);\n\n return (\n <>\n {!drawn && (\n <div className=\"kzc-skeleton\" aria-hidden>\n {[0.55, 0.8, 0.45, 0.95, 0.7, 0.6].map((h, i) => (\n <i key={i} style={{ height: `${h * 100}%` }} />\n ))}\n </div>\n )}\n <div ref={ref} className=\"kzc-host\" data-pending={drawn ? undefined : \"\"} aria-hidden />\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/core/shape.ts
|
|
4
|
+
var r = (n) => Math.round(n * 100) / 100;
|
|
5
|
+
function segments(points) {
|
|
6
|
+
const out = [];
|
|
7
|
+
let current = [];
|
|
8
|
+
for (const point of points) {
|
|
9
|
+
if (point) current.push(point);
|
|
10
|
+
else if (current.length) {
|
|
11
|
+
out.push(current);
|
|
12
|
+
current = [];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (current.length) out.push(current);
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
function linePath(points, curve = "monotone") {
|
|
19
|
+
if (points.length === 0) return "";
|
|
20
|
+
const [x0, y0] = points[0];
|
|
21
|
+
if (points.length === 1) return `M${r(x0)},${r(y0)}`;
|
|
22
|
+
if (curve === "step") {
|
|
23
|
+
let d2 = `M${r(x0)},${r(y0)}`;
|
|
24
|
+
for (let i = 1; i < points.length; i += 1) {
|
|
25
|
+
const [px] = points[i - 1];
|
|
26
|
+
const [x, y] = points[i];
|
|
27
|
+
const mid = (px + x) / 2;
|
|
28
|
+
d2 += `H${r(mid)}V${r(y)}H${r(x)}`;
|
|
29
|
+
}
|
|
30
|
+
return d2;
|
|
31
|
+
}
|
|
32
|
+
if (curve === "linear" || points.length === 2) return points.map(([x, y], i) => `${i ? "L" : "M"}${r(x)},${r(y)}`).join("");
|
|
33
|
+
const tangents = monotoneTangents(points);
|
|
34
|
+
let d = `M${r(x0)},${r(y0)}`;
|
|
35
|
+
for (let i = 1; i < points.length; i += 1) {
|
|
36
|
+
const [xa, ya] = points[i - 1];
|
|
37
|
+
const [xb, yb] = points[i];
|
|
38
|
+
const h = (xb - xa) / 3;
|
|
39
|
+
d += `C${r(xa + h)},${r(ya + h * tangents[i - 1])} ${r(xb - h)},${r(yb - h * tangents[i])} ${r(xb)},${r(yb)}`;
|
|
40
|
+
}
|
|
41
|
+
return d;
|
|
42
|
+
}
|
|
43
|
+
function monotoneTangents(points) {
|
|
44
|
+
const n = points.length;
|
|
45
|
+
const slopes = [];
|
|
46
|
+
for (let i = 0; i < n - 1; i += 1) {
|
|
47
|
+
const [xa, ya] = points[i];
|
|
48
|
+
const [xb, yb] = points[i + 1];
|
|
49
|
+
slopes.push(xb === xa ? 0 : (yb - ya) / (xb - xa));
|
|
50
|
+
}
|
|
51
|
+
const tangents = [slopes[0]];
|
|
52
|
+
for (let i = 1; i < n - 1; i += 1) {
|
|
53
|
+
const a = slopes[i - 1];
|
|
54
|
+
const b = slopes[i];
|
|
55
|
+
tangents.push(a * b <= 0 ? 0 : 3 * a * b / (Math.max(a, b) * 2 + Math.min(a, b)) || 0);
|
|
56
|
+
}
|
|
57
|
+
tangents.push(slopes[n - 2]);
|
|
58
|
+
return tangents;
|
|
59
|
+
}
|
|
60
|
+
function areaPath(top, base, curve = "monotone") {
|
|
61
|
+
if (top.length === 0) return "";
|
|
62
|
+
const line = linePath(top, curve);
|
|
63
|
+
const bottom = typeof base === "number" ? [top[top.length - 1], top[0]].map(([x]) => [x, base]) : [...base].reverse();
|
|
64
|
+
if (typeof base === "number") return `${line}L${r(bottom[0][0])},${r(base)}L${r(bottom[1][0])},${r(base)}Z`;
|
|
65
|
+
return `${line}L${linePath(bottom, curve).slice(1)}Z`;
|
|
66
|
+
}
|
|
67
|
+
function barPath(x, y, width, height, radius = 4, horizontal = false, negative = false) {
|
|
68
|
+
if (width <= 0 || height <= 0) return "";
|
|
69
|
+
const rad = Math.min(radius, horizontal ? height / 2 : width / 2, horizontal ? width : height);
|
|
70
|
+
if (!horizontal) {
|
|
71
|
+
if (!negative) {
|
|
72
|
+
return `M${r(x)},${r(y + height)}V${r(y + rad)}Q${r(x)},${r(y)} ${r(x + rad)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height)}Z`;
|
|
73
|
+
}
|
|
74
|
+
return `M${r(x)},${r(y)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width)},${r(y + height - rad)}V${r(y)}Z`;
|
|
75
|
+
}
|
|
76
|
+
if (!negative) {
|
|
77
|
+
return `M${r(x)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width - rad)},${r(y + height)}H${r(x)}Z`;
|
|
78
|
+
}
|
|
79
|
+
return `M${r(x + width)},${r(y)}H${r(x + rad)}Q${r(x)},${r(y)} ${r(x)},${r(y + rad)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width)}Z`;
|
|
80
|
+
}
|
|
81
|
+
function polar(cx, cy, radius, angle) {
|
|
82
|
+
return [cx + radius * Math.sin(angle), cy - radius * Math.cos(angle)];
|
|
83
|
+
}
|
|
84
|
+
function arcPath(cx, cy, inner, outer, start, end) {
|
|
85
|
+
const sweep = end - start;
|
|
86
|
+
if (sweep <= 0 || outer <= 0) return "";
|
|
87
|
+
if (sweep >= Math.PI * 2 - 1e-6) {
|
|
88
|
+
const mid = start + Math.PI;
|
|
89
|
+
return `${arcPath(cx, cy, inner, outer, start, mid)}${arcPath(cx, cy, inner, outer, mid, start + Math.PI * 2)}`;
|
|
90
|
+
}
|
|
91
|
+
const large = sweep > Math.PI ? 1 : 0;
|
|
92
|
+
const [ox0, oy0] = polar(cx, cy, outer, start);
|
|
93
|
+
const [ox1, oy1] = polar(cx, cy, outer, end);
|
|
94
|
+
let d = `M${r(ox0)},${r(oy0)}A${r(outer)},${r(outer)} 0 ${large} 1 ${r(ox1)},${r(oy1)}`;
|
|
95
|
+
if (inner > 0) {
|
|
96
|
+
const [ix1, iy1] = polar(cx, cy, inner, end);
|
|
97
|
+
const [ix0, iy0] = polar(cx, cy, inner, start);
|
|
98
|
+
d += `L${r(ix1)},${r(iy1)}A${r(inner)},${r(inner)} 0 ${large} 0 ${r(ix0)},${r(iy0)}Z`;
|
|
99
|
+
} else d += `L${r(cx)},${r(cy)}Z`;
|
|
100
|
+
return d;
|
|
101
|
+
}
|
|
102
|
+
function strokeArcPath(cx, cy, radius, start, end) {
|
|
103
|
+
if (end - start <= 0) return "";
|
|
104
|
+
const [x0, y0] = polar(cx, cy, radius, start);
|
|
105
|
+
const [x1, y1] = polar(cx, cy, radius, end);
|
|
106
|
+
return `M${r(x0)},${r(y0)}A${r(radius)},${r(radius)} 0 ${end - start > Math.PI ? 1 : 0} 1 ${r(x1)},${r(y1)}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export {
|
|
110
|
+
segments,
|
|
111
|
+
linePath,
|
|
112
|
+
areaPath,
|
|
113
|
+
barPath,
|
|
114
|
+
polar,
|
|
115
|
+
arcPath,
|
|
116
|
+
strokeArcPath
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=chunk-OB5EFDDH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/shape.ts"],"sourcesContent":["// SVG path data for the marks: lines (linear, monotone, step), areas, bars with a rounded data end, arcs. Shared by\n// the web (`<path d>`) and React Native (react-native-svg's `<Path d>`): the same geometry on both platforms.\n\nexport type Point = readonly [number, number];\nexport type Curve = \"linear\" | \"monotone\" | \"step\";\n\nconst r = (n: number) => Math.round(n * 100) / 100;\n\n/** The segments of a line, split where a value is missing (a gap stays a gap, never a fake zero). */\nexport function segments(points: readonly (Point | null)[]): Point[][] {\n const out: Point[][] = [];\n let current: Point[] = [];\n for (const point of points) {\n if (point) current.push(point);\n else if (current.length) {\n out.push(current);\n current = [];\n }\n }\n if (current.length) out.push(current);\n return out;\n}\n\n/** The path of one segment. `monotone` (Fritsch–Carlson) never overshoots: a curve that never invents a peak. */\nexport function linePath(points: readonly Point[], curve: Curve = \"monotone\"): string {\n if (points.length === 0) return \"\";\n const [x0, y0] = points[0]!;\n if (points.length === 1) return `M${r(x0)},${r(y0)}`;\n if (curve === \"step\") {\n let d = `M${r(x0)},${r(y0)}`;\n for (let i = 1; i < points.length; i += 1) {\n const [px] = points[i - 1]!;\n const [x, y] = points[i]!;\n const mid = (px + x) / 2;\n d += `H${r(mid)}V${r(y)}H${r(x)}`;\n }\n return d;\n }\n if (curve === \"linear\" || points.length === 2) return points.map(([x, y], i) => `${i ? \"L\" : \"M\"}${r(x)},${r(y)}`).join(\"\");\n const tangents = monotoneTangents(points);\n let d = `M${r(x0)},${r(y0)}`;\n for (let i = 1; i < points.length; i += 1) {\n const [xa, ya] = points[i - 1]!;\n const [xb, yb] = points[i]!;\n const h = (xb - xa) / 3;\n d += `C${r(xa + h)},${r(ya + h * tangents[i - 1]!)} ${r(xb - h)},${r(yb - h * tangents[i]!)} ${r(xb)},${r(yb)}`;\n }\n return d;\n}\n\nfunction monotoneTangents(points: readonly Point[]): number[] {\n const n = points.length;\n const slopes: number[] = [];\n for (let i = 0; i < n - 1; i += 1) {\n const [xa, ya] = points[i]!;\n const [xb, yb] = points[i + 1]!;\n slopes.push(xb === xa ? 0 : (yb - ya) / (xb - xa));\n }\n const tangents = [slopes[0]!];\n for (let i = 1; i < n - 1; i += 1) {\n const a = slopes[i - 1]!;\n const b = slopes[i]!;\n tangents.push(a * b <= 0 ? 0 : (3 * a * b) / (Math.max(a, b) * 2 + Math.min(a, b)) || 0);\n }\n tangents.push(slopes[n - 2]!);\n return tangents;\n}\n\n/** An area under (or between) lines: the top points left to right, then the base right to left. */\nexport function areaPath(top: readonly Point[], base: readonly Point[] | number, curve: Curve = \"monotone\"): string {\n if (top.length === 0) return \"\";\n const line = linePath(top, curve);\n const bottom: Point[] = typeof base === \"number\" ? [top[top.length - 1]!, top[0]!].map(([x]) => [x, base] as Point) : [...base].reverse();\n if (typeof base === \"number\") return `${line}L${r(bottom[0]![0])},${r(base)}L${r(bottom[1]![0])},${r(base)}Z`;\n return `${line}L${linePath(bottom, curve).slice(1)}Z`;\n}\n\n/**\n * A bar from its baseline to its value, the data end rounded (`radius`, 4 px by default), square on the baseline.\n * `horizontal` bars grow to the right (or left for a negative value).\n */\nexport function barPath(x: number, y: number, width: number, height: number, radius = 4, horizontal = false, negative = false): string {\n if (width <= 0 || height <= 0) return \"\";\n const rad = Math.min(radius, horizontal ? height / 2 : width / 2, horizontal ? width : height);\n if (!horizontal) {\n if (!negative) {\n // Rounded at the top, square at the baseline (bottom).\n return `M${r(x)},${r(y + height)}V${r(y + rad)}Q${r(x)},${r(y)} ${r(x + rad)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height)}Z`;\n }\n return `M${r(x)},${r(y)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width)},${r(y + height - rad)}V${r(y)}Z`;\n }\n if (!negative) {\n return `M${r(x)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width - rad)},${r(y + height)}H${r(x)}Z`;\n }\n return `M${r(x + width)},${r(y)}H${r(x + rad)}Q${r(x)},${r(y)} ${r(x)},${r(y + rad)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width)}Z`;\n}\n\n/** A point on a circle, the angle in radians from twelve o'clock, clockwise. */\nexport function polar(cx: number, cy: number, radius: number, angle: number): Point {\n return [cx + radius * Math.sin(angle), cy - radius * Math.cos(angle)];\n}\n\n/**\n * A ring sector (a pie slice when `inner` is 0), from `start` to `end` (radians, clockwise from twelve o'clock).\n * A full turn is drawn as two halves: an SVG arc cannot start and end on the same point.\n */\nexport function arcPath(cx: number, cy: number, inner: number, outer: number, start: number, end: number): string {\n const sweep = end - start;\n if (sweep <= 0 || outer <= 0) return \"\";\n if (sweep >= Math.PI * 2 - 1e-6) {\n const mid = start + Math.PI;\n return `${arcPath(cx, cy, inner, outer, start, mid)}${arcPath(cx, cy, inner, outer, mid, start + Math.PI * 2)}`;\n }\n const large = sweep > Math.PI ? 1 : 0;\n const [ox0, oy0] = polar(cx, cy, outer, start);\n const [ox1, oy1] = polar(cx, cy, outer, end);\n let d = `M${r(ox0)},${r(oy0)}A${r(outer)},${r(outer)} 0 ${large} 1 ${r(ox1)},${r(oy1)}`;\n if (inner > 0) {\n const [ix1, iy1] = polar(cx, cy, inner, end);\n const [ix0, iy0] = polar(cx, cy, inner, start);\n d += `L${r(ix1)},${r(iy1)}A${r(inner)},${r(inner)} 0 ${large} 0 ${r(ix0)},${r(iy0)}Z`;\n } else d += `L${r(cx)},${r(cy)}Z`;\n return d;\n}\n\n/** An open arc (a gauge's track), stroked rather than filled. */\nexport function strokeArcPath(cx: number, cy: number, radius: number, start: number, end: number): string {\n if (end - start <= 0) return \"\";\n const [x0, y0] = polar(cx, cy, radius, start);\n const [x1, y1] = polar(cx, cy, radius, end);\n return `M${r(x0)},${r(y0)}A${r(radius)},${r(radius)} 0 ${end - start > Math.PI ? 1 : 0} 1 ${r(x1)},${r(y1)}`;\n}\n"],"mappings":";;;AAMA,IAAM,IAAI,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAGxC,SAAS,SAAS,QAA8C;AACrE,QAAM,MAAiB,CAAC;AACxB,MAAI,UAAmB,CAAC;AACxB,aAAW,SAAS,QAAQ;AAC1B,QAAI,MAAO,SAAQ,KAAK,KAAK;AAAA,aACpB,QAAQ,QAAQ;AACvB,UAAI,KAAK,OAAO;AAChB,gBAAU,CAAC;AAAA,IACb;AAAA,EACF;AACA,MAAI,QAAQ,OAAQ,KAAI,KAAK,OAAO;AACpC,SAAO;AACT;AAGO,SAAS,SAAS,QAA0B,QAAe,YAAoB;AACpF,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC;AACzB,MAAI,OAAO,WAAW,EAAG,QAAO,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAClD,MAAI,UAAU,QAAQ;AACpB,QAAIA,KAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAC1B,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,YAAM,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC;AACzB,YAAM,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;AACvB,YAAM,OAAO,KAAK,KAAK;AACvB,MAAAA,MAAK,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,IACjC;AACA,WAAOA;AAAA,EACT;AACA,MAAI,UAAU,YAAY,OAAO,WAAW,EAAG,QAAO,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE;AAC1H,QAAM,WAAW,iBAAiB,MAAM;AACxC,MAAI,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,UAAM,CAAC,IAAI,EAAE,IAAI,OAAO,IAAI,CAAC;AAC7B,UAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC;AACzB,UAAM,KAAK,KAAK,MAAM;AACtB,SAAK,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,SAAS,IAAI,CAAC,CAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,SAAS,CAAC,CAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAAA,EAC/G;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAoC;AAC5D,QAAM,IAAI,OAAO;AACjB,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK,GAAG;AACjC,UAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC;AACzB,UAAM,CAAC,IAAI,EAAE,IAAI,OAAO,IAAI,CAAC;AAC7B,WAAO,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,GAAG;AAAA,EACnD;AACA,QAAM,WAAW,CAAC,OAAO,CAAC,CAAE;AAC5B,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK,GAAG;AACjC,UAAM,IAAI,OAAO,IAAI,CAAC;AACtB,UAAM,IAAI,OAAO,CAAC;AAClB,aAAS,KAAK,IAAI,KAAK,IAAI,IAAK,IAAI,IAAI,KAAM,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC;AAAA,EACzF;AACA,WAAS,KAAK,OAAO,IAAI,CAAC,CAAE;AAC5B,SAAO;AACT;AAGO,SAAS,SAAS,KAAuB,MAAiC,QAAe,YAAoB;AAClH,MAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,QAAM,OAAO,SAAS,KAAK,KAAK;AAChC,QAAM,SAAkB,OAAO,SAAS,WAAW,CAAC,IAAI,IAAI,SAAS,CAAC,GAAI,IAAI,CAAC,CAAE,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAU,IAAI,CAAC,GAAG,IAAI,EAAE,QAAQ;AACxI,MAAI,OAAO,SAAS,SAAU,QAAO,GAAG,IAAI,IAAI,EAAE,OAAO,CAAC,EAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC;AAC1G,SAAO,GAAG,IAAI,IAAI,SAAS,QAAQ,KAAK,EAAE,MAAM,CAAC,CAAC;AACpD;AAMO,SAAS,QAAQ,GAAW,GAAW,OAAe,QAAgB,SAAS,GAAG,aAAa,OAAO,WAAW,OAAe;AACrI,MAAI,SAAS,KAAK,UAAU,EAAG,QAAO;AACtC,QAAM,MAAM,KAAK,IAAI,QAAQ,aAAa,SAAS,IAAI,QAAQ,GAAG,aAAa,QAAQ,MAAM;AAC7F,MAAI,CAAC,YAAY;AACf,QAAI,CAAC,UAAU;AAEb,aAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC;AAAA,IACnL;AACA,WAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,EAC9M;AACA,MAAI,CAAC,UAAU;AACb,WAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,SAAS,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAAA,EAC5M;AACA,SAAO,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC;AACpL;AAGO,SAAS,MAAM,IAAY,IAAY,QAAgB,OAAsB;AAClF,SAAO,CAAC,KAAK,SAAS,KAAK,IAAI,KAAK,GAAG,KAAK,SAAS,KAAK,IAAI,KAAK,CAAC;AACtE;AAMO,SAAS,QAAQ,IAAY,IAAY,OAAe,OAAe,OAAe,KAAqB;AAChH,QAAM,QAAQ,MAAM;AACpB,MAAI,SAAS,KAAK,SAAS,EAAG,QAAO;AACrC,MAAI,SAAS,KAAK,KAAK,IAAI,MAAM;AAC/B,UAAM,MAAM,QAAQ,KAAK;AACzB,WAAO,GAAG,QAAQ,IAAI,IAAI,OAAO,OAAO,OAAO,GAAG,CAAC,GAAG,QAAQ,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC;AAAA,EAC/G;AACA,QAAM,QAAQ,QAAQ,KAAK,KAAK,IAAI;AACpC,QAAM,CAAC,KAAK,GAAG,IAAI,MAAM,IAAI,IAAI,OAAO,KAAK;AAC7C,QAAM,CAAC,KAAK,GAAG,IAAI,MAAM,IAAI,IAAI,OAAO,GAAG;AAC3C,MAAI,IAAI,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;AACrF,MAAI,QAAQ,GAAG;AACb,UAAM,CAAC,KAAK,GAAG,IAAI,MAAM,IAAI,IAAI,OAAO,GAAG;AAC3C,UAAM,CAAC,KAAK,GAAG,IAAI,MAAM,IAAI,IAAI,OAAO,KAAK;AAC7C,SAAK,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;AAAA,EACpF,MAAO,MAAK,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAC9B,SAAO;AACT;AAGO,SAAS,cAAc,IAAY,IAAY,QAAgB,OAAe,KAAqB;AACxG,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI,IAAI,QAAQ,KAAK;AAC5C,QAAM,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC1C,SAAO,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,MAAM,QAAQ,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAC5G;","names":["d"]}
|