@vielzeug/prism 26.10.0 → 26.10.1
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/README.md +2 -2
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +1 -1
- package/dist/_dev.js.map +1 -1
- package/dist/animation/easing.cjs.map +1 -1
- package/dist/animation/easing.js.map +1 -1
- package/dist/axes/axis.cjs +1 -1
- package/dist/axes/axis.cjs.map +1 -1
- package/dist/axes/axis.d.ts +2 -2
- package/dist/axes/axis.d.ts.map +1 -1
- package/dist/axes/axis.js +1 -1
- package/dist/axes/axis.js.map +1 -1
- package/dist/axes/scale-utils.cjs.map +1 -1
- package/dist/axes/scale-utils.d.ts +1 -1
- package/dist/axes/scale-utils.js.map +1 -1
- package/dist/charts/area/area-chart.cjs +1 -1
- package/dist/charts/area/area-chart.cjs.map +1 -1
- package/dist/charts/area/area-chart.d.ts.map +1 -1
- package/dist/charts/area/area-chart.js +1 -1
- package/dist/charts/area/area-chart.js.map +1 -1
- package/dist/charts/area/area-renderer.cjs +1 -1
- package/dist/charts/area/area-renderer.cjs.map +1 -1
- package/dist/charts/area/area-renderer.d.ts +4 -2
- package/dist/charts/area/area-renderer.d.ts.map +1 -1
- package/dist/charts/area/area-renderer.js +1 -1
- package/dist/charts/area/area-renderer.js.map +1 -1
- package/dist/charts/bar/bar-chart.cjs +1 -1
- package/dist/charts/bar/bar-chart.cjs.map +1 -1
- package/dist/charts/bar/bar-chart.d.ts.map +1 -1
- package/dist/charts/bar/bar-chart.js +1 -1
- package/dist/charts/bar/bar-chart.js.map +1 -1
- package/dist/charts/bar/bar-hit-test.cjs +1 -1
- package/dist/charts/bar/bar-hit-test.cjs.map +1 -1
- package/dist/charts/bar/bar-hit-test.d.ts +0 -5
- package/dist/charts/bar/bar-hit-test.d.ts.map +1 -1
- package/dist/charts/bar/bar-hit-test.js +1 -1
- package/dist/charts/bar/bar-hit-test.js.map +1 -1
- package/dist/charts/bar/bar-renderer.cjs.map +1 -1
- package/dist/charts/bar/bar-renderer.d.ts +1 -1
- package/dist/charts/bar/bar-renderer.d.ts.map +1 -1
- package/dist/charts/bar/bar-renderer.js.map +1 -1
- package/dist/charts/line/line-chart.cjs +1 -1
- package/dist/charts/line/line-chart.cjs.map +1 -1
- package/dist/charts/line/line-chart.d.ts.map +1 -1
- package/dist/charts/line/line-chart.js +1 -1
- package/dist/charts/line/line-chart.js.map +1 -1
- package/dist/charts/line/line-renderer.cjs +1 -1
- package/dist/charts/line/line-renderer.cjs.map +1 -1
- package/dist/charts/line/line-renderer.d.ts +3 -2
- package/dist/charts/line/line-renderer.d.ts.map +1 -1
- package/dist/charts/line/line-renderer.js +1 -1
- package/dist/charts/line/line-renderer.js.map +1 -1
- package/dist/charts/pie/pie-chart.cjs +1 -1
- package/dist/charts/pie/pie-chart.cjs.map +1 -1
- package/dist/charts/pie/pie-chart.d.ts.map +1 -1
- package/dist/charts/pie/pie-chart.js +1 -1
- package/dist/charts/pie/pie-chart.js.map +1 -1
- package/dist/charts/pie/pie-renderer.cjs +1 -1
- package/dist/charts/pie/pie-renderer.cjs.map +1 -1
- package/dist/charts/pie/pie-renderer.d.ts.map +1 -1
- package/dist/charts/pie/pie-renderer.js +1 -1
- package/dist/charts/pie/pie-renderer.js.map +1 -1
- package/dist/charts/radar/index.d.ts +2 -0
- package/dist/charts/radar/index.d.ts.map +1 -0
- package/dist/charts/radar/radar-chart.cjs +2 -0
- package/dist/charts/radar/radar-chart.cjs.map +1 -0
- package/dist/charts/radar/radar-chart.d.ts +3 -0
- package/dist/charts/radar/radar-chart.d.ts.map +1 -0
- package/dist/charts/radar/radar-chart.js +2 -0
- package/dist/charts/radar/radar-chart.js.map +1 -0
- package/dist/charts/radar/radar-geometry.cjs +2 -0
- package/dist/charts/radar/radar-geometry.cjs.map +1 -0
- package/dist/charts/radar/radar-geometry.d.ts +22 -0
- package/dist/charts/radar/radar-geometry.d.ts.map +1 -0
- package/dist/charts/radar/radar-geometry.js +2 -0
- package/dist/charts/radar/radar-geometry.js.map +1 -0
- package/dist/charts/sparkline/sparkline.cjs +1 -1
- package/dist/charts/sparkline/sparkline.cjs.map +1 -1
- package/dist/charts/sparkline/sparkline.d.ts.map +1 -1
- package/dist/charts/sparkline/sparkline.js +1 -1
- package/dist/charts/sparkline/sparkline.js.map +1 -1
- package/dist/core/cartesian-scales.cjs +1 -1
- package/dist/core/cartesian-scales.cjs.map +1 -1
- package/dist/core/cartesian-scales.js +1 -1
- package/dist/core/cartesian-scales.js.map +1 -1
- package/dist/core/chart-base.cjs +1 -1
- package/dist/core/chart-base.cjs.map +1 -1
- package/dist/core/chart-base.d.ts +9 -0
- package/dist/core/chart-base.d.ts.map +1 -1
- package/dist/core/chart-base.js +1 -1
- package/dist/core/chart-base.js.map +1 -1
- package/dist/core/chart-scaffold.cjs +1 -1
- package/dist/core/chart-scaffold.cjs.map +1 -1
- package/dist/core/chart-scaffold.d.ts +7 -3
- package/dist/core/chart-scaffold.d.ts.map +1 -1
- package/dist/core/chart-scaffold.js +1 -1
- package/dist/core/chart-scaffold.js.map +1 -1
- package/dist/core/ids.cjs +2 -0
- package/dist/core/ids.cjs.map +1 -0
- package/dist/core/ids.d.ts +3 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +2 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/polar.cjs +2 -0
- package/dist/core/polar.cjs.map +1 -0
- package/dist/core/polar.d.ts +5 -0
- package/dist/core/polar.d.ts.map +1 -0
- package/dist/core/polar.js +2 -0
- package/dist/core/polar.js.map +1 -0
- package/dist/devtools/index.d.ts +1 -1
- package/dist/devtools.cjs.map +1 -1
- package/dist/devtools.js.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/interaction/announcer.cjs +2 -0
- package/dist/interaction/announcer.cjs.map +1 -0
- package/dist/interaction/announcer.d.ts +13 -0
- package/dist/interaction/announcer.d.ts.map +1 -0
- package/dist/interaction/announcer.js +2 -0
- package/dist/interaction/announcer.js.map +1 -0
- package/dist/interaction/crosshair.cjs +1 -1
- package/dist/interaction/crosshair.cjs.map +1 -1
- package/dist/interaction/crosshair.d.ts +1 -5
- package/dist/interaction/crosshair.d.ts.map +1 -1
- package/dist/interaction/crosshair.js +1 -1
- package/dist/interaction/crosshair.js.map +1 -1
- package/dist/interaction/series-interaction.cjs +1 -1
- package/dist/interaction/series-interaction.cjs.map +1 -1
- package/dist/interaction/series-interaction.d.ts +11 -1
- package/dist/interaction/series-interaction.d.ts.map +1 -1
- package/dist/interaction/series-interaction.js +1 -1
- package/dist/interaction/series-interaction.js.map +1 -1
- package/dist/interaction/tooltip.cjs +1 -1
- package/dist/interaction/tooltip.cjs.map +1 -1
- package/dist/interaction/tooltip.d.ts +12 -1
- package/dist/interaction/tooltip.d.ts.map +1 -1
- package/dist/interaction/tooltip.js +1 -1
- package/dist/interaction/tooltip.js.map +1 -1
- package/dist/prism.cjs +1 -1
- package/dist/prism.cjs.map +1 -1
- package/dist/prism.iife.js +1 -1
- package/dist/prism.iife.js.map +1 -1
- package/dist/prism.js +1 -1
- package/dist/prism.js.map +1 -1
- package/dist/scales/band.cjs.map +1 -1
- package/dist/scales/band.js.map +1 -1
- package/dist/scales/linear.cjs.map +1 -1
- package/dist/scales/linear.js.map +1 -1
- package/dist/scales/time.cjs.map +1 -1
- package/dist/scales/time.js.map +1 -1
- package/dist/svg/element.cjs.map +1 -1
- package/dist/svg/element.js.map +1 -1
- package/dist/svg/text.cjs +1 -1
- package/dist/svg/text.cjs.map +1 -1
- package/dist/svg/text.d.ts +1 -0
- package/dist/svg/text.d.ts.map +1 -1
- package/dist/svg/text.js +1 -1
- package/dist/svg/text.js.map +1 -1
- package/dist/theme/index.cjs.map +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/prism.css +214 -7
- package/dist/types.d.ts +65 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line-renderer.cjs","names":[],"sources":["../../../src/charts/line/line-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface LineRenderOptions {\n color: string;\n curve: 'linear' | 'monotone' | 'step';\n /** Aborted when the owning chart is disposed
|
|
1
|
+
{"version":3,"file":"line-renderer.cjs","names":[],"sources":["../../../src/charts/line/line-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface LineRenderOptions {\n color: string;\n curve: 'linear' | 'monotone' | 'step';\n /** Aborted when the owning chart is disposed: stops the transition's `requestAnimationFrame` loop from rescheduling. */\n disposalSignal?: AbortSignal;\n pointRadius: number;\n showPoints: boolean;\n /** Explicit width beats the `--prism-line-width` theme token. */\n strokeWidth?: number;\n transition?: TransitionConfig;\n}\n\nconst activeAnimations = new WeakMap<SVGGElement, () => void>();\n\nfunction buildPath(pts: Point[], curve: LineRenderOptions['curve']): string {\n return curve === 'monotone' ? monotonePath(pts) : curve === 'step' ? stepPath(pts) : linePath(pts);\n}\n\nexport function renderLine(parent: SVGGElement, points: Point[], options: LineRenderOptions): void {\n const motion = resolveMotion(options.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n let path = parent.querySelector<SVGPathElement>('.prism-line-path');\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-line-path', fill: 'none' });\n parent.appendChild(path);\n }\n\n setAttributes(path, { stroke: options.color, 'stroke-width': options.strokeWidth ?? 2 });\n path.style.strokeWidth = options.strokeWidth === undefined ? '' : String(options.strokeWidth);\n\n let dotsGroup = parent.querySelector<SVGGElement>('.prism-line-dots');\n\n if (options.showPoints) {\n if (!dotsGroup) {\n dotsGroup = createSvgElement('g', { class: 'prism-line-dots' });\n parent.appendChild(dotsGroup);\n }\n } else if (dotsGroup) {\n dotsGroup.remove();\n dotsGroup = null;\n }\n\n if (dur === 0) {\n setAttributes(path, { d: buildPath(points, options.curve) });\n\n if (dotsGroup) {\n while (dotsGroup.children.length > points.length) dotsGroup.removeChild(dotsGroup.lastChild!);\n\n for (let i = 0; i < points.length; i++) {\n let c = dotsGroup.children[i] as SVGCircleElement | undefined;\n\n if (!c) {\n c = createSvgElement('circle', { class: 'prism-line-dot' });\n dotsGroup.appendChild(c);\n }\n\n setAttributes(c, { cx: points[i].x, cy: points[i].y, fill: options.color, r: options.pointRadius });\n }\n }\n\n return;\n }\n\n activeAnimations.get(parent)?.();\n\n const hasExisting = !!path.getAttribute('d');\n\n const fromPts: Point[] = [];\n let lastKnown: Point | null = null;\n\n if (dotsGroup) {\n const existingCount = dotsGroup.children.length;\n\n for (let i = 0; i < existingCount; i++) {\n const c = dotsGroup.children[i] as SVGCircleElement;\n const pt = { x: Number(c.getAttribute('cx')), y: Number(c.getAttribute('cy')) };\n\n fromPts.push(pt);\n lastKnown = pt;\n }\n\n while (dotsGroup.children.length > points.length) dotsGroup.removeChild(dotsGroup.lastChild!);\n\n for (let i = dotsGroup.children.length; i < points.length; i++) {\n const c = createSvgElement('circle', { class: 'prism-line-dot' });\n\n setAttributes(c, { cx: points[i].x, cy: points[i].y, fill: options.color, r: options.pointRadius });\n dotsGroup.appendChild(c);\n }\n }\n\n for (let i = fromPts.length; i < points.length; i++) {\n fromPts.push(lastKnown ?? points[i]);\n }\n\n let startTime: number | null = null;\n\n function frame(ts: number) {\n if (options.disposalSignal?.aborted) {\n activeAnimations.delete(parent);\n\n return;\n }\n\n if (startTime === null) startTime = ts;\n\n const t = Math.min(1, (ts - startTime) / dur);\n const e = easing(t);\n const interpolated: Point[] = points.map((to, i) => {\n const from = fromPts[i] ?? to;\n\n return { x: tweenNumber(from.x, to.x, e), y: tweenNumber(from.y, to.y, e) };\n });\n\n setAttributes(path!, { d: buildPath(interpolated, options.curve) });\n\n if (dotsGroup) {\n for (let i = 0; i < points.length; i++) {\n const c = dotsGroup.children[i] as SVGCircleElement | undefined;\n\n if (c) setAttributes(c, { cx: interpolated[i].x, cy: interpolated[i].y });\n }\n }\n\n if (t < 1) {\n const id = requestAnimationFrame(frame);\n\n activeAnimations.set(parent, () => cancelAnimationFrame(id));\n } else {\n activeAnimations.delete(parent);\n }\n }\n\n if (!hasExisting) {\n setAttributes(path, { d: buildPath(points, options.curve) });\n } else {\n const id = requestAnimationFrame(frame);\n\n activeAnimations.set(parent, () => cancelAnimationFrame(id));\n }\n}\n\nexport function computePoints(data: ContinuousDatum[], xScale: Scale<Date | number>, yScale: Scale<number>): Point[] {\n if (data.some((d) => d.key == null)) {\n warn(\n 'computePoints: datum.key is null or undefined: data must use the Datum shape { key, value }. Did you pass { x, y } instead?',\n );\n } else if (data.some((d) => typeof d.key === 'string')) {\n warn('computePoints: string keys are not supported for line/area charts: use numeric or Date keys.');\n }\n\n return data.map((d) => ({\n x: xScale.map(d.key as Date | number),\n y: yScale.map(d.value),\n }));\n}\n"],"mappings":"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"}
|
|
@@ -3,11 +3,12 @@ import type { ContinuousDatum, Scale, TransitionConfig } from '../../types';
|
|
|
3
3
|
export interface LineRenderOptions {
|
|
4
4
|
color: string;
|
|
5
5
|
curve: 'linear' | 'monotone' | 'step';
|
|
6
|
-
/** Aborted when the owning chart is disposed
|
|
6
|
+
/** Aborted when the owning chart is disposed: stops the transition's `requestAnimationFrame` loop from rescheduling. */
|
|
7
7
|
disposalSignal?: AbortSignal;
|
|
8
8
|
pointRadius: number;
|
|
9
9
|
showPoints: boolean;
|
|
10
|
-
|
|
10
|
+
/** Explicit width beats the `--prism-line-width` theme token. */
|
|
11
|
+
strokeWidth?: number;
|
|
11
12
|
transition?: TransitionConfig;
|
|
12
13
|
}
|
|
13
14
|
export declare function renderLine(parent: SVGGElement, points: Point[], options: LineRenderOptions): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line-renderer.d.ts","sourceRoot":"","sources":["../../../src/charts/line/line-renderer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,
|
|
1
|
+
{"version":3,"file":"line-renderer.d.ts","sourceRoot":"","sources":["../../../src/charts/line/line-renderer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,wHAAwH;IACxH,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAQD,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CA6HjG;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAanH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_dev.js";import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{resolveEasing as n}from"../../animation/easing.js";import{resolveMotion as r}from"../../animation/motion.js";import{tweenNumber as i}from"../../animation/tween.js";import{linePath as a,monotonePath as o,stepPath as s}from"../../svg/path.js";var c=new WeakMap;function buildPath(e,t){return t===`monotone`?o(e):t===`step`?s(e):a(e)}function renderLine(a,o,s){let l=r(s.transition,0),u=l.duration,d=n(l.easing),f=a.querySelector(`.prism-line-path`);f||(f=e(`path`,{class:`prism-line-path`,fill:`none`}),a.appendChild(f)),t(f,{stroke:s.color,"stroke-width":s.strokeWidth});let p=a.querySelector(`.prism-line-dots`);if(s.showPoints?p||(p=e(`g`,{class:`prism-line-dots`}),a.appendChild(p)):p&&=(p.remove(),null),u===0){if(t(f,{d:buildPath(o,s.curve)}),p){for(;p.children.length>o.length;)p.removeChild(p.lastChild);for(let n=0;n<o.length;n++){let r=p.children[n];r||(r=e(`circle`,{class:`prism-line-dot`}),p.appendChild(r)),t(r,{cx:o[n].x,cy:o[n].y,fill:s.color,r:s.pointRadius})}}return}c.get(a)?.();let m=!!f.getAttribute(`d`),h=[],g=null;if(p){let n=p.children.length;for(let e=0;e<n;e++){let t=p.children[e],n={x:Number(t.getAttribute(`cx`)),y:Number(t.getAttribute(`cy`))};h.push(n),g=n}for(;p.children.length>o.length;)p.removeChild(p.lastChild);for(let n=p.children.length;n<o.length;n++){let r=e(`circle`,{class:`prism-line-dot`});t(r,{cx:o[n].x,cy:o[n].y,fill:s.color,r:s.pointRadius}),p.appendChild(r)}}for(let e=h.length;e<o.length;e++)h.push(g??o[e]);let _=null;function frame(e){if(s.disposalSignal?.aborted){c.delete(a);return}_===null&&(_=e);let n=Math.min(1,(e-_)/u),r=d(n),l=o.map((e,t)=>{let n=h[t]??e;return{x:i(n.x,e.x,r),y:i(n.y,e.y,r)}});if(t(f,{d:buildPath(l,s.curve)}),p)for(let e=0;e<o.length;e++){let n=p.children[e];n&&t(n,{cx:l[e].x,cy:l[e].y})}if(n<1){let e=requestAnimationFrame(frame);c.set(a,()=>cancelAnimationFrame(e))}else c.delete(a)}if(!m)t(f,{d:buildPath(o,s.curve)});else{let e=requestAnimationFrame(frame);c.set(a,()=>cancelAnimationFrame(e))}}function computePoints(e,t,n){return e.some(e=>e.key==null)||e.some(e=>typeof e.key==`string`),e.map(e=>({x:t.map(e.key),y:n.map(e.value)}))}export{computePoints,renderLine};
|
|
1
|
+
import"../../_dev.js";import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{resolveEasing as n}from"../../animation/easing.js";import{resolveMotion as r}from"../../animation/motion.js";import{tweenNumber as i}from"../../animation/tween.js";import{linePath as a,monotonePath as o,stepPath as s}from"../../svg/path.js";var c=new WeakMap;function buildPath(e,t){return t===`monotone`?o(e):t===`step`?s(e):a(e)}function renderLine(a,o,s){let l=r(s.transition,0),u=l.duration,d=n(l.easing),f=a.querySelector(`.prism-line-path`);f||(f=e(`path`,{class:`prism-line-path`,fill:`none`}),a.appendChild(f)),t(f,{stroke:s.color,"stroke-width":s.strokeWidth??2}),f.style.strokeWidth=s.strokeWidth===void 0?``:String(s.strokeWidth);let p=a.querySelector(`.prism-line-dots`);if(s.showPoints?p||(p=e(`g`,{class:`prism-line-dots`}),a.appendChild(p)):p&&=(p.remove(),null),u===0){if(t(f,{d:buildPath(o,s.curve)}),p){for(;p.children.length>o.length;)p.removeChild(p.lastChild);for(let n=0;n<o.length;n++){let r=p.children[n];r||(r=e(`circle`,{class:`prism-line-dot`}),p.appendChild(r)),t(r,{cx:o[n].x,cy:o[n].y,fill:s.color,r:s.pointRadius})}}return}c.get(a)?.();let m=!!f.getAttribute(`d`),h=[],g=null;if(p){let n=p.children.length;for(let e=0;e<n;e++){let t=p.children[e],n={x:Number(t.getAttribute(`cx`)),y:Number(t.getAttribute(`cy`))};h.push(n),g=n}for(;p.children.length>o.length;)p.removeChild(p.lastChild);for(let n=p.children.length;n<o.length;n++){let r=e(`circle`,{class:`prism-line-dot`});t(r,{cx:o[n].x,cy:o[n].y,fill:s.color,r:s.pointRadius}),p.appendChild(r)}}for(let e=h.length;e<o.length;e++)h.push(g??o[e]);let _=null;function frame(e){if(s.disposalSignal?.aborted){c.delete(a);return}_===null&&(_=e);let n=Math.min(1,(e-_)/u),r=d(n),l=o.map((e,t)=>{let n=h[t]??e;return{x:i(n.x,e.x,r),y:i(n.y,e.y,r)}});if(t(f,{d:buildPath(l,s.curve)}),p)for(let e=0;e<o.length;e++){let n=p.children[e];n&&t(n,{cx:l[e].x,cy:l[e].y})}if(n<1){let e=requestAnimationFrame(frame);c.set(a,()=>cancelAnimationFrame(e))}else c.delete(a)}if(!m)t(f,{d:buildPath(o,s.curve)});else{let e=requestAnimationFrame(frame);c.set(a,()=>cancelAnimationFrame(e))}}function computePoints(e,t,n){return e.some(e=>e.key==null)||e.some(e=>typeof e.key==`string`),e.map(e=>({x:t.map(e.key),y:n.map(e.value)}))}export{computePoints,renderLine};
|
|
2
2
|
//# sourceMappingURL=line-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line-renderer.js","names":[],"sources":["../../../src/charts/line/line-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface LineRenderOptions {\n color: string;\n curve: 'linear' | 'monotone' | 'step';\n /** Aborted when the owning chart is disposed
|
|
1
|
+
{"version":3,"file":"line-renderer.js","names":[],"sources":["../../../src/charts/line/line-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface LineRenderOptions {\n color: string;\n curve: 'linear' | 'monotone' | 'step';\n /** Aborted when the owning chart is disposed: stops the transition's `requestAnimationFrame` loop from rescheduling. */\n disposalSignal?: AbortSignal;\n pointRadius: number;\n showPoints: boolean;\n /** Explicit width beats the `--prism-line-width` theme token. */\n strokeWidth?: number;\n transition?: TransitionConfig;\n}\n\nconst activeAnimations = new WeakMap<SVGGElement, () => void>();\n\nfunction buildPath(pts: Point[], curve: LineRenderOptions['curve']): string {\n return curve === 'monotone' ? monotonePath(pts) : curve === 'step' ? stepPath(pts) : linePath(pts);\n}\n\nexport function renderLine(parent: SVGGElement, points: Point[], options: LineRenderOptions): void {\n const motion = resolveMotion(options.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n let path = parent.querySelector<SVGPathElement>('.prism-line-path');\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-line-path', fill: 'none' });\n parent.appendChild(path);\n }\n\n setAttributes(path, { stroke: options.color, 'stroke-width': options.strokeWidth ?? 2 });\n path.style.strokeWidth = options.strokeWidth === undefined ? '' : String(options.strokeWidth);\n\n let dotsGroup = parent.querySelector<SVGGElement>('.prism-line-dots');\n\n if (options.showPoints) {\n if (!dotsGroup) {\n dotsGroup = createSvgElement('g', { class: 'prism-line-dots' });\n parent.appendChild(dotsGroup);\n }\n } else if (dotsGroup) {\n dotsGroup.remove();\n dotsGroup = null;\n }\n\n if (dur === 0) {\n setAttributes(path, { d: buildPath(points, options.curve) });\n\n if (dotsGroup) {\n while (dotsGroup.children.length > points.length) dotsGroup.removeChild(dotsGroup.lastChild!);\n\n for (let i = 0; i < points.length; i++) {\n let c = dotsGroup.children[i] as SVGCircleElement | undefined;\n\n if (!c) {\n c = createSvgElement('circle', { class: 'prism-line-dot' });\n dotsGroup.appendChild(c);\n }\n\n setAttributes(c, { cx: points[i].x, cy: points[i].y, fill: options.color, r: options.pointRadius });\n }\n }\n\n return;\n }\n\n activeAnimations.get(parent)?.();\n\n const hasExisting = !!path.getAttribute('d');\n\n const fromPts: Point[] = [];\n let lastKnown: Point | null = null;\n\n if (dotsGroup) {\n const existingCount = dotsGroup.children.length;\n\n for (let i = 0; i < existingCount; i++) {\n const c = dotsGroup.children[i] as SVGCircleElement;\n const pt = { x: Number(c.getAttribute('cx')), y: Number(c.getAttribute('cy')) };\n\n fromPts.push(pt);\n lastKnown = pt;\n }\n\n while (dotsGroup.children.length > points.length) dotsGroup.removeChild(dotsGroup.lastChild!);\n\n for (let i = dotsGroup.children.length; i < points.length; i++) {\n const c = createSvgElement('circle', { class: 'prism-line-dot' });\n\n setAttributes(c, { cx: points[i].x, cy: points[i].y, fill: options.color, r: options.pointRadius });\n dotsGroup.appendChild(c);\n }\n }\n\n for (let i = fromPts.length; i < points.length; i++) {\n fromPts.push(lastKnown ?? points[i]);\n }\n\n let startTime: number | null = null;\n\n function frame(ts: number) {\n if (options.disposalSignal?.aborted) {\n activeAnimations.delete(parent);\n\n return;\n }\n\n if (startTime === null) startTime = ts;\n\n const t = Math.min(1, (ts - startTime) / dur);\n const e = easing(t);\n const interpolated: Point[] = points.map((to, i) => {\n const from = fromPts[i] ?? to;\n\n return { x: tweenNumber(from.x, to.x, e), y: tweenNumber(from.y, to.y, e) };\n });\n\n setAttributes(path!, { d: buildPath(interpolated, options.curve) });\n\n if (dotsGroup) {\n for (let i = 0; i < points.length; i++) {\n const c = dotsGroup.children[i] as SVGCircleElement | undefined;\n\n if (c) setAttributes(c, { cx: interpolated[i].x, cy: interpolated[i].y });\n }\n }\n\n if (t < 1) {\n const id = requestAnimationFrame(frame);\n\n activeAnimations.set(parent, () => cancelAnimationFrame(id));\n } else {\n activeAnimations.delete(parent);\n }\n }\n\n if (!hasExisting) {\n setAttributes(path, { d: buildPath(points, options.curve) });\n } else {\n const id = requestAnimationFrame(frame);\n\n activeAnimations.set(parent, () => cancelAnimationFrame(id));\n }\n}\n\nexport function computePoints(data: ContinuousDatum[], xScale: Scale<Date | number>, yScale: Scale<number>): Point[] {\n if (data.some((d) => d.key == null)) {\n warn(\n 'computePoints: datum.key is null or undefined: data must use the Datum shape { key, value }. Did you pass { x, y } instead?',\n );\n } else if (data.some((d) => typeof d.key === 'string')) {\n warn('computePoints: string keys are not supported for line/area charts: use numeric or Date keys.');\n }\n\n return data.map((d) => ({\n x: xScale.map(d.key as Date | number),\n y: yScale.map(d.value),\n }));\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../svg/element.cjs"),t=require("../../core/chart-scaffold.cjs"),
|
|
1
|
+
const e=require("../../svg/element.cjs"),t=require("../../svg/text.cjs"),n=require("../../core/chart-scaffold.cjs"),r=require("../../theme/index.cjs"),i=require("../../animation/easing.cjs"),a=require("../../animation/motion.cjs"),o=require("../../animation/tween.cjs"),s=require("./pie-renderer.cjs");var c=2*Math.PI,l=12;function labelFits(e,n){let r=e.outerRadius-e.innerRadius,i=(e.outerRadius+e.innerRadius)/2,a=(e.endAngle-e.startAngle-2*e.padAngle)*i;return r>=l*1.4&&a>=t.estimateTextWidth(n,l)+8}var u=-Math.PI/2,d=Math.PI/2;function semiAngles(e){return e===`semi`?{end:d,start:u}:{end:c,start:0}}function createPieChart(t,c){let l=c.variant??`pie`,u=c.padPixels??(l===`pie`?0:8),d=c.cornerRadius??(l===`pie`?0:8),f=c.data,p=e.createSvgElement(`circle`,{class:`prism-pie-bg`,"pointer-events":`none`}),m=e.createSvgElement(`g`,{class:`prism-pie-slices`,"shape-rendering":`geometricPrecision`}),h=e.createSvgElement(`g`,{class:`prism-pie-labels`,"pointer-events":`none`}),g=[],_=null;function renderLabels(t){h.replaceChildren();for(let n=0;n<g.length;n++){let r=g[n],i=t[n];if(!i?.label||!labelFits(r,i.label))continue;let{x:a,y:o}=s.arcCentroid(r),c=e.createSvgElement(`text`,{class:`prism-pie-label`});e.setAttributes(c,{"dominant-baseline":`middle`,fill:`var(--prism-pie-label-color, #fff)`,"font-family":`var(--prism-font-family, system-ui)`,"font-size":`var(--prism-pie-label-size, 12px)`,"text-anchor":`middle`,x:a,y:o}),c.textContent=i.label,h.appendChild(c)}}let v;try{return v=n.createRadialScaffold(t,{a11y:c.a11y,legend:c.legend,tooltip:c.tooltip},n=>{let{legend:v,svg:y,tooltip:b}=n;y.contains(p)||(y.appendChild(p),y.appendChild(m),y.appendChild(h));let{height:x,width:S}=n.dimensions,C=l===`semi`,w=S/2,T=C?x*.85:x/2,E=C?Math.min(w,T)-8:Math.min(S,x)/2-8,D=l===`pie`?0:Math.round(E*.55),O=c.innerRadius===void 0?D:c.innerRadius,k=Math.max(O+1,E),A=f,{end:j,start:M}=semiAngles(l);for(g=s.computeArcs(A,w,T,k,O,M,j,u,d,e=>r.seriesColor(e),!1),e.setAttributes(p,{cx:w,cy:T,r:O>0?O:0}),p.setAttribute(`style`,`fill:var(--prism-bg,#fff)`);m.children.length>g.length;)m.removeChild(m.lastChild);h.replaceChildren();let N=a.resolveMotion(c.transition,0),P=N.duration,F=i.resolveEasing(N.easing);for(let t=0;t<g.length;t++){let n=g[t],r=m.children[t];r||(r=e.createSvgElement(`path`,{class:`prism-pie-slice`}),m.appendChild(r)),r.setAttribute(`fill`,n.color),r.setAttribute(`stroke`,`none`),r.style.cursor=c.onClick||c.onHover?`pointer`:``}if(_!==null&&(cancelAnimationFrame(_),_=null),P>0){let t=null,frame=n=>{t===null&&(t=n);let r=F(Math.min(1,(n-t)/P)),i=o.tweenNumber(M,j,r);for(let t=0;t<g.length;t++){let n=g[t],r=m.children[t];if(r){if(i<=n.startAngle)e.setAttributes(r,{d:``});else{let t=Math.min(n.endAngle,i);e.setAttributes(r,{d:s.arcPath({...n,endAngle:t})})}}}r<1?_=requestAnimationFrame(frame):(_=null,renderLabels(A))};_=requestAnimationFrame(frame)}else{for(let t=0;t<g.length;t++){let n=g[t],r=m.children[t];r&&e.setAttributes(r,{d:s.arcPath(n)})}renderLabels(A)}v?.update(g.map(e=>({color:e.color,name:e.slice.label??``}))),b?.hide();let I=g.reduce((e,t)=>e+Math.max(0,t.slice.value),0),L=-1,describe=e=>{let t=I>0?Math.round(Math.max(0,e.slice.value)/I*1e3)/10:0;return`${e.slice.label??`Slice ${e.index+1}`}: ${e.slice.value} (${t}%)`},setActive=e=>{L=e,m.classList.toggle(`prism-pie-focused`,e>=0);for(let[t,n]of[...m.children].entries())n.classList.toggle(`prism-pie-slice--active`,t===e)},activate=e=>{let r=g[e];if(!r)return;setActive(e),c.onHover?.(r.slice,e);let i=describe(r);if(!b){n.announcer.announce(i);return}let{x:a,y:o}=s.arcCentroid(r),l=y.getBoundingClientRect(),u=t.getBoundingClientRect();b.show(a+(l.left-u.left),o+(l.top-u.top),{key:e,value:r.slice.value},{color:r.color,data:[],name:r.slice.label??``},i)},deactivate=()=>{setActive(-1),b?.hide(),n.announcer.clear(),c.onHover?.(null,null)},hitAt=e=>{let t=y.getBoundingClientRect();return hitTestArc(g,e.clientX-t.left,e.clientY-t.top,l)},onMouseMove=e=>{let t=hitAt(e);t>=0?t!==L&&activate(t):L>=0&&deactivate()},onClick=e=>{if(!c.onClick)return;let t=hitAt(e);t>=0&&c.onClick(g[t].slice,t)},onKeyDown=e=>{let t=g.length;if(t===0)return;let n={ArrowDown:1,ArrowLeft:-1,ArrowRight:1,ArrowUp:-1};e.key in n?(e.preventDefault(),activate(L<0?n[e.key]>0?0:t-1:(L+n[e.key]+t)%t)):e.key===`Home`||e.key===`End`?(e.preventDefault(),activate(e.key===`Home`?0:t-1)):(e.key===`Enter`||e.key===` `)&&L>=0&&c.onClick?(e.preventDefault(),c.onClick(g[L].slice,L)):e.key===`Escape`&&deactivate()};return{onClick,onKeyDown,onMouseLeave:deactivate,onMouseMove}},e=>{f=e}),{get disposalSignal(){return v.disposalSignal},dispose(){_!==null&&(cancelAnimationFrame(_),_=null),v.dispose()},get disposed(){return v.disposed},el:v.el,update(e){v.update(e)},[Symbol.dispose](){this.dispose()}}}catch(e){throw v?.dispose(),e}}function hitTestArc(e,t,n,r){for(let i=0;i<e.length;i++){let a=e[i],o=t-a.centerX,s=n-a.centerY,l=Math.sqrt(o*o+s*s);if(l<a.outerRadius&&l>=a.innerRadius){let e=Math.atan2(o,-s);if(r===`semi`){if(e>=a.startAngle-1e-9&&e<=a.endAngle+1e-9)return i}else{let t=e<0?e+c:e;if(t>=a.startAngle-1e-9&&t<=a.endAngle+1e-9)return i}}}return-1}exports.createPieChart=createPieChart;
|
|
2
2
|
//# sourceMappingURL=pie-chart.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-chart.cjs","names":[],"sources":["../../../src/charts/pie/pie-chart.ts"],"sourcesContent":["import { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, PieChartConfig, PieSliceConfig } from '../../types';\nimport { type Arc, arcCentroid, arcPath, computeArcs } from './pie-renderer';\n\nconst TWO_PI = 2 * Math.PI;\n\nconst SEMI_START = -Math.PI / 2; // -90° = 9-o'clock (left)\nconst SEMI_END = Math.PI / 2; // +90° = 3-o'clock (right) → true 180° half-circle\n\nfunction semiAngles(variant: PieChartConfig['variant']): { end: number; start: number } {\n return variant === 'semi' ? { end: SEMI_END, start: SEMI_START } : { end: TWO_PI, start: 0 };\n}\n\nexport function createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle<PieSliceConfig[]> {\n const variant = config.variant ?? 'pie';\n const padPixels = config.padPixels ?? (variant === 'pie' ? 0 : 8);\n const cornerRadius = config.cornerRadius ?? (variant === 'pie' ? 0 : 8);\n let data = config.data;\n\n // Pie SVG elements live directly on the SVG (not inside chartArea groups).\n // We create them once and reuse across renders.\n const bgCircle = createSvgElement('circle', { class: 'prism-pie-bg', 'pointer-events': 'none' });\n const pieGroup = createSvgElement('g', {\n class: 'prism-pie-slices',\n 'shape-rendering': 'geometricPrecision',\n });\n const labelGroup = createSvgElement('g', { class: 'prism-pie-labels', 'pointer-events': 'none' });\n\n // Current arcs shared between renderFn and event handlers via closure.\n let currentArcs: Arc[] = [];\n let activeRaf: number | null = null;\n\n function renderLabels(slices: PieSliceConfig[]): void {\n labelGroup.replaceChildren();\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n const slice = slices[i];\n\n if (!slice?.label) continue;\n\n const { x, y } = arcCentroid(arc);\n const text = createSvgElement('text', { class: 'prism-pie-label' });\n\n setAttributes(text, {\n 'dominant-baseline': 'middle',\n fill: 'var(--prism-pie-label-color, #fff)',\n 'font-family': 'var(--prism-font-family, system-ui)',\n 'font-size': 'var(--prism-pie-label-size, 12px)',\n 'text-anchor': 'middle',\n x,\n y,\n });\n\n text.textContent = slice.label;\n labelGroup.appendChild(text);\n }\n }\n\n let handle: ChartHandle<PieSliceConfig[]> | undefined;\n\n try {\n handle = createRadialScaffold(\n container,\n {\n a11y: config.a11y,\n legend: config.legend,\n tooltip: config.tooltip,\n },\n (ctx): ChartEventHandlers => {\n const { legend, svg, tooltip } = ctx;\n\n // Append pie groups to SVG on first render (idempotent).\n if (!svg.contains(bgCircle)) {\n svg.appendChild(bgCircle);\n svg.appendChild(pieGroup);\n svg.appendChild(labelGroup);\n }\n\n const { height: h, width: w } = ctx.dimensions;\n const isSemi = variant === 'semi';\n const cx = w / 2;\n const cy = isSemi ? h * 0.85 : h / 2;\n const padding = 8;\n const outer = isSemi ? Math.min(cx, cy) - padding : Math.min(w, h) / 2 - padding;\n const defaultInner = variant === 'pie' ? 0 : Math.round(outer * 0.55);\n const inner = config.innerRadius !== undefined ? config.innerRadius : defaultInner;\n const outerR = Math.max(inner + 1, outer);\n\n const slices = data;\n const { end, start } = semiAngles(variant);\n\n currentArcs = computeArcs(\n slices,\n cx,\n cy,\n outerR,\n inner,\n start,\n end,\n padPixels,\n cornerRadius,\n (i) => seriesColor(i),\n false,\n );\n\n setAttributes(bgCircle, { cx, cy, r: inner > 0 ? inner : 0 });\n bgCircle.setAttribute('style', 'fill:var(--prism-bg,#fff)');\n\n while (pieGroup.children.length > currentArcs.length) pieGroup.removeChild(pieGroup.lastChild!);\n\n labelGroup.replaceChildren();\n\n const motion = resolveMotion(config.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n let path = pieGroup.children[i] as SVGPathElement | undefined;\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-pie-slice' });\n pieGroup.appendChild(path);\n }\n\n path.setAttribute('fill', arc.color);\n path.setAttribute('stroke', 'none');\n path.style.cursor = config.onClick || config.onHover ? 'pointer' : '';\n }\n\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n if (dur > 0) {\n let rafStart: number | null = null;\n\n const frame = (ts: number) => {\n if (rafStart === null) rafStart = ts;\n\n const t = easing(Math.min(1, (ts - rafStart) / dur));\n const revealAngle = tweenNumber(start, end, t);\n\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (!el) continue;\n\n if (revealAngle <= a.startAngle) {\n setAttributes(el, { d: '' });\n } else {\n const visibleEnd = Math.min(a.endAngle, revealAngle);\n\n setAttributes(el, { d: arcPath({ ...a, endAngle: visibleEnd }) });\n }\n }\n\n if (t < 1) {\n activeRaf = requestAnimationFrame(frame);\n } else {\n activeRaf = null;\n renderLabels(slices);\n }\n };\n\n activeRaf = requestAnimationFrame(frame);\n } else {\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (el) setAttributes(el, { d: arcPath(a) });\n }\n\n renderLabels(slices);\n }\n\n legend?.update(currentArcs.map((arc) => ({ color: arc.color, name: arc.slice.label ?? '' })));\n tooltip?.hide();\n\n const onMouseMove = (e: MouseEvent): void => {\n const svgRect = svg.getBoundingClientRect();\n const mx = e.clientX - svgRect.left;\n const my = e.clientY - svgRect.top;\n const hit = hitTestArc(currentArcs, mx, my, variant);\n\n if (hit >= 0) {\n const arc = currentArcs[hit];\n\n config.onHover?.(arc.slice, hit);\n\n const { x, y } = arcCentroid(arc);\n const contR = container.getBoundingClientRect();\n\n tooltip?.show(\n x + (svgRect.left - contR.left),\n y + (svgRect.top - contR.top),\n { key: hit, value: arc.slice.value },\n { color: arc.color, data: [], name: arc.slice.label ?? '' },\n );\n } else {\n config.onHover?.(null, null);\n tooltip?.hide();\n }\n };\n\n const onMouseLeave = (): void => {\n config.onHover?.(null, null);\n tooltip?.hide();\n };\n\n const onClick = (e: MouseEvent): void => {\n if (!config.onClick) return;\n\n const svgRect = svg.getBoundingClientRect();\n const mx = e.clientX - svgRect.left;\n const my = e.clientY - svgRect.top;\n const hit = hitTestArc(currentArcs, mx, my, variant);\n\n if (hit >= 0) config.onClick(currentArcs[hit].slice, hit);\n };\n\n return { onClick, onMouseLeave, onMouseMove };\n },\n (next) => {\n data = next;\n },\n );\n\n return {\n get disposalSignal(): AbortSignal {\n return handle!.disposalSignal;\n },\n\n dispose() {\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n handle!.dispose();\n },\n\n get disposed(): boolean {\n return handle!.disposed;\n },\n\n el: handle!.el,\n\n update(next) {\n handle!.update(next);\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n } catch (error) {\n handle?.dispose();\n throw error;\n }\n}\n\nfunction hitTestArc(arcs: Arc[], mx: number, my: number, variant: PieChartConfig['variant']): number {\n for (let i = 0; i < arcs.length; i++) {\n const arc = arcs[i];\n const dx = mx - arc.centerX;\n const dy = my - arc.centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < arc.outerRadius && dist >= arc.innerRadius) {\n const rawAngle = Math.atan2(dx, -dy);\n\n if (variant === 'semi') {\n if (rawAngle >= arc.startAngle - 1e-9 && rawAngle <= arc.endAngle + 1e-9) return i;\n } else {\n const angle = rawAngle < 0 ? rawAngle + TWO_PI : rawAngle;\n\n if (angle >= arc.startAngle - 1e-9 && angle <= arc.endAngle + 1e-9) return i;\n }\n }\n }\n\n return -1;\n}\n"],"mappings":"8QAUA,IAAM,EAAS,EAAI,KAAK,GAElB,EAAa,CAAC,KAAK,GAAK,EACxB,EAAW,KAAK,GAAK,EAE3B,SAAS,WAAW,EAAoE,CACtF,OAAO,IAAY,OAAS,CAAE,IAAK,EAAU,MAAO,CAAW,EAAI,CAAE,IAAK,EAAQ,MAAO,CAAE,CAC7F,CAEA,SAAgB,eAAe,EAAwB,EAAuD,CAC5G,IAAM,EAAU,EAAO,SAAW,MAC5B,EAAY,EAAO,YAAc,IAAY,MAAQ,EAAI,GACzD,EAAe,EAAO,eAAiB,IAAY,MAAQ,EAAI,GACjE,EAAO,EAAO,KAIZ,EAAW,EAAA,iBAAiB,SAAU,CAAE,MAAO,eAAgB,iBAAkB,MAAO,CAAC,EACzF,EAAW,EAAA,iBAAiB,IAAK,CACrC,MAAO,mBACP,kBAAmB,oBACrB,CAAC,EACK,EAAa,EAAA,iBAAiB,IAAK,CAAE,MAAO,mBAAoB,iBAAkB,MAAO,CAAC,EAG5F,EAAqB,CAAC,EACtB,EAA2B,KAE/B,SAAS,aAAa,EAAgC,CACpD,EAAW,gBAAgB,EAE3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAM,EAAY,GAClB,EAAQ,EAAO,GAErB,GAAI,CAAC,GAAO,MAAO,SAEnB,GAAM,CAAE,IAAG,KAAM,EAAA,YAAY,CAAG,EAC1B,EAAO,EAAA,iBAAiB,OAAQ,CAAE,MAAO,iBAAkB,CAAC,EAElE,EAAA,cAAc,EAAM,CAClB,oBAAqB,SACrB,KAAM,qCACN,cAAe,sCACf,YAAa,oCACb,cAAe,SACf,IACA,GACF,CAAC,EAED,EAAK,YAAc,EAAM,MACzB,EAAW,YAAY,CAAI,CAC7B,CACF,CAEA,IAAI,EAEJ,GAAI,CA2KF,MA1KA,GAAS,EAAA,qBACP,EACA,CACE,KAAM,EAAO,KACb,OAAQ,EAAO,OACf,QAAS,EAAO,OAClB,EACC,GAA4B,CAC3B,GAAM,CAAE,SAAQ,MAAK,WAAY,EAG5B,EAAI,SAAS,CAAQ,IACxB,EAAI,YAAY,CAAQ,EACxB,EAAI,YAAY,CAAQ,EACxB,EAAI,YAAY,CAAU,GAG5B,GAAM,CAAE,OAAQ,EAAG,MAAO,GAAM,EAAI,WAC9B,EAAS,IAAY,OACrB,EAAK,EAAI,EACT,EAAK,EAAS,EAAI,IAAO,EAAI,EAE7B,EAAQ,EAAS,KAAK,IAAI,EAAI,CAAE,EAAI,EAAU,KAAK,IAAI,EAAG,CAAC,EAAI,EAAI,EACnE,EAAe,IAAY,MAAQ,EAAI,KAAK,MAAM,EAAQ,GAAI,EAC9D,EAAQ,EAAO,cAAgB,IAAA,GAAiC,EAArB,EAAO,YAClD,EAAS,KAAK,IAAI,EAAQ,EAAG,CAAK,EAElC,EAAS,EACT,CAAE,MAAK,SAAU,WAAW,CAAO,EAmBzC,IAjBA,EAAc,EAAA,YACZ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACC,GAAM,EAAA,YAAY,CAAC,EACpB,EACF,EAEA,EAAA,cAAc,EAAU,CAAE,KAAI,KAAI,EAAG,EAAQ,EAAI,EAAQ,CAAE,CAAC,EAC5D,EAAS,aAAa,QAAS,2BAA2B,EAEnD,EAAS,SAAS,OAAS,EAAY,QAAQ,EAAS,YAAY,EAAS,SAAU,EAE9F,EAAW,gBAAgB,EAE3B,IAAM,EAAS,EAAA,cAAc,EAAO,WAAY,CAAC,EAC3C,EAAM,EAAO,SACb,EAAS,EAAA,cAAc,EAAO,MAAM,EAE1C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAM,EAAY,GACpB,EAAO,EAAS,SAAS,GAExB,IACH,EAAO,EAAA,iBAAiB,OAAQ,CAAE,MAAO,iBAAkB,CAAC,EAC5D,EAAS,YAAY,CAAI,GAG3B,EAAK,aAAa,OAAQ,EAAI,KAAK,EACnC,EAAK,aAAa,SAAU,MAAM,EAClC,EAAK,MAAM,OAAS,EAAO,SAAW,EAAO,QAAU,UAAY,EACrE,CAOA,GALI,IAAc,OAChB,qBAAqB,CAAS,EAC9B,EAAY,MAGV,EAAM,EAAG,CACX,IAAI,EAA0B,KAExB,MAAS,GAAe,CACxB,IAAa,OAAM,EAAW,GAElC,IAAM,EAAI,EAAO,KAAK,IAAI,GAAI,EAAK,GAAY,CAAG,CAAC,EAC7C,EAAc,EAAA,YAAY,EAAO,EAAK,CAAC,EAE7C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAI,EAAY,GAChB,EAAK,EAAS,SAAS,GAExB,KAEL,IAAI,GAAe,EAAE,WACnB,EAAA,cAAc,EAAI,CAAE,EAAG,EAAG,CAAC,MACtB,CACL,IAAM,EAAa,KAAK,IAAI,EAAE,SAAU,CAAW,EAEnD,EAAA,cAAc,EAAI,CAAE,EAAG,EAAA,QAAQ,CAAE,GAAG,EAAG,SAAU,CAAW,CAAC,CAAE,CAAC,CAClE,EACF,CAEI,EAAI,EACN,EAAY,sBAAsB,KAAK,GAEvC,EAAY,KACZ,aAAa,CAAM,EAEvB,EAEA,EAAY,sBAAsB,KAAK,CACzC,KAAO,CACL,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAI,EAAY,GAChB,EAAK,EAAS,SAAS,GAEzB,GAAI,EAAA,cAAc,EAAI,CAAE,EAAG,EAAA,QAAQ,CAAC,CAAE,CAAC,CAC7C,CAEA,aAAa,CAAM,CACrB,CAEA,GAAQ,OAAO,EAAY,IAAK,IAAS,CAAE,MAAO,EAAI,MAAO,KAAM,EAAI,MAAM,OAAS,EAAG,EAAE,CAAC,EAC5F,GAAS,KAAK,EAEd,IAAM,YAAe,GAAwB,CAC3C,IAAM,EAAU,EAAI,sBAAsB,EACpC,EAAK,EAAE,QAAU,EAAQ,KACzB,EAAK,EAAE,QAAU,EAAQ,IACzB,EAAM,WAAW,EAAa,EAAI,EAAI,CAAO,EAEnD,GAAI,GAAO,EAAG,CACZ,IAAM,EAAM,EAAY,GAExB,EAAO,UAAU,EAAI,MAAO,CAAG,EAE/B,GAAM,CAAE,IAAG,KAAM,EAAA,YAAY,CAAG,EAC1B,EAAQ,EAAU,sBAAsB,EAE9C,GAAS,KACP,GAAK,EAAQ,KAAO,EAAM,MAC1B,GAAK,EAAQ,IAAM,EAAM,KACzB,CAAE,IAAK,EAAK,MAAO,EAAI,MAAM,KAAM,EACnC,CAAE,MAAO,EAAI,MAAO,KAAM,CAAC,EAAG,KAAM,EAAI,MAAM,OAAS,EAAG,CAC5D,CACF,MACE,EAAO,UAAU,KAAM,IAAI,EAC3B,GAAS,KAAK,CAElB,EAEM,iBAA2B,CAC/B,EAAO,UAAU,KAAM,IAAI,EAC3B,GAAS,KAAK,CAChB,EAEM,QAAW,GAAwB,CACvC,GAAI,CAAC,EAAO,QAAS,OAErB,IAAM,EAAU,EAAI,sBAAsB,EACpC,EAAK,EAAE,QAAU,EAAQ,KACzB,EAAK,EAAE,QAAU,EAAQ,IACzB,EAAM,WAAW,EAAa,EAAI,EAAI,CAAO,EAE/C,GAAO,GAAG,EAAO,QAAQ,EAAY,EAAI,CAAC,MAAO,CAAG,CAC1D,EAEA,MAAO,CAAE,QAAS,aAAc,WAAY,CAC9C,EACC,GAAS,CACR,EAAO,CACT,CACF,EAEO,CACL,IAAI,gBAA8B,CAChC,OAAO,EAAQ,cACjB,EAEA,SAAU,CACJ,IAAc,OAChB,qBAAqB,CAAS,EAC9B,EAAY,MAGd,EAAQ,QAAQ,CAClB,EAEA,IAAI,UAAoB,CACtB,OAAO,EAAQ,QACjB,EAEA,GAAI,EAAQ,GAEZ,OAAO,EAAM,CACX,EAAQ,OAAO,CAAI,CACrB,EAEA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF,OAAS,EAAO,CAEd,MADA,GAAQ,QAAQ,EACV,CACR,CACF,CAEA,SAAS,WAAW,EAAa,EAAY,EAAY,EAA4C,CACnG,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GACX,EAAK,EAAK,EAAI,QACd,EAAK,EAAK,EAAI,QACd,EAAO,KAAK,KAAK,EAAK,EAAK,EAAK,CAAE,EAExC,GAAI,EAAO,EAAI,aAAe,GAAQ,EAAI,YAAa,CACrD,IAAM,EAAW,KAAK,MAAM,EAAI,CAAC,CAAE,EAEnC,GAAI,IAAY,OACV,IAAA,GAAY,EAAI,WAAa,MAAQ,GAAY,EAAI,SAAW,KAAM,OAAO,CAAA,KAC5E,CACL,IAAM,EAAQ,EAAW,EAAI,EAAW,EAAS,EAEjD,GAAI,GAAS,EAAI,WAAa,MAAQ,GAAS,EAAI,SAAW,KAAM,OAAO,CAC7E,CACF,CACF,CAEA,MAAO,EACT"}
|
|
1
|
+
{"version":3,"file":"pie-chart.cjs","names":[],"sources":["../../../src/charts/pie/pie-chart.ts"],"sourcesContent":["import { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { estimateTextWidth } from '../../svg/text';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, PieChartConfig, PieSliceConfig } from '../../types';\nimport { type Arc, arcCentroid, arcPath, computeArcs } from './pie-renderer';\n\nconst TWO_PI = 2 * Math.PI;\n/** Default `--prism-pie-label-size` in px, used to decide whether a label fits its slice. */\nconst LABEL_FONT_SIZE = 12;\n\n/** A label fits when its slice is wide enough along the centroid arc and thick enough radially. */\nfunction labelFits(arc: Arc, label: string): boolean {\n const thickness = arc.outerRadius - arc.innerRadius;\n const midRadius = (arc.outerRadius + arc.innerRadius) / 2;\n const arcLength = (arc.endAngle - arc.startAngle - 2 * arc.padAngle) * midRadius;\n\n return thickness >= LABEL_FONT_SIZE * 1.4 && arcLength >= estimateTextWidth(label, LABEL_FONT_SIZE) + 8;\n}\n\nconst SEMI_START = -Math.PI / 2; // -90° = 9-o'clock (left)\nconst SEMI_END = Math.PI / 2; // +90° = 3-o'clock (right) → true 180° half-circle\n\nfunction semiAngles(variant: PieChartConfig['variant']): { end: number; start: number } {\n return variant === 'semi' ? { end: SEMI_END, start: SEMI_START } : { end: TWO_PI, start: 0 };\n}\n\nexport function createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle<PieSliceConfig[]> {\n const variant = config.variant ?? 'pie';\n const padPixels = config.padPixels ?? (variant === 'pie' ? 0 : 8);\n const cornerRadius = config.cornerRadius ?? (variant === 'pie' ? 0 : 8);\n let data = config.data;\n\n // Pie SVG elements live directly on the SVG (not inside chartArea groups).\n // We create them once and reuse across renders.\n const bgCircle = createSvgElement('circle', { class: 'prism-pie-bg', 'pointer-events': 'none' });\n const pieGroup = createSvgElement('g', {\n class: 'prism-pie-slices',\n 'shape-rendering': 'geometricPrecision',\n });\n const labelGroup = createSvgElement('g', { class: 'prism-pie-labels', 'pointer-events': 'none' });\n\n // Current arcs shared between renderFn and event handlers via closure.\n let currentArcs: Arc[] = [];\n let activeRaf: number | null = null;\n\n function renderLabels(slices: PieSliceConfig[]): void {\n labelGroup.replaceChildren();\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n const slice = slices[i];\n\n if (!slice?.label || !labelFits(arc, slice.label)) continue;\n\n const { x, y } = arcCentroid(arc);\n const text = createSvgElement('text', { class: 'prism-pie-label' });\n\n setAttributes(text, {\n 'dominant-baseline': 'middle',\n fill: 'var(--prism-pie-label-color, #fff)',\n 'font-family': 'var(--prism-font-family, system-ui)',\n 'font-size': 'var(--prism-pie-label-size, 12px)',\n 'text-anchor': 'middle',\n x,\n y,\n });\n\n text.textContent = slice.label;\n labelGroup.appendChild(text);\n }\n }\n\n let handle: ChartHandle<PieSliceConfig[]> | undefined;\n\n try {\n handle = createRadialScaffold(\n container,\n {\n a11y: config.a11y,\n legend: config.legend,\n tooltip: config.tooltip,\n },\n (ctx): ChartEventHandlers => {\n const { legend, svg, tooltip } = ctx;\n\n // Append pie groups to SVG on first render (idempotent).\n if (!svg.contains(bgCircle)) {\n svg.appendChild(bgCircle);\n svg.appendChild(pieGroup);\n svg.appendChild(labelGroup);\n }\n\n const { height: h, width: w } = ctx.dimensions;\n const isSemi = variant === 'semi';\n const cx = w / 2;\n const cy = isSemi ? h * 0.85 : h / 2;\n const padding = 8;\n const outer = isSemi ? Math.min(cx, cy) - padding : Math.min(w, h) / 2 - padding;\n const defaultInner = variant === 'pie' ? 0 : Math.round(outer * 0.55);\n const inner = config.innerRadius !== undefined ? config.innerRadius : defaultInner;\n const outerR = Math.max(inner + 1, outer);\n\n const slices = data;\n const { end, start } = semiAngles(variant);\n\n currentArcs = computeArcs(\n slices,\n cx,\n cy,\n outerR,\n inner,\n start,\n end,\n padPixels,\n cornerRadius,\n (i) => seriesColor(i),\n false,\n );\n\n setAttributes(bgCircle, { cx, cy, r: inner > 0 ? inner : 0 });\n bgCircle.setAttribute('style', 'fill:var(--prism-bg,#fff)');\n\n while (pieGroup.children.length > currentArcs.length) pieGroup.removeChild(pieGroup.lastChild!);\n\n labelGroup.replaceChildren();\n\n const motion = resolveMotion(config.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n let path = pieGroup.children[i] as SVGPathElement | undefined;\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-pie-slice' });\n pieGroup.appendChild(path);\n }\n\n path.setAttribute('fill', arc.color);\n path.setAttribute('stroke', 'none');\n path.style.cursor = config.onClick || config.onHover ? 'pointer' : '';\n }\n\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n if (dur > 0) {\n let rafStart: number | null = null;\n\n const frame = (ts: number) => {\n if (rafStart === null) rafStart = ts;\n\n const t = easing(Math.min(1, (ts - rafStart) / dur));\n const revealAngle = tweenNumber(start, end, t);\n\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (!el) continue;\n\n if (revealAngle <= a.startAngle) {\n setAttributes(el, { d: '' });\n } else {\n const visibleEnd = Math.min(a.endAngle, revealAngle);\n\n setAttributes(el, { d: arcPath({ ...a, endAngle: visibleEnd }) });\n }\n }\n\n if (t < 1) {\n activeRaf = requestAnimationFrame(frame);\n } else {\n activeRaf = null;\n renderLabels(slices);\n }\n };\n\n activeRaf = requestAnimationFrame(frame);\n } else {\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (el) setAttributes(el, { d: arcPath(a) });\n }\n\n renderLabels(slices);\n }\n\n legend?.update(currentArcs.map((arc) => ({ color: arc.color, name: arc.slice.label ?? '' })));\n tooltip?.hide();\n\n const total = currentArcs.reduce((sum, arc) => sum + Math.max(0, arc.slice.value), 0);\n let activeIndex = -1;\n\n const describe = (arc: Arc): string => {\n const percent = total > 0 ? Math.round((Math.max(0, arc.slice.value) / total) * 1000) / 10 : 0;\n\n return `${arc.slice.label ?? `Slice ${arc.index + 1}`}: ${arc.slice.value} (${percent}%)`;\n };\n\n const setActive = (index: number): void => {\n activeIndex = index;\n pieGroup.classList.toggle('prism-pie-focused', index >= 0);\n for (const [i, el] of [...pieGroup.children].entries())\n el.classList.toggle('prism-pie-slice--active', i === index);\n };\n\n const activate = (index: number): void => {\n const arc = currentArcs[index];\n\n if (!arc) return;\n\n setActive(index);\n config.onHover?.(arc.slice, index);\n\n const text = describe(arc);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const { x, y } = arcCentroid(arc);\n const svgRect = svg.getBoundingClientRect();\n const contR = container.getBoundingClientRect();\n\n tooltip.show(\n x + (svgRect.left - contR.left),\n y + (svgRect.top - contR.top),\n { key: index, value: arc.slice.value },\n { color: arc.color, data: [], name: arc.slice.label ?? '' },\n text,\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null, null);\n };\n\n const hitAt = (e: MouseEvent): number => {\n const svgRect = svg.getBoundingClientRect();\n\n return hitTestArc(currentArcs, e.clientX - svgRect.left, e.clientY - svgRect.top, variant);\n };\n\n const onMouseMove = (e: MouseEvent): void => {\n const hit = hitAt(e);\n\n if (hit >= 0) {\n if (hit !== activeIndex) activate(hit);\n } else if (activeIndex >= 0) {\n deactivate();\n }\n };\n\n const onClick = (e: MouseEvent): void => {\n if (!config.onClick) return;\n\n const hit = hitAt(e);\n\n if (hit >= 0) config.onClick(currentArcs[hit].slice, hit);\n };\n\n const onKeyDown = (e: KeyboardEvent): void => {\n const count = currentArcs.length;\n\n if (count === 0) return;\n\n const step: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\n if (e.key in step) {\n e.preventDefault();\n activate(activeIndex < 0 ? (step[e.key] > 0 ? 0 : count - 1) : (activeIndex + step[e.key] + count) % count);\n } else if (e.key === 'Home' || e.key === 'End') {\n e.preventDefault();\n activate(e.key === 'Home' ? 0 : count - 1);\n } else if ((e.key === 'Enter' || e.key === ' ') && activeIndex >= 0 && config.onClick) {\n e.preventDefault();\n config.onClick(currentArcs[activeIndex].slice, activeIndex);\n } else if (e.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (next) => {\n data = next;\n },\n );\n\n return {\n get disposalSignal(): AbortSignal {\n return handle!.disposalSignal;\n },\n\n dispose() {\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n handle!.dispose();\n },\n\n get disposed(): boolean {\n return handle!.disposed;\n },\n\n el: handle!.el,\n\n update(next) {\n handle!.update(next);\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n } catch (error) {\n handle?.dispose();\n throw error;\n }\n}\n\nfunction hitTestArc(arcs: Arc[], mx: number, my: number, variant: PieChartConfig['variant']): number {\n for (let i = 0; i < arcs.length; i++) {\n const arc = arcs[i];\n const dx = mx - arc.centerX;\n const dy = my - arc.centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < arc.outerRadius && dist >= arc.innerRadius) {\n const rawAngle = Math.atan2(dx, -dy);\n\n if (variant === 'semi') {\n if (rawAngle >= arc.startAngle - 1e-9 && rawAngle <= arc.endAngle + 1e-9) return i;\n } else {\n const angle = rawAngle < 0 ? rawAngle + TWO_PI : rawAngle;\n\n if (angle >= arc.startAngle - 1e-9 && angle <= arc.endAngle + 1e-9) return i;\n }\n }\n }\n\n return -1;\n}\n"],"mappings":"8SAWA,IAAM,EAAS,EAAI,KAAK,GAElB,EAAkB,GAGxB,SAAS,UAAU,EAAU,EAAwB,CACnD,IAAM,EAAY,EAAI,YAAc,EAAI,YAClC,GAAa,EAAI,YAAc,EAAI,aAAe,EAClD,GAAa,EAAI,SAAW,EAAI,WAAa,EAAI,EAAI,UAAY,EAEvE,OAAO,GAAa,EAAkB,KAAO,GAAa,EAAA,kBAAkB,EAAO,CAAe,EAAI,CACxG,CAEA,IAAM,EAAa,CAAC,KAAK,GAAK,EACxB,EAAW,KAAK,GAAK,EAE3B,SAAS,WAAW,EAAoE,CACtF,OAAO,IAAY,OAAS,CAAE,IAAK,EAAU,MAAO,CAAW,EAAI,CAAE,IAAK,EAAQ,MAAO,CAAE,CAC7F,CAEA,SAAgB,eAAe,EAAwB,EAAuD,CAC5G,IAAM,EAAU,EAAO,SAAW,MAC5B,EAAY,EAAO,YAAc,IAAY,MAAQ,EAAI,GACzD,EAAe,EAAO,eAAiB,IAAY,MAAQ,EAAI,GACjE,EAAO,EAAO,KAIZ,EAAW,EAAA,iBAAiB,SAAU,CAAE,MAAO,eAAgB,iBAAkB,MAAO,CAAC,EACzF,EAAW,EAAA,iBAAiB,IAAK,CACrC,MAAO,mBACP,kBAAmB,oBACrB,CAAC,EACK,EAAa,EAAA,iBAAiB,IAAK,CAAE,MAAO,mBAAoB,iBAAkB,MAAO,CAAC,EAG5F,EAAqB,CAAC,EACtB,EAA2B,KAE/B,SAAS,aAAa,EAAgC,CACpD,EAAW,gBAAgB,EAE3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAM,EAAY,GAClB,EAAQ,EAAO,GAErB,GAAI,CAAC,GAAO,OAAS,CAAC,UAAU,EAAK,EAAM,KAAK,EAAG,SAEnD,GAAM,CAAE,IAAG,KAAM,EAAA,YAAY,CAAG,EAC1B,EAAO,EAAA,iBAAiB,OAAQ,CAAE,MAAO,iBAAkB,CAAC,EAElE,EAAA,cAAc,EAAM,CAClB,oBAAqB,SACrB,KAAM,qCACN,cAAe,sCACf,YAAa,oCACb,cAAe,SACf,IACA,GACF,CAAC,EAED,EAAK,YAAc,EAAM,MACzB,EAAW,YAAY,CAAI,CAC7B,CACF,CAEA,IAAI,EAEJ,GAAI,CAkOF,MAjOA,GAAS,EAAA,qBACP,EACA,CACE,KAAM,EAAO,KACb,OAAQ,EAAO,OACf,QAAS,EAAO,OAClB,EACC,GAA4B,CAC3B,GAAM,CAAE,SAAQ,MAAK,WAAY,EAG5B,EAAI,SAAS,CAAQ,IACxB,EAAI,YAAY,CAAQ,EACxB,EAAI,YAAY,CAAQ,EACxB,EAAI,YAAY,CAAU,GAG5B,GAAM,CAAE,OAAQ,EAAG,MAAO,GAAM,EAAI,WAC9B,EAAS,IAAY,OACrB,EAAK,EAAI,EACT,EAAK,EAAS,EAAI,IAAO,EAAI,EAE7B,EAAQ,EAAS,KAAK,IAAI,EAAI,CAAE,EAAI,EAAU,KAAK,IAAI,EAAG,CAAC,EAAI,EAAI,EACnE,EAAe,IAAY,MAAQ,EAAI,KAAK,MAAM,EAAQ,GAAI,EAC9D,EAAQ,EAAO,cAAgB,IAAA,GAAiC,EAArB,EAAO,YAClD,EAAS,KAAK,IAAI,EAAQ,EAAG,CAAK,EAElC,EAAS,EACT,CAAE,MAAK,SAAU,WAAW,CAAO,EAmBzC,IAjBA,EAAc,EAAA,YACZ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACC,GAAM,EAAA,YAAY,CAAC,EACpB,EACF,EAEA,EAAA,cAAc,EAAU,CAAE,KAAI,KAAI,EAAG,EAAQ,EAAI,EAAQ,CAAE,CAAC,EAC5D,EAAS,aAAa,QAAS,2BAA2B,EAEnD,EAAS,SAAS,OAAS,EAAY,QAAQ,EAAS,YAAY,EAAS,SAAU,EAE9F,EAAW,gBAAgB,EAE3B,IAAM,EAAS,EAAA,cAAc,EAAO,WAAY,CAAC,EAC3C,EAAM,EAAO,SACb,EAAS,EAAA,cAAc,EAAO,MAAM,EAE1C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAM,EAAY,GACpB,EAAO,EAAS,SAAS,GAExB,IACH,EAAO,EAAA,iBAAiB,OAAQ,CAAE,MAAO,iBAAkB,CAAC,EAC5D,EAAS,YAAY,CAAI,GAG3B,EAAK,aAAa,OAAQ,EAAI,KAAK,EACnC,EAAK,aAAa,SAAU,MAAM,EAClC,EAAK,MAAM,OAAS,EAAO,SAAW,EAAO,QAAU,UAAY,EACrE,CAOA,GALI,IAAc,OAChB,qBAAqB,CAAS,EAC9B,EAAY,MAGV,EAAM,EAAG,CACX,IAAI,EAA0B,KAExB,MAAS,GAAe,CACxB,IAAa,OAAM,EAAW,GAElC,IAAM,EAAI,EAAO,KAAK,IAAI,GAAI,EAAK,GAAY,CAAG,CAAC,EAC7C,EAAc,EAAA,YAAY,EAAO,EAAK,CAAC,EAE7C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAI,EAAY,GAChB,EAAK,EAAS,SAAS,GAExB,KAEL,IAAI,GAAe,EAAE,WACnB,EAAA,cAAc,EAAI,CAAE,EAAG,EAAG,CAAC,MACtB,CACL,IAAM,EAAa,KAAK,IAAI,EAAE,SAAU,CAAW,EAEnD,EAAA,cAAc,EAAI,CAAE,EAAG,EAAA,QAAQ,CAAE,GAAG,EAAG,SAAU,CAAW,CAAC,CAAE,CAAC,CAClE,EACF,CAEI,EAAI,EACN,EAAY,sBAAsB,KAAK,GAEvC,EAAY,KACZ,aAAa,CAAM,EAEvB,EAEA,EAAY,sBAAsB,KAAK,CACzC,KAAO,CACL,IAAK,IAAI,EAAI,EAAG,EAAI,EAAY,OAAQ,IAAK,CAC3C,IAAM,EAAI,EAAY,GAChB,EAAK,EAAS,SAAS,GAEzB,GAAI,EAAA,cAAc,EAAI,CAAE,EAAG,EAAA,QAAQ,CAAC,CAAE,CAAC,CAC7C,CAEA,aAAa,CAAM,CACrB,CAEA,GAAQ,OAAO,EAAY,IAAK,IAAS,CAAE,MAAO,EAAI,MAAO,KAAM,EAAI,MAAM,OAAS,EAAG,EAAE,CAAC,EAC5F,GAAS,KAAK,EAEd,IAAM,EAAQ,EAAY,QAAQ,EAAK,IAAQ,EAAM,KAAK,IAAI,EAAG,EAAI,MAAM,KAAK,EAAG,CAAC,EAChF,EAAc,GAEZ,SAAY,GAAqB,CACrC,IAAM,EAAU,EAAQ,EAAI,KAAK,MAAO,KAAK,IAAI,EAAG,EAAI,MAAM,KAAK,EAAI,EAAS,GAAI,EAAI,GAAK,EAE7F,MAAO,GAAG,EAAI,MAAM,OAAS,SAAS,EAAI,MAAQ,IAAI,IAAI,EAAI,MAAM,MAAM,IAAI,EAAQ,GACxF,EAEM,UAAa,GAAwB,CACzC,EAAc,EACd,EAAS,UAAU,OAAO,oBAAqB,GAAS,CAAC,EACzD,IAAK,GAAM,CAAC,EAAG,IAAO,CAAC,GAAG,EAAS,QAAQ,CAAC,CAAC,QAAQ,EACnD,EAAG,UAAU,OAAO,0BAA2B,IAAM,CAAK,CAC9D,EAEM,SAAY,GAAwB,CACxC,IAAM,EAAM,EAAY,GAExB,GAAI,CAAC,EAAK,OAEV,UAAU,CAAK,EACf,EAAO,UAAU,EAAI,MAAO,CAAK,EAEjC,IAAM,EAAO,SAAS,CAAG,EAEzB,GAAI,CAAC,EAAS,CACZ,EAAI,UAAU,SAAS,CAAI,EAE3B,MACF,CAEA,GAAM,CAAE,IAAG,KAAM,EAAA,YAAY,CAAG,EAC1B,EAAU,EAAI,sBAAsB,EACpC,EAAQ,EAAU,sBAAsB,EAE9C,EAAQ,KACN,GAAK,EAAQ,KAAO,EAAM,MAC1B,GAAK,EAAQ,IAAM,EAAM,KACzB,CAAE,IAAK,EAAO,MAAO,EAAI,MAAM,KAAM,EACrC,CAAE,MAAO,EAAI,MAAO,KAAM,CAAC,EAAG,KAAM,EAAI,MAAM,OAAS,EAAG,EAC1D,CACF,CACF,EAEM,eAAyB,CAC7B,UAAU,EAAE,EACZ,GAAS,KAAK,EACd,EAAI,UAAU,MAAM,EACpB,EAAO,UAAU,KAAM,IAAI,CAC7B,EAEM,MAAS,GAA0B,CACvC,IAAM,EAAU,EAAI,sBAAsB,EAE1C,OAAO,WAAW,EAAa,EAAE,QAAU,EAAQ,KAAM,EAAE,QAAU,EAAQ,IAAK,CAAO,CAC3F,EAEM,YAAe,GAAwB,CAC3C,IAAM,EAAM,MAAM,CAAC,EAEf,GAAO,EACL,IAAQ,GAAa,SAAS,CAAG,EAC5B,GAAe,GACxB,WAAW,CAEf,EAEM,QAAW,GAAwB,CACvC,GAAI,CAAC,EAAO,QAAS,OAErB,IAAM,EAAM,MAAM,CAAC,EAEf,GAAO,GAAG,EAAO,QAAQ,EAAY,EAAI,CAAC,MAAO,CAAG,CAC1D,EAEM,UAAa,GAA2B,CAC5C,IAAM,EAAQ,EAAY,OAE1B,GAAI,IAAU,EAAG,OAEjB,IAAM,EAA+B,CAAE,UAAW,EAAG,UAAW,GAAI,WAAY,EAAG,QAAS,EAAG,EAE3F,EAAE,OAAO,GACX,EAAE,eAAe,EACjB,SAAS,EAAc,EAAK,EAAK,EAAE,KAAO,EAAI,EAAI,EAAQ,GAAM,EAAc,EAAK,EAAE,KAAO,GAAS,CAAK,GACjG,EAAE,MAAQ,QAAU,EAAE,MAAQ,OACvC,EAAE,eAAe,EACjB,SAAS,EAAE,MAAQ,OAAS,EAAI,EAAQ,CAAC,IAC/B,EAAE,MAAQ,SAAW,EAAE,MAAQ,MAAQ,GAAe,GAAK,EAAO,SAC5E,EAAE,eAAe,EACjB,EAAO,QAAQ,EAAY,EAAY,CAAC,MAAO,CAAW,GACjD,EAAE,MAAQ,UACnB,WAAW,CAEf,EAEA,MAAO,CAAE,QAAS,UAAW,aAAc,WAAY,WAAY,CACrE,EACC,GAAS,CACR,EAAO,CACT,CACF,EAEO,CACL,IAAI,gBAA8B,CAChC,OAAO,EAAQ,cACjB,EAEA,SAAU,CACJ,IAAc,OAChB,qBAAqB,CAAS,EAC9B,EAAY,MAGd,EAAQ,QAAQ,CAClB,EAEA,IAAI,UAAoB,CACtB,OAAO,EAAQ,QACjB,EAEA,GAAI,EAAQ,GAEZ,OAAO,EAAM,CACX,EAAQ,OAAO,CAAI,CACrB,EAEA,CAAC,OAAO,UAAW,CACjB,KAAK,QAAQ,CACf,CACF,CACF,OAAS,EAAO,CAEd,MADA,GAAQ,QAAQ,EACV,CACR,CACF,CAEA,SAAS,WAAW,EAAa,EAAY,EAAY,EAA4C,CACnG,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GACX,EAAK,EAAK,EAAI,QACd,EAAK,EAAK,EAAI,QACd,EAAO,KAAK,KAAK,EAAK,EAAK,EAAK,CAAE,EAExC,GAAI,EAAO,EAAI,aAAe,GAAQ,EAAI,YAAa,CACrD,IAAM,EAAW,KAAK,MAAM,EAAI,CAAC,CAAE,EAEnC,GAAI,IAAY,OACV,IAAA,GAAY,EAAI,WAAa,MAAQ,GAAY,EAAI,SAAW,KAAM,OAAO,CAAA,KAC5E,CACL,IAAM,EAAQ,EAAW,EAAI,EAAW,EAAS,EAEjD,GAAI,GAAS,EAAI,WAAa,MAAQ,GAAS,EAAI,SAAW,KAAM,OAAO,CAC7E,CACF,CACF,CAEA,MAAO,EACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-chart.d.ts","sourceRoot":"","sources":["../../../src/charts/pie/pie-chart.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pie-chart.d.ts","sourceRoot":"","sources":["../../../src/charts/pie/pie-chart.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAuB/E,wBAAgB,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC,cAAc,EAAE,CAAC,CAkT5G"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{
|
|
1
|
+
import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{estimateTextWidth as n}from"../../svg/text.js";import{createRadialScaffold as r}from"../../core/chart-scaffold.js";import{seriesColor as i}from"../../theme/index.js";import{resolveEasing as a}from"../../animation/easing.js";import{resolveMotion as o}from"../../animation/motion.js";import{tweenNumber as s}from"../../animation/tween.js";import{arcCentroid as c,arcPath as l,computeArcs as u}from"./pie-renderer.js";var d=2*Math.PI,f=12;function labelFits(e,t){let r=e.outerRadius-e.innerRadius,i=(e.outerRadius+e.innerRadius)/2,a=(e.endAngle-e.startAngle-2*e.padAngle)*i;return r>=f*1.4&&a>=n(t,f)+8}var p=-Math.PI/2,m=Math.PI/2;function semiAngles(e){return e===`semi`?{end:m,start:p}:{end:d,start:0}}function createPieChart(n,d){let f=d.variant??`pie`,p=d.padPixels??(f===`pie`?0:8),m=d.cornerRadius??(f===`pie`?0:8),h=d.data,g=e(`circle`,{class:`prism-pie-bg`,"pointer-events":`none`}),_=e(`g`,{class:`prism-pie-slices`,"shape-rendering":`geometricPrecision`}),v=e(`g`,{class:`prism-pie-labels`,"pointer-events":`none`}),y=[],b=null;function renderLabels(n){v.replaceChildren();for(let r=0;r<y.length;r++){let i=y[r],a=n[r];if(!a?.label||!labelFits(i,a.label))continue;let{x:o,y:s}=c(i),l=e(`text`,{class:`prism-pie-label`});t(l,{"dominant-baseline":`middle`,fill:`var(--prism-pie-label-color, #fff)`,"font-family":`var(--prism-font-family, system-ui)`,"font-size":`var(--prism-pie-label-size, 12px)`,"text-anchor":`middle`,x:o,y:s}),l.textContent=a.label,v.appendChild(l)}}let x;try{return x=r(n,{a11y:d.a11y,legend:d.legend,tooltip:d.tooltip},r=>{let{legend:x,svg:S,tooltip:C}=r;S.contains(g)||(S.appendChild(g),S.appendChild(_),S.appendChild(v));let{height:w,width:T}=r.dimensions,E=f===`semi`,D=T/2,O=E?w*.85:w/2,k=E?Math.min(D,O)-8:Math.min(T,w)/2-8,A=f===`pie`?0:Math.round(k*.55),j=d.innerRadius===void 0?A:d.innerRadius,M=Math.max(j+1,k),N=h,{end:P,start:F}=semiAngles(f);for(y=u(N,D,O,M,j,F,P,p,m,e=>i(e),!1),t(g,{cx:D,cy:O,r:j>0?j:0}),g.setAttribute(`style`,`fill:var(--prism-bg,#fff)`);_.children.length>y.length;)_.removeChild(_.lastChild);v.replaceChildren();let I=o(d.transition,0),L=I.duration,R=a(I.easing);for(let t=0;t<y.length;t++){let n=y[t],r=_.children[t];r||(r=e(`path`,{class:`prism-pie-slice`}),_.appendChild(r)),r.setAttribute(`fill`,n.color),r.setAttribute(`stroke`,`none`),r.style.cursor=d.onClick||d.onHover?`pointer`:``}if(b!==null&&(cancelAnimationFrame(b),b=null),L>0){let e=null,frame=n=>{e===null&&(e=n);let r=R(Math.min(1,(n-e)/L)),i=s(F,P,r);for(let e=0;e<y.length;e++){let n=y[e],r=_.children[e];if(r){if(i<=n.startAngle)t(r,{d:``});else{let e=Math.min(n.endAngle,i);t(r,{d:l({...n,endAngle:e})})}}}r<1?b=requestAnimationFrame(frame):(b=null,renderLabels(N))};b=requestAnimationFrame(frame)}else{for(let e=0;e<y.length;e++){let n=y[e],r=_.children[e];r&&t(r,{d:l(n)})}renderLabels(N)}x?.update(y.map(e=>({color:e.color,name:e.slice.label??``}))),C?.hide();let z=y.reduce((e,t)=>e+Math.max(0,t.slice.value),0),B=-1,describe=e=>{let t=z>0?Math.round(Math.max(0,e.slice.value)/z*1e3)/10:0;return`${e.slice.label??`Slice ${e.index+1}`}: ${e.slice.value} (${t}%)`},setActive=e=>{B=e,_.classList.toggle(`prism-pie-focused`,e>=0);for(let[t,n]of[..._.children].entries())n.classList.toggle(`prism-pie-slice--active`,t===e)},activate=e=>{let t=y[e];if(!t)return;setActive(e),d.onHover?.(t.slice,e);let i=describe(t);if(!C){r.announcer.announce(i);return}let{x:a,y:o}=c(t),s=S.getBoundingClientRect(),l=n.getBoundingClientRect();C.show(a+(s.left-l.left),o+(s.top-l.top),{key:e,value:t.slice.value},{color:t.color,data:[],name:t.slice.label??``},i)},deactivate=()=>{setActive(-1),C?.hide(),r.announcer.clear(),d.onHover?.(null,null)},hitAt=e=>{let t=S.getBoundingClientRect();return hitTestArc(y,e.clientX-t.left,e.clientY-t.top,f)},onMouseMove=e=>{let t=hitAt(e);t>=0?t!==B&&activate(t):B>=0&&deactivate()},onClick=e=>{if(!d.onClick)return;let t=hitAt(e);t>=0&&d.onClick(y[t].slice,t)},onKeyDown=e=>{let t=y.length;if(t===0)return;let n={ArrowDown:1,ArrowLeft:-1,ArrowRight:1,ArrowUp:-1};e.key in n?(e.preventDefault(),activate(B<0?n[e.key]>0?0:t-1:(B+n[e.key]+t)%t)):e.key===`Home`||e.key===`End`?(e.preventDefault(),activate(e.key===`Home`?0:t-1)):(e.key===`Enter`||e.key===` `)&&B>=0&&d.onClick?(e.preventDefault(),d.onClick(y[B].slice,B)):e.key===`Escape`&&deactivate()};return{onClick,onKeyDown,onMouseLeave:deactivate,onMouseMove}},e=>{h=e}),{get disposalSignal(){return x.disposalSignal},dispose(){b!==null&&(cancelAnimationFrame(b),b=null),x.dispose()},get disposed(){return x.disposed},el:x.el,update(e){x.update(e)},[Symbol.dispose](){this.dispose()}}}catch(e){throw x?.dispose(),e}}function hitTestArc(e,t,n,r){for(let i=0;i<e.length;i++){let a=e[i],o=t-a.centerX,s=n-a.centerY,c=Math.sqrt(o*o+s*s);if(c<a.outerRadius&&c>=a.innerRadius){let e=Math.atan2(o,-s);if(r===`semi`){if(e>=a.startAngle-1e-9&&e<=a.endAngle+1e-9)return i}else{let t=e<0?e+d:e;if(t>=a.startAngle-1e-9&&t<=a.endAngle+1e-9)return i}}}return-1}export{createPieChart};
|
|
2
2
|
//# sourceMappingURL=pie-chart.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-chart.js","names":[],"sources":["../../../src/charts/pie/pie-chart.ts"],"sourcesContent":["import { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, PieChartConfig, PieSliceConfig } from '../../types';\nimport { type Arc, arcCentroid, arcPath, computeArcs } from './pie-renderer';\n\nconst TWO_PI = 2 * Math.PI;\n\nconst SEMI_START = -Math.PI / 2; // -90° = 9-o'clock (left)\nconst SEMI_END = Math.PI / 2; // +90° = 3-o'clock (right) → true 180° half-circle\n\nfunction semiAngles(variant: PieChartConfig['variant']): { end: number; start: number } {\n return variant === 'semi' ? { end: SEMI_END, start: SEMI_START } : { end: TWO_PI, start: 0 };\n}\n\nexport function createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle<PieSliceConfig[]> {\n const variant = config.variant ?? 'pie';\n const padPixels = config.padPixels ?? (variant === 'pie' ? 0 : 8);\n const cornerRadius = config.cornerRadius ?? (variant === 'pie' ? 0 : 8);\n let data = config.data;\n\n // Pie SVG elements live directly on the SVG (not inside chartArea groups).\n // We create them once and reuse across renders.\n const bgCircle = createSvgElement('circle', { class: 'prism-pie-bg', 'pointer-events': 'none' });\n const pieGroup = createSvgElement('g', {\n class: 'prism-pie-slices',\n 'shape-rendering': 'geometricPrecision',\n });\n const labelGroup = createSvgElement('g', { class: 'prism-pie-labels', 'pointer-events': 'none' });\n\n // Current arcs shared between renderFn and event handlers via closure.\n let currentArcs: Arc[] = [];\n let activeRaf: number | null = null;\n\n function renderLabels(slices: PieSliceConfig[]): void {\n labelGroup.replaceChildren();\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n const slice = slices[i];\n\n if (!slice?.label) continue;\n\n const { x, y } = arcCentroid(arc);\n const text = createSvgElement('text', { class: 'prism-pie-label' });\n\n setAttributes(text, {\n 'dominant-baseline': 'middle',\n fill: 'var(--prism-pie-label-color, #fff)',\n 'font-family': 'var(--prism-font-family, system-ui)',\n 'font-size': 'var(--prism-pie-label-size, 12px)',\n 'text-anchor': 'middle',\n x,\n y,\n });\n\n text.textContent = slice.label;\n labelGroup.appendChild(text);\n }\n }\n\n let handle: ChartHandle<PieSliceConfig[]> | undefined;\n\n try {\n handle = createRadialScaffold(\n container,\n {\n a11y: config.a11y,\n legend: config.legend,\n tooltip: config.tooltip,\n },\n (ctx): ChartEventHandlers => {\n const { legend, svg, tooltip } = ctx;\n\n // Append pie groups to SVG on first render (idempotent).\n if (!svg.contains(bgCircle)) {\n svg.appendChild(bgCircle);\n svg.appendChild(pieGroup);\n svg.appendChild(labelGroup);\n }\n\n const { height: h, width: w } = ctx.dimensions;\n const isSemi = variant === 'semi';\n const cx = w / 2;\n const cy = isSemi ? h * 0.85 : h / 2;\n const padding = 8;\n const outer = isSemi ? Math.min(cx, cy) - padding : Math.min(w, h) / 2 - padding;\n const defaultInner = variant === 'pie' ? 0 : Math.round(outer * 0.55);\n const inner = config.innerRadius !== undefined ? config.innerRadius : defaultInner;\n const outerR = Math.max(inner + 1, outer);\n\n const slices = data;\n const { end, start } = semiAngles(variant);\n\n currentArcs = computeArcs(\n slices,\n cx,\n cy,\n outerR,\n inner,\n start,\n end,\n padPixels,\n cornerRadius,\n (i) => seriesColor(i),\n false,\n );\n\n setAttributes(bgCircle, { cx, cy, r: inner > 0 ? inner : 0 });\n bgCircle.setAttribute('style', 'fill:var(--prism-bg,#fff)');\n\n while (pieGroup.children.length > currentArcs.length) pieGroup.removeChild(pieGroup.lastChild!);\n\n labelGroup.replaceChildren();\n\n const motion = resolveMotion(config.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n let path = pieGroup.children[i] as SVGPathElement | undefined;\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-pie-slice' });\n pieGroup.appendChild(path);\n }\n\n path.setAttribute('fill', arc.color);\n path.setAttribute('stroke', 'none');\n path.style.cursor = config.onClick || config.onHover ? 'pointer' : '';\n }\n\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n if (dur > 0) {\n let rafStart: number | null = null;\n\n const frame = (ts: number) => {\n if (rafStart === null) rafStart = ts;\n\n const t = easing(Math.min(1, (ts - rafStart) / dur));\n const revealAngle = tweenNumber(start, end, t);\n\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (!el) continue;\n\n if (revealAngle <= a.startAngle) {\n setAttributes(el, { d: '' });\n } else {\n const visibleEnd = Math.min(a.endAngle, revealAngle);\n\n setAttributes(el, { d: arcPath({ ...a, endAngle: visibleEnd }) });\n }\n }\n\n if (t < 1) {\n activeRaf = requestAnimationFrame(frame);\n } else {\n activeRaf = null;\n renderLabels(slices);\n }\n };\n\n activeRaf = requestAnimationFrame(frame);\n } else {\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (el) setAttributes(el, { d: arcPath(a) });\n }\n\n renderLabels(slices);\n }\n\n legend?.update(currentArcs.map((arc) => ({ color: arc.color, name: arc.slice.label ?? '' })));\n tooltip?.hide();\n\n const onMouseMove = (e: MouseEvent): void => {\n const svgRect = svg.getBoundingClientRect();\n const mx = e.clientX - svgRect.left;\n const my = e.clientY - svgRect.top;\n const hit = hitTestArc(currentArcs, mx, my, variant);\n\n if (hit >= 0) {\n const arc = currentArcs[hit];\n\n config.onHover?.(arc.slice, hit);\n\n const { x, y } = arcCentroid(arc);\n const contR = container.getBoundingClientRect();\n\n tooltip?.show(\n x + (svgRect.left - contR.left),\n y + (svgRect.top - contR.top),\n { key: hit, value: arc.slice.value },\n { color: arc.color, data: [], name: arc.slice.label ?? '' },\n );\n } else {\n config.onHover?.(null, null);\n tooltip?.hide();\n }\n };\n\n const onMouseLeave = (): void => {\n config.onHover?.(null, null);\n tooltip?.hide();\n };\n\n const onClick = (e: MouseEvent): void => {\n if (!config.onClick) return;\n\n const svgRect = svg.getBoundingClientRect();\n const mx = e.clientX - svgRect.left;\n const my = e.clientY - svgRect.top;\n const hit = hitTestArc(currentArcs, mx, my, variant);\n\n if (hit >= 0) config.onClick(currentArcs[hit].slice, hit);\n };\n\n return { onClick, onMouseLeave, onMouseMove };\n },\n (next) => {\n data = next;\n },\n );\n\n return {\n get disposalSignal(): AbortSignal {\n return handle!.disposalSignal;\n },\n\n dispose() {\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n handle!.dispose();\n },\n\n get disposed(): boolean {\n return handle!.disposed;\n },\n\n el: handle!.el,\n\n update(next) {\n handle!.update(next);\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n } catch (error) {\n handle?.dispose();\n throw error;\n }\n}\n\nfunction hitTestArc(arcs: Arc[], mx: number, my: number, variant: PieChartConfig['variant']): number {\n for (let i = 0; i < arcs.length; i++) {\n const arc = arcs[i];\n const dx = mx - arc.centerX;\n const dy = my - arc.centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < arc.outerRadius && dist >= arc.innerRadius) {\n const rawAngle = Math.atan2(dx, -dy);\n\n if (variant === 'semi') {\n if (rawAngle >= arc.startAngle - 1e-9 && rawAngle <= arc.endAngle + 1e-9) return i;\n } else {\n const angle = rawAngle < 0 ? rawAngle + TWO_PI : rawAngle;\n\n if (angle >= arc.startAngle - 1e-9 && angle <= arc.endAngle + 1e-9) return i;\n }\n }\n }\n\n return -1;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pie-chart.js","names":[],"sources":["../../../src/charts/pie/pie-chart.ts"],"sourcesContent":["import { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { estimateTextWidth } from '../../svg/text';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, PieChartConfig, PieSliceConfig } from '../../types';\nimport { type Arc, arcCentroid, arcPath, computeArcs } from './pie-renderer';\n\nconst TWO_PI = 2 * Math.PI;\n/** Default `--prism-pie-label-size` in px, used to decide whether a label fits its slice. */\nconst LABEL_FONT_SIZE = 12;\n\n/** A label fits when its slice is wide enough along the centroid arc and thick enough radially. */\nfunction labelFits(arc: Arc, label: string): boolean {\n const thickness = arc.outerRadius - arc.innerRadius;\n const midRadius = (arc.outerRadius + arc.innerRadius) / 2;\n const arcLength = (arc.endAngle - arc.startAngle - 2 * arc.padAngle) * midRadius;\n\n return thickness >= LABEL_FONT_SIZE * 1.4 && arcLength >= estimateTextWidth(label, LABEL_FONT_SIZE) + 8;\n}\n\nconst SEMI_START = -Math.PI / 2; // -90° = 9-o'clock (left)\nconst SEMI_END = Math.PI / 2; // +90° = 3-o'clock (right) → true 180° half-circle\n\nfunction semiAngles(variant: PieChartConfig['variant']): { end: number; start: number } {\n return variant === 'semi' ? { end: SEMI_END, start: SEMI_START } : { end: TWO_PI, start: 0 };\n}\n\nexport function createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle<PieSliceConfig[]> {\n const variant = config.variant ?? 'pie';\n const padPixels = config.padPixels ?? (variant === 'pie' ? 0 : 8);\n const cornerRadius = config.cornerRadius ?? (variant === 'pie' ? 0 : 8);\n let data = config.data;\n\n // Pie SVG elements live directly on the SVG (not inside chartArea groups).\n // We create them once and reuse across renders.\n const bgCircle = createSvgElement('circle', { class: 'prism-pie-bg', 'pointer-events': 'none' });\n const pieGroup = createSvgElement('g', {\n class: 'prism-pie-slices',\n 'shape-rendering': 'geometricPrecision',\n });\n const labelGroup = createSvgElement('g', { class: 'prism-pie-labels', 'pointer-events': 'none' });\n\n // Current arcs shared between renderFn and event handlers via closure.\n let currentArcs: Arc[] = [];\n let activeRaf: number | null = null;\n\n function renderLabels(slices: PieSliceConfig[]): void {\n labelGroup.replaceChildren();\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n const slice = slices[i];\n\n if (!slice?.label || !labelFits(arc, slice.label)) continue;\n\n const { x, y } = arcCentroid(arc);\n const text = createSvgElement('text', { class: 'prism-pie-label' });\n\n setAttributes(text, {\n 'dominant-baseline': 'middle',\n fill: 'var(--prism-pie-label-color, #fff)',\n 'font-family': 'var(--prism-font-family, system-ui)',\n 'font-size': 'var(--prism-pie-label-size, 12px)',\n 'text-anchor': 'middle',\n x,\n y,\n });\n\n text.textContent = slice.label;\n labelGroup.appendChild(text);\n }\n }\n\n let handle: ChartHandle<PieSliceConfig[]> | undefined;\n\n try {\n handle = createRadialScaffold(\n container,\n {\n a11y: config.a11y,\n legend: config.legend,\n tooltip: config.tooltip,\n },\n (ctx): ChartEventHandlers => {\n const { legend, svg, tooltip } = ctx;\n\n // Append pie groups to SVG on first render (idempotent).\n if (!svg.contains(bgCircle)) {\n svg.appendChild(bgCircle);\n svg.appendChild(pieGroup);\n svg.appendChild(labelGroup);\n }\n\n const { height: h, width: w } = ctx.dimensions;\n const isSemi = variant === 'semi';\n const cx = w / 2;\n const cy = isSemi ? h * 0.85 : h / 2;\n const padding = 8;\n const outer = isSemi ? Math.min(cx, cy) - padding : Math.min(w, h) / 2 - padding;\n const defaultInner = variant === 'pie' ? 0 : Math.round(outer * 0.55);\n const inner = config.innerRadius !== undefined ? config.innerRadius : defaultInner;\n const outerR = Math.max(inner + 1, outer);\n\n const slices = data;\n const { end, start } = semiAngles(variant);\n\n currentArcs = computeArcs(\n slices,\n cx,\n cy,\n outerR,\n inner,\n start,\n end,\n padPixels,\n cornerRadius,\n (i) => seriesColor(i),\n false,\n );\n\n setAttributes(bgCircle, { cx, cy, r: inner > 0 ? inner : 0 });\n bgCircle.setAttribute('style', 'fill:var(--prism-bg,#fff)');\n\n while (pieGroup.children.length > currentArcs.length) pieGroup.removeChild(pieGroup.lastChild!);\n\n labelGroup.replaceChildren();\n\n const motion = resolveMotion(config.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n let path = pieGroup.children[i] as SVGPathElement | undefined;\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-pie-slice' });\n pieGroup.appendChild(path);\n }\n\n path.setAttribute('fill', arc.color);\n path.setAttribute('stroke', 'none');\n path.style.cursor = config.onClick || config.onHover ? 'pointer' : '';\n }\n\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n if (dur > 0) {\n let rafStart: number | null = null;\n\n const frame = (ts: number) => {\n if (rafStart === null) rafStart = ts;\n\n const t = easing(Math.min(1, (ts - rafStart) / dur));\n const revealAngle = tweenNumber(start, end, t);\n\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (!el) continue;\n\n if (revealAngle <= a.startAngle) {\n setAttributes(el, { d: '' });\n } else {\n const visibleEnd = Math.min(a.endAngle, revealAngle);\n\n setAttributes(el, { d: arcPath({ ...a, endAngle: visibleEnd }) });\n }\n }\n\n if (t < 1) {\n activeRaf = requestAnimationFrame(frame);\n } else {\n activeRaf = null;\n renderLabels(slices);\n }\n };\n\n activeRaf = requestAnimationFrame(frame);\n } else {\n for (let j = 0; j < currentArcs.length; j++) {\n const a = currentArcs[j];\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (el) setAttributes(el, { d: arcPath(a) });\n }\n\n renderLabels(slices);\n }\n\n legend?.update(currentArcs.map((arc) => ({ color: arc.color, name: arc.slice.label ?? '' })));\n tooltip?.hide();\n\n const total = currentArcs.reduce((sum, arc) => sum + Math.max(0, arc.slice.value), 0);\n let activeIndex = -1;\n\n const describe = (arc: Arc): string => {\n const percent = total > 0 ? Math.round((Math.max(0, arc.slice.value) / total) * 1000) / 10 : 0;\n\n return `${arc.slice.label ?? `Slice ${arc.index + 1}`}: ${arc.slice.value} (${percent}%)`;\n };\n\n const setActive = (index: number): void => {\n activeIndex = index;\n pieGroup.classList.toggle('prism-pie-focused', index >= 0);\n for (const [i, el] of [...pieGroup.children].entries())\n el.classList.toggle('prism-pie-slice--active', i === index);\n };\n\n const activate = (index: number): void => {\n const arc = currentArcs[index];\n\n if (!arc) return;\n\n setActive(index);\n config.onHover?.(arc.slice, index);\n\n const text = describe(arc);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const { x, y } = arcCentroid(arc);\n const svgRect = svg.getBoundingClientRect();\n const contR = container.getBoundingClientRect();\n\n tooltip.show(\n x + (svgRect.left - contR.left),\n y + (svgRect.top - contR.top),\n { key: index, value: arc.slice.value },\n { color: arc.color, data: [], name: arc.slice.label ?? '' },\n text,\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null, null);\n };\n\n const hitAt = (e: MouseEvent): number => {\n const svgRect = svg.getBoundingClientRect();\n\n return hitTestArc(currentArcs, e.clientX - svgRect.left, e.clientY - svgRect.top, variant);\n };\n\n const onMouseMove = (e: MouseEvent): void => {\n const hit = hitAt(e);\n\n if (hit >= 0) {\n if (hit !== activeIndex) activate(hit);\n } else if (activeIndex >= 0) {\n deactivate();\n }\n };\n\n const onClick = (e: MouseEvent): void => {\n if (!config.onClick) return;\n\n const hit = hitAt(e);\n\n if (hit >= 0) config.onClick(currentArcs[hit].slice, hit);\n };\n\n const onKeyDown = (e: KeyboardEvent): void => {\n const count = currentArcs.length;\n\n if (count === 0) return;\n\n const step: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\n if (e.key in step) {\n e.preventDefault();\n activate(activeIndex < 0 ? (step[e.key] > 0 ? 0 : count - 1) : (activeIndex + step[e.key] + count) % count);\n } else if (e.key === 'Home' || e.key === 'End') {\n e.preventDefault();\n activate(e.key === 'Home' ? 0 : count - 1);\n } else if ((e.key === 'Enter' || e.key === ' ') && activeIndex >= 0 && config.onClick) {\n e.preventDefault();\n config.onClick(currentArcs[activeIndex].slice, activeIndex);\n } else if (e.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (next) => {\n data = next;\n },\n );\n\n return {\n get disposalSignal(): AbortSignal {\n return handle!.disposalSignal;\n },\n\n dispose() {\n if (activeRaf !== null) {\n cancelAnimationFrame(activeRaf);\n activeRaf = null;\n }\n\n handle!.dispose();\n },\n\n get disposed(): boolean {\n return handle!.disposed;\n },\n\n el: handle!.el,\n\n update(next) {\n handle!.update(next);\n },\n\n [Symbol.dispose]() {\n this.dispose();\n },\n };\n } catch (error) {\n handle?.dispose();\n throw error;\n }\n}\n\nfunction hitTestArc(arcs: Arc[], mx: number, my: number, variant: PieChartConfig['variant']): number {\n for (let i = 0; i < arcs.length; i++) {\n const arc = arcs[i];\n const dx = mx - arc.centerX;\n const dy = my - arc.centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < arc.outerRadius && dist >= arc.innerRadius) {\n const rawAngle = Math.atan2(dx, -dy);\n\n if (variant === 'semi') {\n if (rawAngle >= arc.startAngle - 1e-9 && rawAngle <= arc.endAngle + 1e-9) return i;\n } else {\n const angle = rawAngle < 0 ? rawAngle + TWO_PI : rawAngle;\n\n if (angle >= arc.startAngle - 1e-9 && angle <= arc.endAngle + 1e-9) return i;\n }\n }\n }\n\n return -1;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function computeArcs(e,t,n,r,i,a,o,s,c,l,u=!1){let d=e.reduce((e,t)=>e+Math.max(0,t.value),0);if(d===0)return[];let f=o-a,
|
|
1
|
+
const e=require("../../core/polar.cjs");function computeArcs(e,t,n,r,i,a,o,s,c,l,u=!1){let d=e.reduce((e,t)=>e+Math.max(0,t.value),0);if(d===0)return[];let f=o-a,p=r>0?Math.asin(Math.min(1,s/2/r)):0,m=a,h=e.length;return e.map((e,a)=>{let o=Math.max(0,e.value)/d*f,s=m,g=m+o;m+=o;let _=Math.min(p,o/2);return{capEnd:u&&a===h-1,capStart:u&&a===0,centerX:t,centerY:n,color:e.color??l(a),cornerRadius:c,endAngle:g,index:a,innerRadius:i,outerRadius:r,padAngle:_,slice:e,startAngle:s}})}function arcPath(t){let{capEnd:n,capStart:r,centerX:i,centerY:a,cornerRadius:o,endAngle:s,innerRadius:c,outerRadius:l,padAngle:u,startAngle:d}=t,f=s-d;if(f<=0)return``;if(f>=2*Math.PI-1e-6){let t=d+Math.PI;return c<=0?`M${e.polarPoint(i,a,l,d)}A${l},${l},0,1,1,${e.polarPoint(i,a,l,t)}A${l},${l},0,1,1,${e.polarPoint(i,a,l,d)}Z`:[`M${e.polarPoint(i,a,l,d)}`,`A${l},${l},0,1,1,${e.polarPoint(i,a,l,t)}`,`A${l},${l},0,1,1,${e.polarPoint(i,a,l,d)}`,`M${e.polarPoint(i,a,c,d)}`,`A${c},${c},0,1,0,${e.polarPoint(i,a,c,t)}`,`A${c},${c},0,1,0,${e.polarPoint(i,a,c,d)}`,`Z`].join(``)}let p=r?d:d+u,m=n?s:s-u;if(m<=p)return``;let h=m-p;if(o<=0){let t=+(h>Math.PI);return c<=0?`M${i},${a}L${e.polarPoint(i,a,l,p)}A${l},${l},0,${t},1,${e.polarPoint(i,a,l,m)}Z`:[`M${e.polarPoint(i,a,l,p)}`,`A${l},${l},0,${t},1,${e.polarPoint(i,a,l,m)}`,`L${e.polarPoint(i,a,c,m)}`,`A${c},${c},0,${t},0,${e.polarPoint(i,a,c,p)}`,`Z`].join(``)}let g=Math.min(o/l,h/2),_=Math.min(o/c,h/2),v=Math.min(o,(l-c)/2),y=(l-c)/2,b=p+(r?0:g),x=m-(n?0:g),S=p+(r?0:_),C=m-(n?0:_),w=+(x-b>Math.PI),T=+(C-S>Math.PI),E=e.polarX(i,l,p),D=e.polarY(a,l,p),O=e.polarX(i,l,m),k=e.polarY(a,l,m),A=e.polarX(i,c,p),j=e.polarY(a,c,p),M=e.polarX(i,c,m),N=e.polarY(a,c,m),P=v/(l-c),F=`${E+(A-E)*P},${D+(j-D)*P}`,I=`${O+(M-O)*P},${k+(N-k)*P}`,L=`${A+(E-A)*P},${j+(D-j)*P}`,R=`${M+(O-M)*P},${N+(k-N)*P}`,z=[];return r?z.push(`M${e.polarPoint(i,a,l,p)}`):(z.push(`M${F}`),z.push(`Q${E},${D},${e.polarPoint(i,a,l,b)}`)),z.push(`A${l},${l},0,${w},1,${e.polarPoint(i,a,l,x)}`),n?z.push(`A${y},${y},0,0,1,${e.polarPoint(i,a,c,m)}`):(z.push(`Q${O},${k},${I}`),z.push(`L${R}`),z.push(`Q${M},${N},${e.polarPoint(i,a,c,C)}`)),z.push(`A${c},${c},0,${T},0,${e.polarPoint(i,a,c,S)}`),r?z.push(`A${y},${y},0,0,0,${e.polarPoint(i,a,l,p)}`):z.push(`Q${A},${j},${L}`),z.push(`Z`),z.join(``)}function arcCentroid(e){let t=(e.startAngle+e.endAngle)/2,n=(e.outerRadius+e.innerRadius)/2;return{x:e.centerX+n*Math.sin(t),y:e.centerY-n*Math.cos(t)}}exports.arcCentroid=arcCentroid,exports.arcPath=arcPath,exports.computeArcs=computeArcs;
|
|
2
2
|
//# sourceMappingURL=pie-renderer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-renderer.cjs","names":[],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\n// Polar to cartesian, returns x,y string for SVG path\nfunction p(cx: number, cy: number, r: number, a: number): string {\n return `${cx + r * Math.sin(a)},${cy - r * Math.cos(a)}`;\n}\n\n// Cartesian x component\nfunction px(cx: number, r: number, a: number): number {\n return cx + r * Math.sin(a);\n}\n\n// Cartesian y component\nfunction py(cy: number, r: number, a: number): number {\n return cy - r * Math.cos(a);\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pie-renderer.cjs","names":[],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import { polarPoint as p, polarX as px, polarY as py } from '../../core/polar';\nimport type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-renderer.d.ts","sourceRoot":"","sources":["../../../src/charts/pie/pie-renderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pie-renderer.d.ts","sourceRoot":"","sources":["../../../src/charts/pie/pie-renderer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,cAAc,EAAE,EACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EACpC,OAAO,UAAQ,GACd,GAAG,EAAE,CAqCP;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAmIxC;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAQ9D"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function computeArcs(e,t,n,r,i,a,o,s,c,l,u=!1){let d=e.reduce((e,t)=>e+Math.max(0,t.value),0);if(d===0)return[];let f=o-a,
|
|
1
|
+
import{polarPoint as e,polarX as t,polarY as n}from"../../core/polar.js";function computeArcs(e,t,n,r,i,a,o,s,c,l,u=!1){let d=e.reduce((e,t)=>e+Math.max(0,t.value),0);if(d===0)return[];let f=o-a,p=r>0?Math.asin(Math.min(1,s/2/r)):0,m=a,h=e.length;return e.map((e,a)=>{let o=Math.max(0,e.value)/d*f,s=m,g=m+o;m+=o;let _=Math.min(p,o/2);return{capEnd:u&&a===h-1,capStart:u&&a===0,centerX:t,centerY:n,color:e.color??l(a),cornerRadius:c,endAngle:g,index:a,innerRadius:i,outerRadius:r,padAngle:_,slice:e,startAngle:s}})}function arcPath(r){let{capEnd:i,capStart:a,centerX:o,centerY:s,cornerRadius:c,endAngle:l,innerRadius:u,outerRadius:d,padAngle:f,startAngle:p}=r,m=l-p;if(m<=0)return``;if(m>=2*Math.PI-1e-6){let t=p+Math.PI;return u<=0?`M${e(o,s,d,p)}A${d},${d},0,1,1,${e(o,s,d,t)}A${d},${d},0,1,1,${e(o,s,d,p)}Z`:[`M${e(o,s,d,p)}`,`A${d},${d},0,1,1,${e(o,s,d,t)}`,`A${d},${d},0,1,1,${e(o,s,d,p)}`,`M${e(o,s,u,p)}`,`A${u},${u},0,1,0,${e(o,s,u,t)}`,`A${u},${u},0,1,0,${e(o,s,u,p)}`,`Z`].join(``)}let h=a?p:p+f,g=i?l:l-f;if(g<=h)return``;let _=g-h;if(c<=0){let t=+(_>Math.PI);return u<=0?`M${o},${s}L${e(o,s,d,h)}A${d},${d},0,${t},1,${e(o,s,d,g)}Z`:[`M${e(o,s,d,h)}`,`A${d},${d},0,${t},1,${e(o,s,d,g)}`,`L${e(o,s,u,g)}`,`A${u},${u},0,${t},0,${e(o,s,u,h)}`,`Z`].join(``)}let v=Math.min(c/d,_/2),y=Math.min(c/u,_/2),b=Math.min(c,(d-u)/2),x=(d-u)/2,S=h+(a?0:v),C=g-(i?0:v),w=h+(a?0:y),T=g-(i?0:y),E=+(C-S>Math.PI),D=+(T-w>Math.PI),O=t(o,d,h),k=n(s,d,h),A=t(o,d,g),j=n(s,d,g),M=t(o,u,h),N=n(s,u,h),P=t(o,u,g),F=n(s,u,g),I=b/(d-u),L=`${O+(M-O)*I},${k+(N-k)*I}`,R=`${A+(P-A)*I},${j+(F-j)*I}`,z=`${M+(O-M)*I},${N+(k-N)*I}`,B=`${P+(A-P)*I},${F+(j-F)*I}`,V=[];return a?V.push(`M${e(o,s,d,h)}`):(V.push(`M${L}`),V.push(`Q${O},${k},${e(o,s,d,S)}`)),V.push(`A${d},${d},0,${E},1,${e(o,s,d,C)}`),i?V.push(`A${x},${x},0,0,1,${e(o,s,u,g)}`):(V.push(`Q${A},${j},${R}`),V.push(`L${B}`),V.push(`Q${P},${F},${e(o,s,u,T)}`)),V.push(`A${u},${u},0,${D},0,${e(o,s,u,w)}`),a?V.push(`A${x},${x},0,0,0,${e(o,s,d,h)}`):V.push(`Q${M},${N},${z}`),V.push(`Z`),V.join(``)}function arcCentroid(e){let t=(e.startAngle+e.endAngle)/2,n=(e.outerRadius+e.innerRadius)/2;return{x:e.centerX+n*Math.sin(t),y:e.centerY-n*Math.cos(t)}}export{arcCentroid,arcPath,computeArcs};
|
|
2
2
|
//# sourceMappingURL=pie-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-renderer.js","names":[],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\n// Polar to cartesian, returns x,y string for SVG path\nfunction p(cx: number, cy: number, r: number, a: number): string {\n return `${cx + r * Math.sin(a)},${cy - r * Math.cos(a)}`;\n}\n\n// Cartesian x component\nfunction px(cx: number, r: number, a: number): number {\n return cx + r * Math.sin(a);\n}\n\n// Cartesian y component\nfunction py(cy: number, r: number, a: number): number {\n return cy - r * Math.cos(a);\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pie-renderer.js","names":[],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import { polarPoint as p, polarX as px, polarY as py } from '../../core/polar';\nimport type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/charts/radar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../interaction/announcer.cjs"),n=require("../../interaction/tooltip.cjs"),r=require("../../core/chart-scaffold.cjs"),i=require("../../theme/index.cjs"),a=require("../../animation/easing.cjs"),o=require("../../animation/motion.cjs"),s=require("../../animation/tween.cjs"),c=require("../../core/ids.cjs"),l=require("../../core/polar.cjs"),u=require("./radar-geometry.cjs");var d=11,f=12,p=10,m={ArrowDown:1,ArrowLeft:-1,ArrowRight:1,ArrowUp:-1};function resolveGrid(e){return e===!1?null:{bands:!0,labels:!1,levels:4,shape:`polygon`,...typeof e==`object`?e:{}}}function createRadarChart(h,g){let{axes:_}=g,v=g.curve??`linear`,y=g.fill??`solid`,b=g.showPoints??!0,x=resolveGrid(g.grid),S=u.toRadians(g.startAngle??0),C=u.axisAngles(_.length,S),w=f+(g.showValues?p:0),T=c.uniqueId(`prism-radar`),E=g.series,D=e.createSvgElement(`g`,{class:`prism-radar`}),O=e.createSvgElement(`defs`),k=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-radar-grid`}),A=e.createSvgElement(`g`,{class:`prism-radar-series-group`}),j=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-radar-labels`});D.append(O,k,A,j);let M=[],N=null,P=-1,F={cx:0,cy:0,radius:0},datumAt=(e,t)=>e.data.find(e=>e.key===_[t].key),valuesAt=e=>E.map(t=>({datum:datumAt(t,e),series:t})),formatValue=(e,t)=>_[e].format?.(t)??String(t),describe=e=>t.describeValues(_[e].label,valuesAt(e),t=>formatValue(e,t));function draw(t){let{cx:n,cy:r,radius:i}=F;t.forEach((t,a)=>{let o=A.children[a];if(!o)return;let s=u.radarPoints(t,n,r,i,C);o.querySelector(`.prism-radar-area`)?.setAttribute(`d`,u.closedPath(s,v)),o.querySelectorAll(`.prism-radar-point`).forEach((t,n)=>{e.setAttributes(t,{cx:s[n].x,cy:s[n].y})}),o.querySelectorAll(`.prism-radar-value`).forEach((a,o)=>{let s=i*t[o]+p;e.setAttributes(a,{x:l.polarX(n,s,C[o]),y:l.polarY(r,s,C[o])})})})}function renderGrid(t){if(k.replaceChildren(),!x)return;let{cx:n,cy:r,radius:i}=F,a=Math.max(1,Math.round(x.levels)),o=Array.from({length:a},(e,t)=>u.ringPath(x.shape,n,r,i*(t+1)/a,C));if(x.bands)for(let t=a-1;t>=0;t-=2)k.appendChild(e.createSvgElement(`path`,{class:`prism-radar-band`,d:`${o[t]}${o[t-1]??``}`,"fill-rule":`evenodd`}));for(let t of o)k.appendChild(e.createSvgElement(`path`,{class:`prism-radar-ring`,d:t,fill:`none`}));C.forEach((t,a)=>{k.appendChild(e.createSvgElement(`line`,{class:`prism-radar-spoke`,"data-axis":a,x1:n,x2:l.polarX(n,i,t),y1:r,y2:l.polarY(r,i,t)}))});let[s,c]=t[0],d=t.every(([e,t])=>e===s&&t===c);if(!x.labels||!d)return;let f=C[0]+Math.PI/C.length;for(let t=1;t<=a;t++){let o=i*t/a,u=e.createSvgElement(`text`,{class:`prism-radar-level`,"dominant-baseline":`middle`,"text-anchor":`middle`,x:l.polarX(n,o,f),y:l.polarY(r,o,f)});u.textContent=formatValue(0,Math.round((s+(c-s)*t/a)*100)/100),k.appendChild(u)}}function renderLabels(){j.replaceChildren();let{cx:t,cy:n,radius:r}=F;_.forEach((i,a)=>{let{anchor:o,baseline:s}=u.labelPlacement(C[a]),c=e.createSvgElement(`text`,{class:`prism-radar-axis-label`,"dominant-baseline":s,"text-anchor":o,x:l.polarX(t,r+w,C[a]),y:l.polarY(n,r+w,C[a])});c.textContent=i.label,j.appendChild(c)})}function renderSeries(){let{cx:t,cy:n,radius:r}=F;for(O.replaceChildren();A.children.length>E.length;)A.lastChild?.remove();E.forEach((a,o)=>{let s=a.color??i.seriesColor(o),c=A.children[o];c||(c=e.createSvgElement(`g`,{class:`prism-radar-series`}),A.appendChild(c)),c.replaceChildren();let l=e.createSvgElement(`path`,{class:`prism-radar-area prism-radar-area--${y}`,stroke:s,"stroke-linejoin":`round`,"stroke-width":2});if(y===`gradient`){let i=`${T}-fill-${o}`,a=e.createSvgElement(`radialGradient`,{cx:t,cy:n,gradientUnits:`userSpaceOnUse`,id:i,r});for(let[t,n]of[[0,.08],[1,.55]])a.appendChild(e.createSvgElement(`stop`,{offset:t,"stop-color":s,"stop-opacity":n,style:`stop-color:${s}`}));O.appendChild(a),e.setAttributes(l,{fill:`url(#${i})`})}else e.setAttributes(l,{fill:y===`none`?`none`:s,"fill-opacity":.25});c.appendChild(l),b&&_.forEach((t,n)=>{let r=!Number.isFinite(datumAt(a,n)?.value);c.appendChild(e.createSvgElement(`circle`,{class:`prism-radar-point${r?` prism-radar-point--missing`:``}`,"data-axis":n,fill:r?`none`:s,r:3,stroke:s}))}),g.showValues&&_.forEach((t,n)=>{let r=datumAt(a,n),{anchor:i,baseline:o}=u.labelPlacement(C[n]),s=e.createSvgElement(`text`,{"aria-hidden":`true`,class:`prism-radar-value`,"dominant-baseline":o,"text-anchor":i});s.textContent=r&&Number.isFinite(r.value)?formatValue(n,r.value):``,c.appendChild(s)})})}function setActive(e){P=e;for(let t of D.querySelectorAll(`[data-axis]`)){let n=Number(t.getAttribute(`data-axis`))===e;t.classList.toggle(t.tagName===`line`?`prism-radar-spoke--active`:`prism-radar-point--active`,n)}}function animateTo(e){N!==null&&(cancelAnimationFrame(N),N=null);let t=e.map((e,t)=>e.map((e,n)=>M[t]?.[n]??0)),n=o.resolveMotion(g.transition,400),r=a.resolveEasing(n.easing??`ease-out`),i=t.every((t,n)=>t.every((t,r)=>t===e[n][r]));if(n.duration===0||i){M=e,draw(e);return}let c=null,frame=i=>{c===null&&(c=i);let a=i-c,o=!0;M=e.map((e,i)=>{let c=Math.max(0,Math.min(1,(a-i*n.stagger)/n.duration));return c<1&&(o=!1),e.map((e,n)=>s.tweenNumber(t[i][n],e,r(c)))}),draw(M),N=o?null:requestAnimationFrame(frame)};N=requestAnimationFrame(frame)}let I;try{return I=r.createRadialScaffold(h,{a11y:g.a11y,legend:g.legend,tooltip:g.tooltip},e=>{let{legend:t,svg:r,tooltip:a}=e;if(r.contains(D)||r.appendChild(D),a?.hide(),t?.update(E.map((e,t)=>({color:e.color??i.seriesColor(t),name:e.name}))),_.length<3){for(let e of[O,k,A,j])e.replaceChildren();M=[];return}let{height:o,width:s}=e.dimensions,c=u.fitRadius(s,o,_.map(e=>e.label),C,d,w);F={cx:s/2,cy:o/2,radius:c};let f=u.resolveAxisDomains(_,E,g.domain);renderGrid(f),renderLabels(),renderSeries(),animateTo(E.map(e=>_.map((t,n)=>{let r=datumAt(e,n)?.value;return r!==void 0&&Number.isFinite(r)?u.normalize(r,f[n]):0}))),setActive(P);let eventFor=(e,t)=>({axis:_[e],index:e,originalEvent:t,values:valuesAt(e)}),activate=(t,o)=>{setActive(t),g.onHover?.(eventFor(t,o));let s=describe(t);if(!a){e.announcer.announce(s);return}let c=Math.max(0,...M.map(e=>e[t]??0)),u=r.getBoundingClientRect(),d=h.getBoundingClientRect(),f=valuesAt(t),p=f.find(e=>e.datum)?.datum,m=f.flatMap(({datum:e,series:n})=>e?[{color:n.color??i.seriesColor(E.indexOf(n)),name:n.name,value:formatValue(t,e.value)}]:[]);a.show(l.polarX(F.cx,F.radius*c,C[t])+(u.left-d.left),l.polarY(F.cy,F.radius*c,C[t])+(u.top-d.top),{key:_[t].key,meta:{axis:_[t],text:s,values:f},value:p?.value??0},{color:E[0]?.color??i.seriesColor(0),data:[],name:_[t].label},n.comparisonContent(r.ownerDocument,_[t].label,m,s))},deactivate=()=>{setActive(-1),g.onHover?.(null),a?.hide(),e.announcer.clear()},hitIndex=e=>{let t=r.getBoundingClientRect(),n=e.clientX-t.left-F.cx,i=e.clientY-t.top-F.cy;return Math.hypot(n,i)>F.radius+w+22?-1:u.nearestAxis(n,i,_.length,S)};return{onClick(e){let t=hitIndex(e);t>=0&&g.onClick?.(eventFor(t,e))},onKeyDown(e){let t=m[e.key];t===void 0?(e.key===`Enter`||e.key===` `)&&P>=0&&g.onClick?(e.preventDefault(),g.onClick(eventFor(P,e))):e.key===`Escape`&&deactivate():(e.preventDefault(),activate(P<0?0:(P+t+_.length)%_.length,e))},onMouseLeave:deactivate,onMouseMove(e){let t=hitIndex(e);t<0?P>=0&&deactivate():t!==P&&activate(t,e)}}},e=>{E=e}),{get disposalSignal(){return I.disposalSignal},dispose(){N!==null&&(cancelAnimationFrame(N),N=null),I.dispose()},get disposed(){return I.disposed},el:I.el,update(e){I.update(e)},[Symbol.dispose](){this.dispose()}}}catch(e){throw I?.dispose(),e}}exports.createRadarChart=createRadarChart;
|
|
2
|
+
//# sourceMappingURL=radar-chart.cjs.map
|