mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-08-06 21:03:37 +08:00
chore: 更新 layerchart 并做对应修改
This commit is contained in:
32
web/bun.lock
32
web/bun.lock
@@ -27,7 +27,7 @@
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.20.0",
|
||||
"globals": "^17.7.0",
|
||||
"layerchart": "2.0.0-next.43",
|
||||
"layerchart": "^2.0.1",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"prettier": "^3.9.5",
|
||||
"prettier-plugin-organize-imports": "^4.3.0",
|
||||
@@ -47,9 +47,9 @@
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@dagrejs/dagre": ["@dagrejs/dagre@1.1.8", "", { "dependencies": { "@dagrejs/graphlib": "2.2.4" } }, "sha512-5SEDlndt4W/LaVzPYJW+bSmSEZc9EzTf8rJ20WCKvjS5EAZAN0b+x0Yww7VMT4R3Wootkg+X9bUfUxazYw6Blw=="],
|
||||
"@dagrejs/dagre": ["@dagrejs/dagre@2.0.4", "", { "dependencies": { "@dagrejs/graphlib": "3.0.4" } }, "sha512-J6vCWTNpicHF4zFlZG1cS5DkGzMr9941gddYkakjrg3ZNev4bbqEgLHFTWiFrcJm7UCRu7olO3K6IRDd9gSGhA=="],
|
||||
|
||||
"@dagrejs/graphlib": ["@dagrejs/graphlib@2.2.4", "", {}, "sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw=="],
|
||||
"@dagrejs/graphlib": ["@dagrejs/graphlib@3.0.4", "", {}, "sha512-HxZ7fCvAwTLCWCO0WjDkzAFQze8LdC6iOpKbetDKHIuDfIgMlIzYzqZ4nxwLlclQX+3ZVeZ1K2OuaOE2WWcyOg=="],
|
||||
|
||||
"@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
|
||||
|
||||
@@ -103,13 +103,13 @@
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@layerstack/svelte-actions": ["@layerstack/svelte-actions@1.0.1-next.14", "", { "dependencies": { "@floating-ui/dom": "^1.7.0", "@layerstack/utils": "2.0.0-next.14", "d3-scale": "^4.0.2" } }, "sha512-MPBmVaB+GfNHvBkg5nJkPG18smoXKvsvJRpsdWnrUBfca+TieZLoaEzNxDH+9LG11dIXP9gghsXt1mUqbbyAsA=="],
|
||||
"@layerstack/svelte-actions": ["@layerstack/svelte-actions@1.0.1-next.18", "", { "dependencies": { "@floating-ui/dom": "^1.7.0", "@layerstack/utils": "2.0.0-next.18", "d3-scale": "^4.0.2" } }, "sha512-gxPzCnJ1c9LTfWtRqLUzefCx+k59ZpxDUQ2XB+LokveZQPe7IDSOwHaBOEMlaGoGrtwc3Ft8dSZq+2WT2o9u/g=="],
|
||||
|
||||
"@layerstack/svelte-state": ["@layerstack/svelte-state@0.1.0-next.19", "", { "dependencies": { "@layerstack/utils": "2.0.0-next.14" } }, "sha512-yCYoQAIbeP8y1xmOB/r0+UundgP4JFnpNURgMki+26TotzoqrZ5oLpHvhPSVm60ks+buR3ebDBTeUFdHzxwzQQ=="],
|
||||
"@layerstack/svelte-state": ["@layerstack/svelte-state@0.1.0-next.23", "", { "dependencies": { "@layerstack/utils": "2.0.0-next.18" } }, "sha512-7O4umv+gXwFfs3/vjzFWYHNXGwYnnjBapWJ5Y+9u99F4eVk6rh4ocNwqkqQNkpMZ5tUJBlRTWjPE1So6+hEzIg=="],
|
||||
|
||||
"@layerstack/tailwind": ["@layerstack/tailwind@2.0.0-next.17", "", { "dependencies": { "@layerstack/utils": "^2.0.0-next.14", "clsx": "^2.1.1", "d3-array": "^3.2.4", "lodash-es": "^4.17.21", "tailwind-merge": "^3.2.0" } }, "sha512-ZSn6ouqpnzB6DKzSKLVwrUBOQsrzpDA/By2/ba9ApxgTGnaD1nyqNwrvmZ+kswdAwB4YnrGEAE4VZkKrB2+DaQ=="],
|
||||
"@layerstack/tailwind": ["@layerstack/tailwind@2.0.0-next.21", "", { "dependencies": { "@layerstack/utils": "^2.0.0-next.18", "clsx": "^2.1.1", "d3-array": "^3.2.4", "tailwind-merge": "^3.2.0" } }, "sha512-Qgp2EpmEHmjtura8MQzWicR6ztBRSsRvddakFtx9ShrLMz6jWzd6bCMVVRu44Q3ZOrtXmSu4QxjCZWu1ytvuPg=="],
|
||||
|
||||
"@layerstack/utils": ["@layerstack/utils@2.0.0-next.14", "", { "dependencies": { "d3-array": "^3.2.4", "d3-time": "^3.1.0", "d3-time-format": "^4.1.0", "lodash-es": "^4.17.21" } }, "sha512-1I2CS0Cwgs53W35qVg1eBdYhB/CiPvL3s0XE61b8jWkTHxgjBF65yYNgXjW74kv7WI7GsJcWMNBufPd0rnu9kA=="],
|
||||
"@layerstack/utils": ["@layerstack/utils@2.0.0-next.18", "", { "dependencies": { "d3-array": "^3.2.4", "d3-time": "^3.1.0", "d3-time-format": "^4.1.0" } }, "sha512-EYILHpfBRYMMEahajInu9C2AXQom5IcAEdtCeucD3QIl/fdDgRbtzn6/8QW9ewumfyNZetdUvitOksmI1+gZYQ=="],
|
||||
|
||||
"@lucide/svelte": ["@lucide/svelte@1.24.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-yXwewA7ANQ5hfaSDrvsecosWjZn5RglzeXUZRSnxeANBskpNwblOkEJTqD0ujDdNKIKL8E9eVc2U/P3ziJr7OA=="],
|
||||
|
||||
@@ -203,6 +203,10 @@
|
||||
|
||||
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||
|
||||
"@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="],
|
||||
|
||||
"@types/d3-contour": ["@types/d3-contour@3.0.6", "", { "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" } }, "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg=="],
|
||||
|
||||
"@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
|
||||
|
||||
"@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
|
||||
@@ -213,6 +217,8 @@
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@25.0.6", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-NNu0sjyNxpoiW3YuVFfNz7mxSQ+S4X2G28uqg2s+CzoqoQjLPsWSbsFFyztIAqt2vb8kfEAsJNepMGPTxFDx3Q=="],
|
||||
@@ -291,8 +297,12 @@
|
||||
|
||||
"d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
|
||||
|
||||
"d3-chord": ["d3-chord@3.0.1", "", { "dependencies": { "d3-path": "1 - 3" } }, "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="],
|
||||
|
||||
"d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
|
||||
|
||||
"d3-contour": ["d3-contour@4.0.2", "", { "dependencies": { "d3-array": "^3.2.0" } }, "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA=="],
|
||||
|
||||
"d3-delaunay": ["d3-delaunay@6.0.4", "", { "dependencies": { "delaunator": "5" } }, "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A=="],
|
||||
|
||||
"d3-dispatch": ["d3-dispatch@3.0.1", "", {}, "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="],
|
||||
@@ -451,7 +461,7 @@
|
||||
|
||||
"known-css-properties": ["known-css-properties@0.37.0", "", {}, "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="],
|
||||
|
||||
"layerchart": ["layerchart@2.0.0-next.43", "", { "dependencies": { "@dagrejs/dagre": "^1.1.5", "@layerstack/svelte-actions": "1.0.1-next.14", "@layerstack/svelte-state": "0.1.0-next.19", "@layerstack/tailwind": "2.0.0-next.17", "@layerstack/utils": "2.0.0-next.14", "d3-array": "^3.2.4", "d3-color": "^3.1.0", "d3-delaunay": "^6.0.4", "d3-dsv": "^3.0.1", "d3-force": "^3.0.0", "d3-geo": "^3.1.1", "d3-geo-voronoi": "^2.1.0", "d3-hierarchy": "^3.1.2", "d3-interpolate": "^3.0.1", "d3-interpolate-path": "^2.3.0", "d3-path": "^3.1.0", "d3-quadtree": "^3.0.1", "d3-random": "^3.0.1", "d3-sankey": "^0.12.3", "d3-scale": "^4.0.2", "d3-scale-chromatic": "^3.1.0", "d3-shape": "^3.2.0", "d3-tile": "^1.0.0", "d3-time": "^3.1.0", "lodash-es": "^4.17.21", "memoize": "^10.1.0", "runed": "^0.31.1" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-1Ywm38NdzHWKwgaAHq3EcqshIgsq+pylntSnVWAVazXUk/NsxPcxdpR3tMt3ySjWV0ZPBBgLs78sdVf7FTgd+g=="],
|
||||
"layerchart": ["layerchart@2.0.1", "", { "dependencies": { "@dagrejs/dagre": "^2.0.4", "@layerstack/svelte-actions": "1.0.1-next.18", "@layerstack/svelte-state": "0.1.0-next.23", "@layerstack/tailwind": "2.0.0-next.21", "@layerstack/utils": "2.0.0-next.18", "@types/d3-contour": "^3.0.6", "d3-array": "^3.2.4", "d3-chord": "^3.0.1", "d3-color": "^3.1.0", "d3-contour": "^4.0.2", "d3-delaunay": "^6.0.4", "d3-dsv": "^3.0.1", "d3-force": "^3.0.0", "d3-geo": "^3.1.1", "d3-geo-voronoi": "^2.1.0", "d3-hierarchy": "^3.1.2", "d3-interpolate": "^3.0.1", "d3-interpolate-path": "^2.3.0", "d3-path": "^3.1.0", "d3-quadtree": "^3.0.1", "d3-random": "^3.0.1", "d3-sankey": "^0.12.3", "d3-scale": "^4.0.2", "d3-scale-chromatic": "^3.1.0", "d3-shape": "^3.2.0", "d3-tile": "^1.0.0", "d3-time": "^3.1.0", "memoize": "^10.2.0", "runed": "^0.37.1" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-ss19hUjjZawMni60dgYsm+ZT/Fq/HYh8YSQt6D9xhN+Dc9HB6TH77FOeOl1avf7Wlpc2MG7X16SFuMGh8nR+Eg=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
||||
@@ -485,8 +495,6 @@
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash-es": ["lodash-es@4.18.1", "", {}, "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A=="],
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
|
||||
@@ -677,8 +685,6 @@
|
||||
|
||||
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||
|
||||
"@layerstack/tailwind/@layerstack/utils": ["@layerstack/utils@2.0.0-next.18", "", { "dependencies": { "d3-array": "^3.2.4", "d3-time": "^3.1.0", "d3-time-format": "^4.1.0" } }, "sha512-EYILHpfBRYMMEahajInu9C2AXQom5IcAEdtCeucD3QIl/fdDgRbtzn6/8QW9ewumfyNZetdUvitOksmI1+gZYQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="],
|
||||
@@ -707,7 +713,7 @@
|
||||
|
||||
"espree/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||
|
||||
"layerchart/runed": ["runed@0.31.1", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-v3czcTnO+EJjiPvD4dwIqfTdHLZ8oH0zJheKqAHh9QMViY7Qb29UlAMRpX7ZtHh7AFqV60KmfxaJ9QMy+L1igQ=="],
|
||||
"layerchart/runed": ["runed@0.37.1", "", { "dependencies": { "dequal": "^2.0.3", "esm-env": "^1.0.0", "lz-string": "^1.5.0" }, "peerDependencies": { "@sveltejs/kit": "^2.21.0", "svelte": "^5.7.0", "zod": "^4.1.0" }, "optionalPeers": ["@sveltejs/kit", "zod"] }, "sha512-MeFY73xBW8IueWBm012nNFIGy19WUGPLtknavyUPMpnyt350M47PhGSGrGoSLbidwn+Zlt/O0cp8/OZE3LASWA=="],
|
||||
|
||||
"mode-watcher/runed": ["runed@0.25.0", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg=="],
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-svelte": "^3.20.0",
|
||||
"globals": "^17.7.0",
|
||||
"layerchart": "2.0.0-next.43",
|
||||
"layerchart": "^2.0.1",
|
||||
"mode-watcher": "^1.1.0",
|
||||
"prettier": "^3.9.5",
|
||||
"prettier-plugin-organize-imports": "^4.3.0",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
useChart,
|
||||
type TooltipPayload
|
||||
} from '../ui/chart/chart-utils.js';
|
||||
import { getTooltipContext, Tooltip as TooltipPrimitive } from 'layerchart';
|
||||
import { getChartContext, Tooltip as TooltipPrimitive } from 'layerchart';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -61,27 +61,34 @@
|
||||
} = $props();
|
||||
|
||||
const chart = useChart();
|
||||
const tooltipCtx = getTooltipContext();
|
||||
const chartCtx = getChartContext();
|
||||
const visibleSeries = $derived(
|
||||
chartCtx.tooltip.series.filter((series: TooltipPayload) => series.value !== undefined)
|
||||
);
|
||||
|
||||
const formattedLabel = $derived.by(() => {
|
||||
if (hideLabel || !tooltipCtx.payload?.length) return null;
|
||||
if (hideLabel || !visibleSeries.length) return null;
|
||||
|
||||
const [item] = tooltipCtx.payload;
|
||||
const key = labelKey ?? item?.label ?? item?.name ?? 'value';
|
||||
const [item] = visibleSeries;
|
||||
const tooltipData = chartCtx.tooltip.data;
|
||||
const dataLabel = tooltipData != null ? chartCtx.x(tooltipData) : undefined;
|
||||
const key = labelKey ?? item?.label ?? item?.key ?? 'value';
|
||||
|
||||
const itemConfig = getPayloadConfigFromPayload(chart.config, item, key);
|
||||
const itemConfig = getPayloadConfigFromPayload(chart.config, item, key, tooltipData);
|
||||
|
||||
const value =
|
||||
!labelKey && typeof label === 'string'
|
||||
? (chart.config[label as keyof typeof chart.config]?.label ?? label)
|
||||
: (itemConfig?.label ?? item.label);
|
||||
: labelKey
|
||||
? (itemConfig?.label ?? dataLabel)
|
||||
: dataLabel;
|
||||
|
||||
if (value === undefined) return null;
|
||||
if (!labelFormatter) return value;
|
||||
return labelFormatter(value, tooltipCtx.payload);
|
||||
return labelFormatter(value, visibleSeries);
|
||||
});
|
||||
|
||||
const nestLabel = $derived(tooltipCtx.payload.length === 1 && indicator !== 'dot');
|
||||
const nestLabel = $derived(visibleSeries.length === 1 && indicator !== 'dot');
|
||||
</script>
|
||||
|
||||
{#snippet TooltipLabel()}
|
||||
@@ -98,6 +105,7 @@
|
||||
|
||||
<TooltipPrimitive.Root variant="none">
|
||||
<div
|
||||
bind:this={ref}
|
||||
class={cn(
|
||||
'border-border/50 bg-background grid min-w-[9rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl',
|
||||
className
|
||||
@@ -108,23 +116,28 @@
|
||||
{@render TooltipLabel()}
|
||||
{/if}
|
||||
<div class="grid gap-1.5">
|
||||
{#each tooltipCtx.payload as item, i (item.key + i)}
|
||||
{@const key = `${nameKey || item.key || item.name || 'value'}`}
|
||||
{@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)}
|
||||
{@const indicatorColor = color || item.payload?.color || item.color}
|
||||
{#each visibleSeries as item, i (item.key + i)}
|
||||
{@const key = `${nameKey || item.key || item.label || 'value'}`}
|
||||
{@const itemConfig = getPayloadConfigFromPayload(
|
||||
chart.config,
|
||||
item,
|
||||
key,
|
||||
chartCtx.tooltip.data
|
||||
)}
|
||||
{@const indicatorColor = color || item.config?.color || item.color}
|
||||
<div
|
||||
class={cn(
|
||||
'[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5',
|
||||
indicator === 'dot' && 'items-center'
|
||||
)}
|
||||
>
|
||||
{#if formatter && item.value !== undefined && item.name}
|
||||
{#if formatter && item.value !== undefined && item.label}
|
||||
{@render formatter({
|
||||
value: item.value,
|
||||
name: item.name,
|
||||
name: item.label,
|
||||
item,
|
||||
index: i,
|
||||
payload: tooltipCtx.payload
|
||||
payload: visibleSeries
|
||||
})}
|
||||
{:else}
|
||||
{#if itemConfig?.icon}
|
||||
@@ -151,7 +164,7 @@
|
||||
{@render TooltipLabel()}
|
||||
{/if}
|
||||
<span class="text-muted-foreground">
|
||||
{itemConfig?.label || item.name}
|
||||
{itemConfig?.label || item.label}
|
||||
</span>
|
||||
</div>
|
||||
{#if item.value !== undefined}
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
config: ChartConfig;
|
||||
} = $props();
|
||||
|
||||
// svelte-ignore state_referenced_locally
|
||||
const chartId = `chart-${id || uid.replace(/:/g, '')}`;
|
||||
const chartId = $derived(`chart-${id || uid.replace(/:/g, '')}`);
|
||||
|
||||
setChartContext({
|
||||
get config() {
|
||||
@@ -36,7 +35,7 @@
|
||||
// Overrides
|
||||
//
|
||||
// Stroke around dots/marks when hovering
|
||||
'[&_.stroke-white]:stroke-transparent',
|
||||
'[&_.lc-highlight-point]:stroke-transparent',
|
||||
// override the default stroke color of lines
|
||||
'[&_.lc-line]:stroke-border/50',
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
if (!colorConfig || !colorConfig.length) return;
|
||||
|
||||
const themeContents = [];
|
||||
for (let [_theme, prefix] of Object.entries(THEMES)) {
|
||||
for (const [_theme, prefix] of Object.entries(THEMES)) {
|
||||
let content = `${prefix} [data-chart=${id}] {\n`;
|
||||
const color = colorConfig.map(([key, itemConfig]) => {
|
||||
const theme = _theme as keyof typeof itemConfig.theme;
|
||||
@@ -30,7 +30,8 @@
|
||||
|
||||
{#if themeContents}
|
||||
{#key id}
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
{@html `<style>${themeContents}</style>`}
|
||||
<svelte:element this={"style"}>
|
||||
{themeContents}
|
||||
</svelte:element>
|
||||
{/key}
|
||||
{/if}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { cn, type WithElementRef, type WithoutChildren } from '$lib/utils.js';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { getPayloadConfigFromPayload, useChart, type TooltipPayload } from './chart-utils.js';
|
||||
import { getTooltipContext, Tooltip as TooltipPrimitive } from 'layerchart';
|
||||
import { getChartContext, Tooltip as TooltipPrimitive } from 'layerchart';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -49,27 +49,46 @@
|
||||
} = $props();
|
||||
|
||||
const chart = useChart();
|
||||
const tooltipCtx = getTooltipContext();
|
||||
const chartCtx = getChartContext();
|
||||
|
||||
// Filter to series with defined values (important for item-based charts like Pie/Arc
|
||||
// where only the hovered item has a value)
|
||||
const visibleSeries = $derived(
|
||||
chartCtx.tooltip.series.filter((s: TooltipPayload) => s.value !== undefined)
|
||||
);
|
||||
|
||||
const formattedLabel = $derived.by(() => {
|
||||
if (hideLabel || !tooltipCtx.payload?.length) return null;
|
||||
if (hideLabel || !visibleSeries?.length) return null;
|
||||
|
||||
const [item] = tooltipCtx.payload;
|
||||
const key = labelKey ?? item?.label ?? item?.name ?? 'value';
|
||||
const [item] = visibleSeries;
|
||||
const tooltipData = chartCtx.tooltip.data;
|
||||
|
||||
const itemConfig = getPayloadConfigFromPayload(chart.config, item, key);
|
||||
// Get the x-axis label value from the raw tooltip data (e.g. a Date or month string)
|
||||
const dataLabel = tooltipData != null ? chartCtx.x(tooltipData) : undefined;
|
||||
|
||||
const value =
|
||||
!labelKey && typeof label === 'string'
|
||||
? (chart.config[label as keyof typeof chart.config]?.label ?? label)
|
||||
: (itemConfig?.label ?? item.label);
|
||||
const key = labelKey ?? item?.label ?? item?.key ?? 'value';
|
||||
const itemConfig = getPayloadConfigFromPayload(
|
||||
chart.config,
|
||||
item,
|
||||
key,
|
||||
tooltipData as Record<string, unknown> | null
|
||||
);
|
||||
|
||||
let value: unknown;
|
||||
if (!labelKey && typeof label === 'string') {
|
||||
value = chart.config[label as keyof typeof chart.config]?.label ?? label;
|
||||
} else if (labelKey) {
|
||||
value = itemConfig?.label ?? dataLabel;
|
||||
} else {
|
||||
value = dataLabel;
|
||||
}
|
||||
|
||||
if (value === undefined) return null;
|
||||
if (!labelFormatter) return value;
|
||||
return labelFormatter(value, tooltipCtx.payload);
|
||||
return labelFormatter(value, visibleSeries);
|
||||
});
|
||||
|
||||
const nestLabel = $derived(tooltipCtx.payload.length === 1 && indicator !== 'dot');
|
||||
const nestLabel = $derived(visibleSeries.length === 1 && indicator !== 'dot');
|
||||
</script>
|
||||
|
||||
{#snippet TooltipLabel()}
|
||||
@@ -86,6 +105,7 @@
|
||||
|
||||
<TooltipPrimitive.Root variant="none">
|
||||
<div
|
||||
bind:this={ref}
|
||||
class={cn(
|
||||
'border-border/50 bg-background grid min-w-[9rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl',
|
||||
className
|
||||
@@ -96,23 +116,28 @@
|
||||
{@render TooltipLabel()}
|
||||
{/if}
|
||||
<div class="grid gap-1.5">
|
||||
{#each tooltipCtx.payload as item, i (item.key + i)}
|
||||
{@const key = `${nameKey || item.key || item.name || 'value'}`}
|
||||
{@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)}
|
||||
{@const indicatorColor = color || item.payload?.color || item.color}
|
||||
{#each visibleSeries as item, i (item.key + i)}
|
||||
{@const key = `${nameKey || item.key || item.label || 'value'}`}
|
||||
{@const itemConfig = getPayloadConfigFromPayload(
|
||||
chart.config,
|
||||
item,
|
||||
key,
|
||||
chartCtx.tooltip.data
|
||||
)}
|
||||
{@const indicatorColor = color || item.config?.color || item.color}
|
||||
<div
|
||||
class={cn(
|
||||
'[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5',
|
||||
indicator === 'dot' && 'items-center'
|
||||
)}
|
||||
>
|
||||
{#if formatter && item.value !== undefined && item.name}
|
||||
{#if formatter && item.value !== undefined && item.label}
|
||||
{@render formatter({
|
||||
value: item.value,
|
||||
name: item.name,
|
||||
name: item.label,
|
||||
item,
|
||||
index: i,
|
||||
payload: tooltipCtx.payload
|
||||
payload: visibleSeries
|
||||
})}
|
||||
{:else}
|
||||
{#if itemConfig?.icon}
|
||||
@@ -139,7 +164,7 @@
|
||||
{@render TooltipLabel()}
|
||||
{/if}
|
||||
<span class="text-muted-foreground">
|
||||
{itemConfig?.label || item.name}
|
||||
{itemConfig?.label || item.label}
|
||||
</span>
|
||||
</div>
|
||||
{#if item.value !== undefined}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Tooltip } from 'layerchart';
|
||||
import { getContext, setContext, type Component, type ComponentProps, type Snippet } from 'svelte';
|
||||
import { getContext, setContext, type Component, type Snippet } from 'svelte';
|
||||
|
||||
export const THEMES = { light: '', dark: '.dark' } as const;
|
||||
|
||||
@@ -15,37 +15,39 @@ export type ChartConfig = {
|
||||
|
||||
export type ExtractSnippetParams<T> = T extends Snippet<[infer P]> ? P : never;
|
||||
|
||||
export type TooltipPayload = ExtractSnippetParams<
|
||||
ComponentProps<typeof Tooltip.Root>['children']
|
||||
>['payload'][number];
|
||||
export type TooltipPayload = Tooltip.TooltipSeries;
|
||||
|
||||
// Helper to extract item config from a payload.
|
||||
export function getPayloadConfigFromPayload(
|
||||
config: ChartConfig,
|
||||
payload: TooltipPayload,
|
||||
key: string
|
||||
key: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
data?: Record<string, any> | null
|
||||
) {
|
||||
if (typeof payload !== 'object' || payload === null) return undefined;
|
||||
|
||||
const payloadPayload =
|
||||
'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null
|
||||
? payload.payload
|
||||
const payloadConfig =
|
||||
'config' in payload && typeof payload.config === 'object' && payload.config !== null
|
||||
? payload.config
|
||||
: undefined;
|
||||
|
||||
let configLabelKey: string = key;
|
||||
|
||||
if (payload.key === key) {
|
||||
configLabelKey = payload.key;
|
||||
} else if (payload.name === key) {
|
||||
configLabelKey = payload.name;
|
||||
} else if (payload.label === key) {
|
||||
configLabelKey = payload.label;
|
||||
} else if (key in payload && typeof payload[key as keyof typeof payload] === 'string') {
|
||||
configLabelKey = payload[key as keyof typeof payload] as string;
|
||||
} else if (
|
||||
payloadPayload !== undefined &&
|
||||
key in payloadPayload &&
|
||||
typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'
|
||||
payloadConfig !== undefined &&
|
||||
key in payloadConfig &&
|
||||
typeof payloadConfig[key as keyof typeof payloadConfig] === 'string'
|
||||
) {
|
||||
configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;
|
||||
configLabelKey = payloadConfig[key as keyof typeof payloadConfig] as string;
|
||||
} else if (data != null && key in data && typeof data[key] === 'string') {
|
||||
configLabelKey = data[key] as string;
|
||||
}
|
||||
|
||||
return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config];
|
||||
|
||||
Reference in New Issue
Block a user