@vielzeug/prism 26.10.1 → 26.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +3 -0
- 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-renderer.cjs +1 -1
- package/dist/charts/bar/bar-renderer.cjs.map +1 -1
- package/dist/charts/bar/bar-renderer.d.ts +2 -0
- package/dist/charts/bar/bar-renderer.d.ts.map +1 -1
- package/dist/charts/bar/bar-renderer.js +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 -0
- 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/radar/radar-chart.cjs +1 -1
- package/dist/charts/radar/radar-chart.cjs.map +1 -1
- package/dist/charts/radar/radar-chart.d.ts.map +1 -1
- package/dist/charts/radar/radar-chart.js +1 -1
- package/dist/charts/radar/radar-chart.js.map +1 -1
- package/dist/core/datum-style.cjs +2 -0
- package/dist/core/datum-style.cjs.map +1 -0
- package/dist/core/datum-style.d.ts +18 -0
- package/dist/core/datum-style.d.ts.map +1 -0
- package/dist/core/datum-style.js +2 -0
- package/dist/core/datum-style.js.map +1 -0
- package/dist/core/series-id.cjs +2 -0
- package/dist/core/series-id.cjs.map +1 -0
- package/dist/core/series-id.d.ts +8 -0
- package/dist/core/series-id.d.ts.map +1 -0
- package/dist/core/series-id.js +2 -0
- package/dist/core/series-id.js.map +1 -0
- 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/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../../svg/element.cjs"),t=require("../../axes/axis.cjs"),n=require("../../axes/grid.cjs"),r=require("../../core/cartesian-scales.cjs"),i=require("../../core/layout.cjs"),a=require("../../core/chart-scaffold.cjs"),o=require("../../interaction/crosshair.cjs"),
|
|
1
|
+
const e=require("../../svg/element.cjs"),t=require("../../axes/axis.cjs"),n=require("../../axes/grid.cjs"),r=require("../../core/cartesian-scales.cjs"),i=require("../../core/layout.cjs"),a=require("../../core/chart-scaffold.cjs"),o=require("../../core/series-id.cjs"),s=require("../../interaction/crosshair.cjs"),c=require("../../interaction/series-interaction.cjs"),l=require("../../theme/index.cjs"),u=require("./area-renderer.cjs");function createAreaChart(d,f){let p=null,m=null,h=f.series;return a.createChartScaffold(d,f,d=>{let{groups:g,legend:_,tooltip:v}=d,y=d.dimensions,b=i.chartArea(y.width,y.height,y.margin),x=h.map(e=>e.data),S=x.flat().map(e=>e.key),C=x.flat().map(e=>e.value);if(S.length===0){a.clearCartesianDom(g,_,v,p),m?.replaceChildren();return}f.crosshair&&!p&&(p=s.createCrosshair(d.chartArea,f.crosshair));let w=r.buildXScale(S,b.width),T=r.buildYScale(C,b.height),E=T.map(0);for(f.yAxis?.grid&&n.renderGrid(g.grid,T,f.yAxis.grid,b.width,`horizontal`,t.resolveTickCount(f.yAxis,b.height,`left`)),f.xAxis?.grid&&n.renderGrid(g.grid,w,f.xAxis.grid,b.height,`vertical`,t.resolveTickCount(f.xAxis,b.width,`bottom`)),f.xAxis&&(t.positionAxis(g.xAxis,f.xAxis.position??`bottom`,b.width,b.height),t.renderAxis(g.xAxis,w,f.xAxis,b.width,`bottom`)),f.yAxis&&(t.positionAxis(g.yAxis,f.yAxis.position??`left`,b.width,b.height),t.renderAxis(g.yAxis,T,f.yAxis,b.height,`left`));g.series.children.length>h.length;)g.series.removeChild(g.series.lastChild);let D=[];for(let t=0;t<h.length;t++){let n=h[t],r=g.series.children[t];r||(r=e.createSvgElement(`g`,{class:`prism-area-series`}),g.series.appendChild(r)),r.setAttribute(`data-series-id`,o.seriesDomId(n,t));let i=u.computeAreaPoints(x[t],w,T);D.push(i),u.renderArea(r,i,E,{color:l.seriesColor(t,n.color),curve:n.curve??`linear`,disposalSignal:d.disposalSignal,fill:n.fill??`gradient`,fillOpacity:n.fillOpacity,marks:n.data,showLine:n.showLine!==!1,transition:f.transition})}return _?.update(h.map((e,t)=>({color:l.seriesColor(t,e.color),name:e.name}))),v?.hide(),m=c.ensureMarkerGroup(d.chartArea,m),c.createSeriesInteraction({announcer:d.announcer,colors:()=>h.map((e,t)=>l.seriesColor(t,e.color)),crosshair:p,dims:()=>d.dimensions,getData:()=>x,getPoints:()=>D,getSeriesList:()=>h,markers:m,onClick:f.onClick,onHover:f.onHover,seriesGroup:g.series,svg:d.svg,tooltip:v})},e=>{h=e})}exports.createAreaChart=createAreaChart;
|
|
2
2
|
//# sourceMappingURL=area-chart.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-chart.cjs","names":[],"sources":["../../../src/charts/area/area-chart.ts"],"sourcesContent":["import { positionAxis, renderAxis, resolveTickCount } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { buildXScale, buildYScale } from '../../core/cartesian-scales';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { createCrosshair } from '../../interaction/crosshair';\nimport { createSeriesInteraction, ensureMarkerGroup } from '../../interaction/series-interaction';\nimport { createSvgElement } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { seriesColor } from '../../theme';\nimport type { AreaChartConfig, AreaSeriesConfig, ChartHandle } from '../../types';\nimport { computeAreaPoints, renderArea } from './area-renderer';\n\nexport function createAreaChart(container: HTMLElement, config: AreaChartConfig): ChartHandle<AreaSeriesConfig[]> {\n let crosshair: ReturnType<typeof createCrosshair> | null = null;\n let markers: SVGGElement | null = null;\n let seriesList = config.series;\n\n return createChartScaffold(\n container,\n config,\n (ctx) => {\n const { groups, legend, tooltip } = ctx;\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const allData = seriesList.map((series) => series.data);\n const allX = allData.flat().map((datum) => datum.key);\n const allY = allData.flat().map((d) => d.value);\n\n if (allX.length === 0) {\n clearCartesianDom(groups, legend, tooltip, crosshair);\n markers?.replaceChildren();\n\n return;\n }\n\n if (config.crosshair && !crosshair) {\n crosshair = createCrosshair(ctx.chartArea, config.crosshair);\n }\n\n const xScale = buildXScale(allX, area.width);\n const yScale = buildYScale(allY, area.height);\n const baselineY = yScale.map(0);\n\n if (config.yAxis?.grid) {\n renderGrid(\n groups.grid,\n yScale,\n config.yAxis.grid,\n area.width,\n 'horizontal',\n resolveTickCount(config.yAxis, area.height, 'left'),\n );\n }\n\n if (config.xAxis?.grid) {\n renderGrid(\n groups.grid,\n xScale,\n config.xAxis.grid,\n area.height,\n 'vertical',\n resolveTickCount(config.xAxis, area.width, 'bottom'),\n );\n }\n\n if (config.xAxis) {\n positionAxis(groups.xAxis, config.xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, xScale, config.xAxis, area.width, 'bottom');\n }\n\n if (config.yAxis) {\n positionAxis(groups.yAxis, config.yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, yScale, config.yAxis, area.height, 'left');\n }\n\n while (groups.series.children.length > seriesList.length) {\n groups.series.removeChild(groups.series.lastChild!);\n }\n\n const allPoints: Point[][] = [];\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-area-series' });\n groups.series.appendChild(group);\n }\n\n const points = computeAreaPoints(allData[i], xScale, yScale);\n\n allPoints.push(points);\n\n renderArea(group, points, baselineY, {\n color: seriesColor(i, series.color),\n curve: series.curve ?? 'linear',\n disposalSignal: ctx.disposalSignal,\n fill: series.fill ?? 'gradient',\n fillOpacity: series.fillOpacity,\n showLine: series.showLine !== false,\n transition: config.transition,\n });\n }\n\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n tooltip?.hide();\n markers = ensureMarkerGroup(ctx.chartArea, markers);\n\n return createSeriesInteraction({\n announcer: ctx.announcer,\n colors: () => seriesList.map((s, i) => seriesColor(i, s.color)),\n crosshair,\n dims: () => ctx.dimensions,\n getData: () => allData,\n getPoints: () => allPoints,\n getSeriesList: () => seriesList,\n markers,\n onClick: config.onClick,\n onHover: config.onHover,\n seriesGroup: groups.series,\n svg: ctx.svg,\n tooltip,\n });\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"area-chart.cjs","names":[],"sources":["../../../src/charts/area/area-chart.ts"],"sourcesContent":["import { positionAxis, renderAxis, resolveTickCount } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { buildXScale, buildYScale } from '../../core/cartesian-scales';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { createCrosshair } from '../../interaction/crosshair';\nimport { createSeriesInteraction, ensureMarkerGroup } from '../../interaction/series-interaction';\nimport { createSvgElement } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { seriesColor } from '../../theme';\nimport type { AreaChartConfig, AreaSeriesConfig, ChartHandle } from '../../types';\nimport { computeAreaPoints, renderArea } from './area-renderer';\n\nexport function createAreaChart(container: HTMLElement, config: AreaChartConfig): ChartHandle<AreaSeriesConfig[]> {\n let crosshair: ReturnType<typeof createCrosshair> | null = null;\n let markers: SVGGElement | null = null;\n let seriesList = config.series;\n\n return createChartScaffold(\n container,\n config,\n (ctx) => {\n const { groups, legend, tooltip } = ctx;\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const allData = seriesList.map((series) => series.data);\n const allX = allData.flat().map((datum) => datum.key);\n const allY = allData.flat().map((d) => d.value);\n\n if (allX.length === 0) {\n clearCartesianDom(groups, legend, tooltip, crosshair);\n markers?.replaceChildren();\n\n return;\n }\n\n if (config.crosshair && !crosshair) {\n crosshair = createCrosshair(ctx.chartArea, config.crosshair);\n }\n\n const xScale = buildXScale(allX, area.width);\n const yScale = buildYScale(allY, area.height);\n const baselineY = yScale.map(0);\n\n if (config.yAxis?.grid) {\n renderGrid(\n groups.grid,\n yScale,\n config.yAxis.grid,\n area.width,\n 'horizontal',\n resolveTickCount(config.yAxis, area.height, 'left'),\n );\n }\n\n if (config.xAxis?.grid) {\n renderGrid(\n groups.grid,\n xScale,\n config.xAxis.grid,\n area.height,\n 'vertical',\n resolveTickCount(config.xAxis, area.width, 'bottom'),\n );\n }\n\n if (config.xAxis) {\n positionAxis(groups.xAxis, config.xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, xScale, config.xAxis, area.width, 'bottom');\n }\n\n if (config.yAxis) {\n positionAxis(groups.yAxis, config.yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, yScale, config.yAxis, area.height, 'left');\n }\n\n while (groups.series.children.length > seriesList.length) {\n groups.series.removeChild(groups.series.lastChild!);\n }\n\n const allPoints: Point[][] = [];\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-area-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const points = computeAreaPoints(allData[i], xScale, yScale);\n\n allPoints.push(points);\n\n renderArea(group, points, baselineY, {\n color: seriesColor(i, series.color),\n curve: series.curve ?? 'linear',\n disposalSignal: ctx.disposalSignal,\n fill: series.fill ?? 'gradient',\n fillOpacity: series.fillOpacity,\n marks: series.data,\n showLine: series.showLine !== false,\n transition: config.transition,\n });\n }\n\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n tooltip?.hide();\n markers = ensureMarkerGroup(ctx.chartArea, markers);\n\n return createSeriesInteraction({\n announcer: ctx.announcer,\n colors: () => seriesList.map((s, i) => seriesColor(i, s.color)),\n crosshair,\n dims: () => ctx.dimensions,\n getData: () => allData,\n getPoints: () => allPoints,\n getSeriesList: () => seriesList,\n markers,\n onClick: config.onClick,\n onHover: config.onHover,\n seriesGroup: groups.series,\n svg: ctx.svg,\n tooltip,\n });\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-chart.d.ts","sourceRoot":"","sources":["../../../src/charts/area/area-chart.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"area-chart.d.ts","sourceRoot":"","sources":["../../../src/charts/area/area-chart.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGlF,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,GAAG,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAwHhH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createSvgElement as e}from"../../svg/element.js";import{positionAxis as t,renderAxis as n,resolveTickCount as r}from"../../axes/axis.js";import{renderGrid as i}from"../../axes/grid.js";import{buildXScale as a,buildYScale as o}from"../../core/cartesian-scales.js";import{chartArea as s}from"../../core/layout.js";import{clearCartesianDom as c,createChartScaffold as l}from"../../core/chart-scaffold.js";import{
|
|
1
|
+
import{createSvgElement as e}from"../../svg/element.js";import{positionAxis as t,renderAxis as n,resolveTickCount as r}from"../../axes/axis.js";import{renderGrid as i}from"../../axes/grid.js";import{buildXScale as a,buildYScale as o}from"../../core/cartesian-scales.js";import{chartArea as s}from"../../core/layout.js";import{clearCartesianDom as c,createChartScaffold as l}from"../../core/chart-scaffold.js";import{seriesDomId as u}from"../../core/series-id.js";import{createCrosshair as d}from"../../interaction/crosshair.js";import{createSeriesInteraction as f,ensureMarkerGroup as p}from"../../interaction/series-interaction.js";import{seriesColor as m}from"../../theme/index.js";import{computeAreaPoints as h,renderArea as g}from"./area-renderer.js";function createAreaChart(_,v){let y=null,b=null,x=v.series;return l(_,v,l=>{let{groups:_,legend:S,tooltip:C}=l,w=l.dimensions,T=s(w.width,w.height,w.margin),E=x.map(e=>e.data),D=E.flat().map(e=>e.key),O=E.flat().map(e=>e.value);if(D.length===0){c(_,S,C,y),b?.replaceChildren();return}v.crosshair&&!y&&(y=d(l.chartArea,v.crosshair));let k=a(D,T.width),A=o(O,T.height),j=A.map(0);for(v.yAxis?.grid&&i(_.grid,A,v.yAxis.grid,T.width,`horizontal`,r(v.yAxis,T.height,`left`)),v.xAxis?.grid&&i(_.grid,k,v.xAxis.grid,T.height,`vertical`,r(v.xAxis,T.width,`bottom`)),v.xAxis&&(t(_.xAxis,v.xAxis.position??`bottom`,T.width,T.height),n(_.xAxis,k,v.xAxis,T.width,`bottom`)),v.yAxis&&(t(_.yAxis,v.yAxis.position??`left`,T.width,T.height),n(_.yAxis,A,v.yAxis,T.height,`left`));_.series.children.length>x.length;)_.series.removeChild(_.series.lastChild);let M=[];for(let t=0;t<x.length;t++){let n=x[t],r=_.series.children[t];r||(r=e(`g`,{class:`prism-area-series`}),_.series.appendChild(r)),r.setAttribute(`data-series-id`,u(n,t));let i=h(E[t],k,A);M.push(i),g(r,i,j,{color:m(t,n.color),curve:n.curve??`linear`,disposalSignal:l.disposalSignal,fill:n.fill??`gradient`,fillOpacity:n.fillOpacity,marks:n.data,showLine:n.showLine!==!1,transition:v.transition})}return S?.update(x.map((e,t)=>({color:m(t,e.color),name:e.name}))),C?.hide(),b=p(l.chartArea,b),f({announcer:l.announcer,colors:()=>x.map((e,t)=>m(t,e.color)),crosshair:y,dims:()=>l.dimensions,getData:()=>E,getPoints:()=>M,getSeriesList:()=>x,markers:b,onClick:v.onClick,onHover:v.onHover,seriesGroup:_.series,svg:l.svg,tooltip:C})},e=>{x=e})}export{createAreaChart};
|
|
2
2
|
//# sourceMappingURL=area-chart.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-chart.js","names":[],"sources":["../../../src/charts/area/area-chart.ts"],"sourcesContent":["import { positionAxis, renderAxis, resolveTickCount } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { buildXScale, buildYScale } from '../../core/cartesian-scales';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { createCrosshair } from '../../interaction/crosshair';\nimport { createSeriesInteraction, ensureMarkerGroup } from '../../interaction/series-interaction';\nimport { createSvgElement } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { seriesColor } from '../../theme';\nimport type { AreaChartConfig, AreaSeriesConfig, ChartHandle } from '../../types';\nimport { computeAreaPoints, renderArea } from './area-renderer';\n\nexport function createAreaChart(container: HTMLElement, config: AreaChartConfig): ChartHandle<AreaSeriesConfig[]> {\n let crosshair: ReturnType<typeof createCrosshair> | null = null;\n let markers: SVGGElement | null = null;\n let seriesList = config.series;\n\n return createChartScaffold(\n container,\n config,\n (ctx) => {\n const { groups, legend, tooltip } = ctx;\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const allData = seriesList.map((series) => series.data);\n const allX = allData.flat().map((datum) => datum.key);\n const allY = allData.flat().map((d) => d.value);\n\n if (allX.length === 0) {\n clearCartesianDom(groups, legend, tooltip, crosshair);\n markers?.replaceChildren();\n\n return;\n }\n\n if (config.crosshair && !crosshair) {\n crosshair = createCrosshair(ctx.chartArea, config.crosshair);\n }\n\n const xScale = buildXScale(allX, area.width);\n const yScale = buildYScale(allY, area.height);\n const baselineY = yScale.map(0);\n\n if (config.yAxis?.grid) {\n renderGrid(\n groups.grid,\n yScale,\n config.yAxis.grid,\n area.width,\n 'horizontal',\n resolveTickCount(config.yAxis, area.height, 'left'),\n );\n }\n\n if (config.xAxis?.grid) {\n renderGrid(\n groups.grid,\n xScale,\n config.xAxis.grid,\n area.height,\n 'vertical',\n resolveTickCount(config.xAxis, area.width, 'bottom'),\n );\n }\n\n if (config.xAxis) {\n positionAxis(groups.xAxis, config.xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, xScale, config.xAxis, area.width, 'bottom');\n }\n\n if (config.yAxis) {\n positionAxis(groups.yAxis, config.yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, yScale, config.yAxis, area.height, 'left');\n }\n\n while (groups.series.children.length > seriesList.length) {\n groups.series.removeChild(groups.series.lastChild!);\n }\n\n const allPoints: Point[][] = [];\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-area-series' });\n groups.series.appendChild(group);\n }\n\n const points = computeAreaPoints(allData[i], xScale, yScale);\n\n allPoints.push(points);\n\n renderArea(group, points, baselineY, {\n color: seriesColor(i, series.color),\n curve: series.curve ?? 'linear',\n disposalSignal: ctx.disposalSignal,\n fill: series.fill ?? 'gradient',\n fillOpacity: series.fillOpacity,\n showLine: series.showLine !== false,\n transition: config.transition,\n });\n }\n\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n tooltip?.hide();\n markers = ensureMarkerGroup(ctx.chartArea, markers);\n\n return createSeriesInteraction({\n announcer: ctx.announcer,\n colors: () => seriesList.map((s, i) => seriesColor(i, s.color)),\n crosshair,\n dims: () => ctx.dimensions,\n getData: () => allData,\n getPoints: () => allPoints,\n getSeriesList: () => seriesList,\n markers,\n onClick: config.onClick,\n onHover: config.onHover,\n seriesGroup: groups.series,\n svg: ctx.svg,\n tooltip,\n });\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"area-chart.js","names":[],"sources":["../../../src/charts/area/area-chart.ts"],"sourcesContent":["import { positionAxis, renderAxis, resolveTickCount } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { buildXScale, buildYScale } from '../../core/cartesian-scales';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { createCrosshair } from '../../interaction/crosshair';\nimport { createSeriesInteraction, ensureMarkerGroup } from '../../interaction/series-interaction';\nimport { createSvgElement } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { seriesColor } from '../../theme';\nimport type { AreaChartConfig, AreaSeriesConfig, ChartHandle } from '../../types';\nimport { computeAreaPoints, renderArea } from './area-renderer';\n\nexport function createAreaChart(container: HTMLElement, config: AreaChartConfig): ChartHandle<AreaSeriesConfig[]> {\n let crosshair: ReturnType<typeof createCrosshair> | null = null;\n let markers: SVGGElement | null = null;\n let seriesList = config.series;\n\n return createChartScaffold(\n container,\n config,\n (ctx) => {\n const { groups, legend, tooltip } = ctx;\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const allData = seriesList.map((series) => series.data);\n const allX = allData.flat().map((datum) => datum.key);\n const allY = allData.flat().map((d) => d.value);\n\n if (allX.length === 0) {\n clearCartesianDom(groups, legend, tooltip, crosshair);\n markers?.replaceChildren();\n\n return;\n }\n\n if (config.crosshair && !crosshair) {\n crosshair = createCrosshair(ctx.chartArea, config.crosshair);\n }\n\n const xScale = buildXScale(allX, area.width);\n const yScale = buildYScale(allY, area.height);\n const baselineY = yScale.map(0);\n\n if (config.yAxis?.grid) {\n renderGrid(\n groups.grid,\n yScale,\n config.yAxis.grid,\n area.width,\n 'horizontal',\n resolveTickCount(config.yAxis, area.height, 'left'),\n );\n }\n\n if (config.xAxis?.grid) {\n renderGrid(\n groups.grid,\n xScale,\n config.xAxis.grid,\n area.height,\n 'vertical',\n resolveTickCount(config.xAxis, area.width, 'bottom'),\n );\n }\n\n if (config.xAxis) {\n positionAxis(groups.xAxis, config.xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, xScale, config.xAxis, area.width, 'bottom');\n }\n\n if (config.yAxis) {\n positionAxis(groups.yAxis, config.yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, yScale, config.yAxis, area.height, 'left');\n }\n\n while (groups.series.children.length > seriesList.length) {\n groups.series.removeChild(groups.series.lastChild!);\n }\n\n const allPoints: Point[][] = [];\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-area-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const points = computeAreaPoints(allData[i], xScale, yScale);\n\n allPoints.push(points);\n\n renderArea(group, points, baselineY, {\n color: seriesColor(i, series.color),\n curve: series.curve ?? 'linear',\n disposalSignal: ctx.disposalSignal,\n fill: series.fill ?? 'gradient',\n fillOpacity: series.fillOpacity,\n marks: series.data,\n showLine: series.showLine !== false,\n transition: config.transition,\n });\n }\n\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n tooltip?.hide();\n markers = ensureMarkerGroup(ctx.chartArea, markers);\n\n return createSeriesInteraction({\n announcer: ctx.announcer,\n colors: () => seriesList.map((s, i) => seriesColor(i, s.color)),\n crosshair,\n dims: () => ctx.dimensions,\n getData: () => allData,\n getPoints: () => allPoints,\n getSeriesList: () => seriesList,\n markers,\n onClick: config.onClick,\n onHover: config.onHover,\n seriesGroup: groups.series,\n svg: ctx.svg,\n tooltip,\n });\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../animation/easing.cjs"),n=require("../../animation/motion.cjs"),r=require("../../animation/tween.cjs"),i=require("../../core/
|
|
1
|
+
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../animation/easing.cjs"),n=require("../../animation/motion.cjs"),r=require("../../animation/tween.cjs"),i=require("../../core/datum-style.cjs"),a=require("../../core/ids.cjs"),o=require("../../svg/path.cjs");var s=new WeakMap,c=new WeakMap;function buildLinePath(e,t){return t===`monotone`?o.monotonePath(e):t===`step`?o.stepPath(e):o.linePath(e)}function applyAreaFill(t,n,r){let i=t.querySelector(`linearGradient`);if(r.fill===`gradient`){if(!i){let n=e.createSvgElement(`defs`);i=e.createSvgElement(`linearGradient`,{id:a.uniqueId(`prism-area-fill`),x1:0,x2:0,y1:0,y2:1}),i.append(e.createSvgElement(`stop`,{class:`prism-area-stop-top`,offset:0}),e.createSvgElement(`stop`,{class:`prism-area-stop-bottom`,offset:1})),n.appendChild(i),t.insertBefore(n,t.firstChild)}for(let e of i.querySelectorAll(`stop`))e.setAttribute(`stop-color`,r.color),e.style.stopColor=r.color;e.setAttributes(n,{fill:`url(#${i.id})`})}else i?.parentElement?.remove(),e.setAttributes(n,{fill:r.color});e.setAttributes(n,{class:`prism-area-fill prism-area-fill--${r.fill}`,stroke:`none`}),n.style.fillOpacity=r.fillOpacity===void 0?``:String(r.fillOpacity)}function renderArea(a,l,u,d){let f=n.resolveMotion(d.transition,0),p=f.duration,m=t.resolveEasing(f.easing),h=a.querySelector(`.prism-area-fill`);h||(h=e.createSvgElement(`path`,{class:`prism-area-fill`}),a.appendChild(h)),applyAreaFill(a,h,d);let g=null,_=[],v=[],y=i.hasStyledRuns(d.marks),b=d.marks??[];if(d.showLine){if(y){_=i.computeStyleRuns(b,l.length);let t=[...a.querySelectorAll(`.prism-area-line`)];for(let e of t.slice(_.length))e.remove();v=_.map((n,r)=>{let i=t[r];if(i)return i;let o=e.createSvgElement(`path`,{class:`prism-area-line`,fill:`none`});return a.appendChild(o),o});for(let[t,n]of _.entries())e.setAttributes(v[t],{opacity:n.opacity,stroke:d.color,"stroke-dasharray":n.dash,"stroke-width":2});g=null}else{let t=[...a.querySelectorAll(`.prism-area-line`)];for(let e of t.slice(1))e.remove();g=t[0]??null,g||(g=e.createSvgElement(`path`,{class:`prism-area-line`,fill:`none`}),a.appendChild(g)),e.setAttributes(g,{opacity:void 0,stroke:d.color,"stroke-dasharray":void 0,"stroke-width":2})}}else for(let e of a.querySelectorAll(`.prism-area-line`))e.remove();let drawLine=t=>{if(d.showLine){if(y)for(let[n,r]of _.entries())e.setAttributes(v[n],{d:buildLinePath(t.slice(r.start,r.end+1),d.curve)});else g&&e.setAttributes(g,{d:buildLinePath(t,d.curve)})}};if(p===0){let t=l.map(e=>({x:e.x,y:u}));e.setAttributes(h,{d:o.areaPath(l,t,d.curve)}),drawLine(l);return}if(s.get(a)?.(),!h.hasAttribute(`d`)){let t=l.map(e=>({x:e.x,y:u}));e.setAttributes(h,{d:o.areaPath(l,t,d.curve)}),drawLine(l),c.set(a,l);return}let x=c.get(a)??l,S=l.map((e,t)=>x[t]??x[x.length-1]??l[t]),C=null;function frame(t){if(d.disposalSignal?.aborted){s.delete(a);return}C===null&&(C=t);let n=Math.min(1,(t-C)/p),i=m(n),f=l.map((e,t)=>({x:r.tweenNumber(S[t].x,e.x,i),y:r.tweenNumber(S[t].y,e.y,i)})),g=f.map(e=>({x:e.x,y:u}));if(e.setAttributes(h,{d:o.areaPath(f,g,d.curve)}),drawLine(f),n<1){let e=requestAnimationFrame(frame);s.set(a,()=>cancelAnimationFrame(e))}else s.delete(a),c.set(a,l)}c.set(a,S);let w=requestAnimationFrame(frame);s.set(a,()=>cancelAnimationFrame(w))}function computeAreaPoints(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)}))}exports.computeAreaPoints=computeAreaPoints,exports.renderArea=renderArea;
|
|
2
2
|
//# sourceMappingURL=area-renderer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-renderer.cjs","names":[],"sources":["../../../src/charts/area/area-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { uniqueId } from '../../core/ids';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface AreaRenderOptions {\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 fill: 'gradient' | 'solid';\n /** Explicit opacity beats the `--prism-area-opacity` theme token. */\n fillOpacity?: number;\n showLine: boolean;\n transition?: TransitionConfig;\n}\n\nconst activeAreaAnimations = new WeakMap<SVGGElement, () => void>();\nconst previousPoints = new WeakMap<SVGGElement, Point[]>();\n\nfunction buildLinePath(pts: Point[], curve: AreaRenderOptions['curve']): string {\n return curve === 'monotone' ? monotonePath(pts) : curve === 'step' ? stepPath(pts) : linePath(pts);\n}\n\n/** A vertical gradient fading to transparent at the baseline, or a flat fill. */\nfunction applyAreaFill(parent: SVGGElement, fill: SVGPathElement, options: AreaRenderOptions): void {\n let gradient = parent.querySelector<SVGLinearGradientElement>('linearGradient');\n\n if (options.fill === 'gradient') {\n if (!gradient) {\n const defs = createSvgElement('defs');\n\n gradient = createSvgElement('linearGradient', { id: uniqueId('prism-area-fill'), x1: 0, x2: 0, y1: 0, y2: 1 });\n gradient.append(\n createSvgElement('stop', { class: 'prism-area-stop-top', offset: 0 }),\n createSvgElement('stop', { class: 'prism-area-stop-bottom', offset: 1 }),\n );\n defs.appendChild(gradient);\n parent.insertBefore(defs, parent.firstChild);\n }\n\n for (const stop of gradient.querySelectorAll('stop')) {\n stop.setAttribute('stop-color', options.color);\n stop.style.stopColor = options.color;\n }\n\n setAttributes(fill, { fill: `url(#${gradient.id})` });\n } else {\n gradient?.parentElement?.remove();\n setAttributes(fill, { fill: options.color });\n }\n\n setAttributes(fill, { class: `prism-area-fill prism-area-fill--${options.fill}`, stroke: 'none' });\n fill.style.fillOpacity = options.fillOpacity === undefined ? '' : String(options.fillOpacity);\n}\n\nexport function renderArea(parent: SVGGElement, points: Point[], baselineY: number, options: AreaRenderOptions): void {\n const motion = resolveMotion(options.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n let fill = parent.querySelector<SVGPathElement>('.prism-area-fill');\n\n if (!fill) {\n fill = createSvgElement('path', { class: 'prism-area-fill' });\n parent.appendChild(fill);\n }\n\n applyAreaFill(parent, fill, options);\n\n let line: SVGPathElement | null = null;\n\n if (options.showLine) {\n line = parent.querySelector<SVGPathElement>('.prism-area-line');\n\n if (!line) {\n line = createSvgElement('path', { class: 'prism-area-line', fill: 'none' });\n parent.appendChild(line);\n }\n\n setAttributes(line, { stroke: options.color, 'stroke-width': 2 });\n } else {\n parent.querySelector('.prism-area-line')?.remove();\n }\n\n if (dur === 0) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n if (line) setAttributes(line, { d: buildLinePath(points, options.curve) });\n\n return;\n }\n\n activeAreaAnimations.get(parent)?.();\n\n const hasExisting = fill.hasAttribute('d');\n\n if (!hasExisting) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n if (line) setAttributes(line, { d: buildLinePath(points, options.curve) });\n\n previousPoints.set(parent, points);\n\n return;\n }\n\n const rawFrom = previousPoints.get(parent) ?? points;\n const fromPoints: Point[] = points.map((_, i) => rawFrom[i] ?? rawFrom[rawFrom.length - 1] ?? points[i]);\n\n let startTime: number | null = null;\n\n function frame(ts: number) {\n if (options.disposalSignal?.aborted) {\n activeAreaAnimations.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 x: tweenNumber(fromPoints[i].x, to.x, e),\n y: tweenNumber(fromPoints[i].y, to.y, e),\n }));\n const interpolatedBottom = interpolated.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill!, { d: areaPath(interpolated, interpolatedBottom, options.curve) });\n\n if (line) setAttributes(line, { d: buildLinePath(interpolated, options.curve) });\n\n if (t < 1) {\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n } else {\n activeAreaAnimations.delete(parent);\n previousPoints.set(parent, points);\n }\n }\n\n previousPoints.set(parent, fromPoints);\n\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n}\n\nexport function computeAreaPoints(\n data: ContinuousDatum[],\n xScale: Scale<Date | number>,\n yScale: Scale<number>,\n): Point[] {\n if (data.some((d) => d.key == null)) {\n warn(\n 'computeAreaPoints: 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('computeAreaPoints: 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
|
+
{"version":3,"file":"area-renderer.cjs","names":[],"sources":["../../../src/charts/area/area-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { computeStyleRuns, type DatumMark, hasStyledRuns, type StyleRun } from '../../core/datum-style';\nimport { uniqueId } from '../../core/ids';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface AreaRenderOptions {\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 fill: 'gradient' | 'solid';\n /** Explicit opacity beats the `--prism-area-opacity` theme token. */\n fillOpacity?: number;\n /** Per-datum presentation parallel to `points`; styled runs split the top line into subpaths. */\n marks?: readonly DatumMark[];\n showLine: boolean;\n transition?: TransitionConfig;\n}\n\nconst activeAreaAnimations = new WeakMap<SVGGElement, () => void>();\nconst previousPoints = new WeakMap<SVGGElement, Point[]>();\n\nfunction buildLinePath(pts: Point[], curve: AreaRenderOptions['curve']): string {\n return curve === 'monotone' ? monotonePath(pts) : curve === 'step' ? stepPath(pts) : linePath(pts);\n}\n\n/** A vertical gradient fading to transparent at the baseline, or a flat fill. */\nfunction applyAreaFill(parent: SVGGElement, fill: SVGPathElement, options: AreaRenderOptions): void {\n let gradient = parent.querySelector<SVGLinearGradientElement>('linearGradient');\n\n if (options.fill === 'gradient') {\n if (!gradient) {\n const defs = createSvgElement('defs');\n\n gradient = createSvgElement('linearGradient', { id: uniqueId('prism-area-fill'), x1: 0, x2: 0, y1: 0, y2: 1 });\n gradient.append(\n createSvgElement('stop', { class: 'prism-area-stop-top', offset: 0 }),\n createSvgElement('stop', { class: 'prism-area-stop-bottom', offset: 1 }),\n );\n defs.appendChild(gradient);\n parent.insertBefore(defs, parent.firstChild);\n }\n\n for (const stop of gradient.querySelectorAll('stop')) {\n stop.setAttribute('stop-color', options.color);\n stop.style.stopColor = options.color;\n }\n\n setAttributes(fill, { fill: `url(#${gradient.id})` });\n } else {\n gradient?.parentElement?.remove();\n setAttributes(fill, { fill: options.color });\n }\n\n setAttributes(fill, { class: `prism-area-fill prism-area-fill--${options.fill}`, stroke: 'none' });\n fill.style.fillOpacity = options.fillOpacity === undefined ? '' : String(options.fillOpacity);\n}\n\nexport function renderArea(parent: SVGGElement, points: Point[], baselineY: number, options: AreaRenderOptions): void {\n const motion = resolveMotion(options.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n let fill = parent.querySelector<SVGPathElement>('.prism-area-fill');\n\n if (!fill) {\n fill = createSvgElement('path', { class: 'prism-area-fill' });\n parent.appendChild(fill);\n }\n\n applyAreaFill(parent, fill, options);\n\n let line: SVGPathElement | null = null;\n let runs: readonly StyleRun[] = [];\n let lines: SVGPathElement[] = [];\n const styled = hasStyledRuns(options.marks);\n const marks = options.marks ?? [];\n\n if (options.showLine) {\n if (styled) {\n runs = computeStyleRuns(marks, points.length);\n\n const existing = [...parent.querySelectorAll<SVGPathElement>('.prism-area-line')];\n\n for (const extra of existing.slice(runs.length)) extra.remove();\n\n lines = runs.map((_, r) => {\n const reuse = existing[r];\n\n if (reuse) return reuse;\n\n const created = createSvgElement('path', { class: 'prism-area-line', fill: 'none' });\n\n parent.appendChild(created);\n\n return created;\n });\n\n for (const [r, run] of runs.entries()) {\n setAttributes(lines[r], {\n opacity: run.opacity,\n stroke: options.color,\n 'stroke-dasharray': run.dash,\n 'stroke-width': 2,\n });\n }\n\n line = null;\n } else {\n const existing = [...parent.querySelectorAll<SVGPathElement>('.prism-area-line')];\n\n for (const stale of existing.slice(1)) stale.remove();\n\n line = existing[0] ?? null;\n\n if (!line) {\n line = createSvgElement('path', { class: 'prism-area-line', fill: 'none' });\n parent.appendChild(line);\n }\n\n setAttributes(line, {\n opacity: undefined,\n stroke: options.color,\n 'stroke-dasharray': undefined,\n 'stroke-width': 2,\n });\n }\n } else {\n for (const stale of parent.querySelectorAll('.prism-area-line')) stale.remove();\n }\n\n const drawLine = (pts: Point[]): void => {\n if (!options.showLine) return;\n\n if (styled) {\n for (const [r, run] of runs.entries()) {\n setAttributes(lines[r], { d: buildLinePath(pts.slice(run.start, run.end + 1), options.curve) });\n }\n } else if (line) {\n setAttributes(line, { d: buildLinePath(pts, options.curve) });\n }\n };\n\n if (dur === 0) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n drawLine(points);\n\n return;\n }\n\n activeAreaAnimations.get(parent)?.();\n\n const hasExisting = fill.hasAttribute('d');\n\n if (!hasExisting) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n drawLine(points);\n\n previousPoints.set(parent, points);\n\n return;\n }\n\n const rawFrom = previousPoints.get(parent) ?? points;\n const fromPoints: Point[] = points.map((_, i) => rawFrom[i] ?? rawFrom[rawFrom.length - 1] ?? points[i]);\n\n let startTime: number | null = null;\n\n function frame(ts: number) {\n if (options.disposalSignal?.aborted) {\n activeAreaAnimations.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 x: tweenNumber(fromPoints[i].x, to.x, e),\n y: tweenNumber(fromPoints[i].y, to.y, e),\n }));\n const interpolatedBottom = interpolated.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill!, { d: areaPath(interpolated, interpolatedBottom, options.curve) });\n\n drawLine(interpolated);\n\n if (t < 1) {\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n } else {\n activeAreaAnimations.delete(parent);\n previousPoints.set(parent, points);\n }\n }\n\n previousPoints.set(parent, fromPoints);\n\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n}\n\nexport function computeAreaPoints(\n data: ContinuousDatum[],\n xScale: Scale<Date | number>,\n yScale: Scale<number>,\n): Point[] {\n if (data.some((d) => d.key == null)) {\n warn(\n 'computeAreaPoints: 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('computeAreaPoints: 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,3 +1,4 @@
|
|
|
1
|
+
import { type DatumMark } from '../../core/datum-style';
|
|
1
2
|
import type { Point } from '../../svg/path';
|
|
2
3
|
import type { ContinuousDatum, Scale, TransitionConfig } from '../../types';
|
|
3
4
|
export interface AreaRenderOptions {
|
|
@@ -8,6 +9,8 @@ export interface AreaRenderOptions {
|
|
|
8
9
|
fill: 'gradient' | 'solid';
|
|
9
10
|
/** Explicit opacity beats the `--prism-area-opacity` theme token. */
|
|
10
11
|
fillOpacity?: number;
|
|
12
|
+
/** Per-datum presentation parallel to `points`; styled runs split the top line into subpaths. */
|
|
13
|
+
marks?: readonly DatumMark[];
|
|
11
14
|
showLine: boolean;
|
|
12
15
|
transition?: TransitionConfig;
|
|
13
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-renderer.d.ts","sourceRoot":"","sources":["../../../src/charts/area/area-renderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"area-renderer.d.ts","sourceRoot":"","sources":["../../../src/charts/area/area-renderer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoB,KAAK,SAAS,EAAgC,MAAM,wBAAwB,CAAC;AAGxG,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,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;IAC3B,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAyCD,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAwJpH;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,EAAE,EACvB,MAAM,EAAE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,EAC5B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GACpB,KAAK,EAAE,CAaT"}
|
|
@@ -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{
|
|
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{computeStyleRuns as a,hasStyledRuns as o}from"../../core/datum-style.js";import{uniqueId as s}from"../../core/ids.js";import{areaPath as c,linePath as l,monotonePath as u,stepPath as d}from"../../svg/path.js";var f=new WeakMap,p=new WeakMap;function buildLinePath(e,t){return t===`monotone`?u(e):t===`step`?d(e):l(e)}function applyAreaFill(n,r,i){let a=n.querySelector(`linearGradient`);if(i.fill===`gradient`){if(!a){let t=e(`defs`);a=e(`linearGradient`,{id:s(`prism-area-fill`),x1:0,x2:0,y1:0,y2:1}),a.append(e(`stop`,{class:`prism-area-stop-top`,offset:0}),e(`stop`,{class:`prism-area-stop-bottom`,offset:1})),t.appendChild(a),n.insertBefore(t,n.firstChild)}for(let e of a.querySelectorAll(`stop`))e.setAttribute(`stop-color`,i.color),e.style.stopColor=i.color;t(r,{fill:`url(#${a.id})`})}else a?.parentElement?.remove(),t(r,{fill:i.color});t(r,{class:`prism-area-fill prism-area-fill--${i.fill}`,stroke:`none`}),r.style.fillOpacity=i.fillOpacity===void 0?``:String(i.fillOpacity)}function renderArea(s,l,u,d){let m=r(d.transition,0),h=m.duration,g=n(m.easing),_=s.querySelector(`.prism-area-fill`);_||(_=e(`path`,{class:`prism-area-fill`}),s.appendChild(_)),applyAreaFill(s,_,d);let v=null,y=[],b=[],x=o(d.marks),S=d.marks??[];if(d.showLine){if(x){y=a(S,l.length);let n=[...s.querySelectorAll(`.prism-area-line`)];for(let e of n.slice(y.length))e.remove();b=y.map((t,r)=>{let i=n[r];if(i)return i;let a=e(`path`,{class:`prism-area-line`,fill:`none`});return s.appendChild(a),a});for(let[e,n]of y.entries())t(b[e],{opacity:n.opacity,stroke:d.color,"stroke-dasharray":n.dash,"stroke-width":2});v=null}else{let n=[...s.querySelectorAll(`.prism-area-line`)];for(let e of n.slice(1))e.remove();v=n[0]??null,v||(v=e(`path`,{class:`prism-area-line`,fill:`none`}),s.appendChild(v)),t(v,{opacity:void 0,stroke:d.color,"stroke-dasharray":void 0,"stroke-width":2})}}else for(let e of s.querySelectorAll(`.prism-area-line`))e.remove();let drawLine=e=>{if(d.showLine){if(x)for(let[n,r]of y.entries())t(b[n],{d:buildLinePath(e.slice(r.start,r.end+1),d.curve)});else v&&t(v,{d:buildLinePath(e,d.curve)})}};if(h===0){let e=l.map(e=>({x:e.x,y:u}));t(_,{d:c(l,e,d.curve)}),drawLine(l);return}if(f.get(s)?.(),!_.hasAttribute(`d`)){let e=l.map(e=>({x:e.x,y:u}));t(_,{d:c(l,e,d.curve)}),drawLine(l),p.set(s,l);return}let C=p.get(s)??l,w=l.map((e,t)=>C[t]??C[C.length-1]??l[t]),T=null;function frame(e){if(d.disposalSignal?.aborted){f.delete(s);return}T===null&&(T=e);let n=Math.min(1,(e-T)/h),r=g(n),a=l.map((e,t)=>({x:i(w[t].x,e.x,r),y:i(w[t].y,e.y,r)})),o=a.map(e=>({x:e.x,y:u}));if(t(_,{d:c(a,o,d.curve)}),drawLine(a),n<1){let e=requestAnimationFrame(frame);f.set(s,()=>cancelAnimationFrame(e))}else f.delete(s),p.set(s,l)}p.set(s,w);let E=requestAnimationFrame(frame);f.set(s,()=>cancelAnimationFrame(E))}function computeAreaPoints(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{computeAreaPoints,renderArea};
|
|
2
2
|
//# sourceMappingURL=area-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-renderer.js","names":[],"sources":["../../../src/charts/area/area-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { uniqueId } from '../../core/ids';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface AreaRenderOptions {\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 fill: 'gradient' | 'solid';\n /** Explicit opacity beats the `--prism-area-opacity` theme token. */\n fillOpacity?: number;\n showLine: boolean;\n transition?: TransitionConfig;\n}\n\nconst activeAreaAnimations = new WeakMap<SVGGElement, () => void>();\nconst previousPoints = new WeakMap<SVGGElement, Point[]>();\n\nfunction buildLinePath(pts: Point[], curve: AreaRenderOptions['curve']): string {\n return curve === 'monotone' ? monotonePath(pts) : curve === 'step' ? stepPath(pts) : linePath(pts);\n}\n\n/** A vertical gradient fading to transparent at the baseline, or a flat fill. */\nfunction applyAreaFill(parent: SVGGElement, fill: SVGPathElement, options: AreaRenderOptions): void {\n let gradient = parent.querySelector<SVGLinearGradientElement>('linearGradient');\n\n if (options.fill === 'gradient') {\n if (!gradient) {\n const defs = createSvgElement('defs');\n\n gradient = createSvgElement('linearGradient', { id: uniqueId('prism-area-fill'), x1: 0, x2: 0, y1: 0, y2: 1 });\n gradient.append(\n createSvgElement('stop', { class: 'prism-area-stop-top', offset: 0 }),\n createSvgElement('stop', { class: 'prism-area-stop-bottom', offset: 1 }),\n );\n defs.appendChild(gradient);\n parent.insertBefore(defs, parent.firstChild);\n }\n\n for (const stop of gradient.querySelectorAll('stop')) {\n stop.setAttribute('stop-color', options.color);\n stop.style.stopColor = options.color;\n }\n\n setAttributes(fill, { fill: `url(#${gradient.id})` });\n } else {\n gradient?.parentElement?.remove();\n setAttributes(fill, { fill: options.color });\n }\n\n setAttributes(fill, { class: `prism-area-fill prism-area-fill--${options.fill}`, stroke: 'none' });\n fill.style.fillOpacity = options.fillOpacity === undefined ? '' : String(options.fillOpacity);\n}\n\nexport function renderArea(parent: SVGGElement, points: Point[], baselineY: number, options: AreaRenderOptions): void {\n const motion = resolveMotion(options.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n let fill = parent.querySelector<SVGPathElement>('.prism-area-fill');\n\n if (!fill) {\n fill = createSvgElement('path', { class: 'prism-area-fill' });\n parent.appendChild(fill);\n }\n\n applyAreaFill(parent, fill, options);\n\n let line: SVGPathElement | null = null;\n\n if (options.showLine) {\n line = parent.querySelector<SVGPathElement>('.prism-area-line');\n\n if (!line) {\n line = createSvgElement('path', { class: 'prism-area-line', fill: 'none' });\n parent.appendChild(line);\n }\n\n setAttributes(line, { stroke: options.color, 'stroke-width': 2 });\n } else {\n parent.querySelector('.prism-area-line')?.remove();\n }\n\n if (dur === 0) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n if (line) setAttributes(line, { d: buildLinePath(points, options.curve) });\n\n return;\n }\n\n activeAreaAnimations.get(parent)?.();\n\n const hasExisting = fill.hasAttribute('d');\n\n if (!hasExisting) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n if (line) setAttributes(line, { d: buildLinePath(points, options.curve) });\n\n previousPoints.set(parent, points);\n\n return;\n }\n\n const rawFrom = previousPoints.get(parent) ?? points;\n const fromPoints: Point[] = points.map((_, i) => rawFrom[i] ?? rawFrom[rawFrom.length - 1] ?? points[i]);\n\n let startTime: number | null = null;\n\n function frame(ts: number) {\n if (options.disposalSignal?.aborted) {\n activeAreaAnimations.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 x: tweenNumber(fromPoints[i].x, to.x, e),\n y: tweenNumber(fromPoints[i].y, to.y, e),\n }));\n const interpolatedBottom = interpolated.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill!, { d: areaPath(interpolated, interpolatedBottom, options.curve) });\n\n if (line) setAttributes(line, { d: buildLinePath(interpolated, options.curve) });\n\n if (t < 1) {\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n } else {\n activeAreaAnimations.delete(parent);\n previousPoints.set(parent, points);\n }\n }\n\n previousPoints.set(parent, fromPoints);\n\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n}\n\nexport function computeAreaPoints(\n data: ContinuousDatum[],\n xScale: Scale<Date | number>,\n yScale: Scale<number>,\n): Point[] {\n if (data.some((d) => d.key == null)) {\n warn(\n 'computeAreaPoints: 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('computeAreaPoints: 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
|
+
{"version":3,"file":"area-renderer.js","names":[],"sources":["../../../src/charts/area/area-renderer.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { tweenNumber } from '../../animation/tween';\nimport { computeStyleRuns, type DatumMark, hasStyledRuns, type StyleRun } from '../../core/datum-style';\nimport { uniqueId } from '../../core/ids';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport type { Point } from '../../svg/path';\nimport { areaPath, linePath, monotonePath, stepPath } from '../../svg/path';\nimport type { ContinuousDatum, Scale, TransitionConfig } from '../../types';\n\nexport interface AreaRenderOptions {\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 fill: 'gradient' | 'solid';\n /** Explicit opacity beats the `--prism-area-opacity` theme token. */\n fillOpacity?: number;\n /** Per-datum presentation parallel to `points`; styled runs split the top line into subpaths. */\n marks?: readonly DatumMark[];\n showLine: boolean;\n transition?: TransitionConfig;\n}\n\nconst activeAreaAnimations = new WeakMap<SVGGElement, () => void>();\nconst previousPoints = new WeakMap<SVGGElement, Point[]>();\n\nfunction buildLinePath(pts: Point[], curve: AreaRenderOptions['curve']): string {\n return curve === 'monotone' ? monotonePath(pts) : curve === 'step' ? stepPath(pts) : linePath(pts);\n}\n\n/** A vertical gradient fading to transparent at the baseline, or a flat fill. */\nfunction applyAreaFill(parent: SVGGElement, fill: SVGPathElement, options: AreaRenderOptions): void {\n let gradient = parent.querySelector<SVGLinearGradientElement>('linearGradient');\n\n if (options.fill === 'gradient') {\n if (!gradient) {\n const defs = createSvgElement('defs');\n\n gradient = createSvgElement('linearGradient', { id: uniqueId('prism-area-fill'), x1: 0, x2: 0, y1: 0, y2: 1 });\n gradient.append(\n createSvgElement('stop', { class: 'prism-area-stop-top', offset: 0 }),\n createSvgElement('stop', { class: 'prism-area-stop-bottom', offset: 1 }),\n );\n defs.appendChild(gradient);\n parent.insertBefore(defs, parent.firstChild);\n }\n\n for (const stop of gradient.querySelectorAll('stop')) {\n stop.setAttribute('stop-color', options.color);\n stop.style.stopColor = options.color;\n }\n\n setAttributes(fill, { fill: `url(#${gradient.id})` });\n } else {\n gradient?.parentElement?.remove();\n setAttributes(fill, { fill: options.color });\n }\n\n setAttributes(fill, { class: `prism-area-fill prism-area-fill--${options.fill}`, stroke: 'none' });\n fill.style.fillOpacity = options.fillOpacity === undefined ? '' : String(options.fillOpacity);\n}\n\nexport function renderArea(parent: SVGGElement, points: Point[], baselineY: number, options: AreaRenderOptions): void {\n const motion = resolveMotion(options.transition, 0);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n let fill = parent.querySelector<SVGPathElement>('.prism-area-fill');\n\n if (!fill) {\n fill = createSvgElement('path', { class: 'prism-area-fill' });\n parent.appendChild(fill);\n }\n\n applyAreaFill(parent, fill, options);\n\n let line: SVGPathElement | null = null;\n let runs: readonly StyleRun[] = [];\n let lines: SVGPathElement[] = [];\n const styled = hasStyledRuns(options.marks);\n const marks = options.marks ?? [];\n\n if (options.showLine) {\n if (styled) {\n runs = computeStyleRuns(marks, points.length);\n\n const existing = [...parent.querySelectorAll<SVGPathElement>('.prism-area-line')];\n\n for (const extra of existing.slice(runs.length)) extra.remove();\n\n lines = runs.map((_, r) => {\n const reuse = existing[r];\n\n if (reuse) return reuse;\n\n const created = createSvgElement('path', { class: 'prism-area-line', fill: 'none' });\n\n parent.appendChild(created);\n\n return created;\n });\n\n for (const [r, run] of runs.entries()) {\n setAttributes(lines[r], {\n opacity: run.opacity,\n stroke: options.color,\n 'stroke-dasharray': run.dash,\n 'stroke-width': 2,\n });\n }\n\n line = null;\n } else {\n const existing = [...parent.querySelectorAll<SVGPathElement>('.prism-area-line')];\n\n for (const stale of existing.slice(1)) stale.remove();\n\n line = existing[0] ?? null;\n\n if (!line) {\n line = createSvgElement('path', { class: 'prism-area-line', fill: 'none' });\n parent.appendChild(line);\n }\n\n setAttributes(line, {\n opacity: undefined,\n stroke: options.color,\n 'stroke-dasharray': undefined,\n 'stroke-width': 2,\n });\n }\n } else {\n for (const stale of parent.querySelectorAll('.prism-area-line')) stale.remove();\n }\n\n const drawLine = (pts: Point[]): void => {\n if (!options.showLine) return;\n\n if (styled) {\n for (const [r, run] of runs.entries()) {\n setAttributes(lines[r], { d: buildLinePath(pts.slice(run.start, run.end + 1), options.curve) });\n }\n } else if (line) {\n setAttributes(line, { d: buildLinePath(pts, options.curve) });\n }\n };\n\n if (dur === 0) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n drawLine(points);\n\n return;\n }\n\n activeAreaAnimations.get(parent)?.();\n\n const hasExisting = fill.hasAttribute('d');\n\n if (!hasExisting) {\n const bottomPoints = points.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill, { d: areaPath(points, bottomPoints, options.curve) });\n\n drawLine(points);\n\n previousPoints.set(parent, points);\n\n return;\n }\n\n const rawFrom = previousPoints.get(parent) ?? points;\n const fromPoints: Point[] = points.map((_, i) => rawFrom[i] ?? rawFrom[rawFrom.length - 1] ?? points[i]);\n\n let startTime: number | null = null;\n\n function frame(ts: number) {\n if (options.disposalSignal?.aborted) {\n activeAreaAnimations.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 x: tweenNumber(fromPoints[i].x, to.x, e),\n y: tweenNumber(fromPoints[i].y, to.y, e),\n }));\n const interpolatedBottom = interpolated.map((p) => ({ x: p.x, y: baselineY }));\n\n setAttributes(fill!, { d: areaPath(interpolated, interpolatedBottom, options.curve) });\n\n drawLine(interpolated);\n\n if (t < 1) {\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n } else {\n activeAreaAnimations.delete(parent);\n previousPoints.set(parent, points);\n }\n }\n\n previousPoints.set(parent, fromPoints);\n\n const id = requestAnimationFrame(frame);\n\n activeAreaAnimations.set(parent, () => cancelAnimationFrame(id));\n}\n\nexport function computeAreaPoints(\n data: ContinuousDatum[],\n xScale: Scale<Date | number>,\n yScale: Scale<number>,\n): Point[] {\n if (data.some((d) => d.key == null)) {\n warn(\n 'computeAreaPoints: 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('computeAreaPoints: 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
|
-
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../axes/axis.cjs"),n=require("../../axes/grid.cjs"),r=require("../../scales/linear.cjs"),i=require("../../interaction/announcer.cjs"),a=require("../../interaction/tooltip.cjs"),o=require("../../core/layout.cjs"),s=require("../../core/chart-scaffold.cjs"),c=require("../../core/cartesian-model.cjs"),
|
|
1
|
+
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../axes/axis.cjs"),n=require("../../axes/grid.cjs"),r=require("../../scales/linear.cjs"),i=require("../../interaction/announcer.cjs"),a=require("../../interaction/tooltip.cjs"),o=require("../../core/layout.cjs"),s=require("../../core/chart-scaffold.cjs"),c=require("../../core/series-id.cjs"),l=require("../../core/cartesian-model.cjs"),u=require("../../interaction/events.cjs"),d=require("../../theme/index.cjs"),f=require("../../scales/band.cjs"),p=require("./bar-hit-test.cjs"),m=require("./bar-renderer.cjs");function variantFlags(e){return{horizontal:e===`grouped-horizontal`||e===`stacked-horizontal`,stacked:e===`stacked`||e===`stacked-horizontal`}}function createBarChart(h,g){let _=g.series,v=null;return s.createChartScaffold(h,g,h=>{let{groups:y,legend:b,tooltip:x}=h,S=h.dimensions,C=o.chartArea(S.width,S.height,S.margin),w=_.map(e=>e.data),T=l.normalizeCartesianSeries(_,w),E=T.domain,D=T.series.map(({byKey:e})=>E.map(t=>e.get(t))),categoryAxis=e=>{if(e)return{...e,tickFormat:t=>{let n=String(t),r=T.labels.get(n)??t;return e.tickFormat?e.tickFormat(r):String(r)}}};if(E.length===0){s.clearCartesianDom(y,b,x),v?.remove(),v=null;return}let{horizontal:O,stacked:k}=variantFlags(g.variant??`grouped`),A,j;if(k){D.some(e=>e.some(e=>(e?.value??0)<0));let e=E.map((e,t)=>D.reduce((e,n)=>e+Math.max(0,n[t]?.value??0),0));A=Math.max(...e),j=0}else{let e=D.flatMap(e=>e.flatMap(e=>e?[e.value]:[]));A=Math.max(...e),j=Math.min(0,...e)}let M=O?f.bandScale({domain:E,range:[0,C.height]}):f.bandScale({domain:E,range:[0,C.width]}),N=O?r.linearScale({domain:[j,A],range:[0,C.width]}):r.linearScale({domain:[j,A],range:[C.height,0]}),P=[],F=Object.create(null);for(let e of E)F[e]=0;let I={bandCenter:e=>M.map(e)+M.bandwidth()/2,bandwidth:M.bandwidth(),baselinePx:N.map(0),horizontal:O,stacked:k,stackedTops:P,valueScale:N};if(O){g.xAxis?.grid&&n.renderGrid(y.grid,N,g.xAxis.grid,C.height,`vertical`,t.resolveTickCount(g.xAxis,C.width,`bottom`));let e=categoryAxis(g.yAxis);e&&(t.positionAxis(y.yAxis,e.position??`left`,C.width,C.height),t.renderAxis(y.yAxis,M,e,C.height,`left`)),g.xAxis&&(t.positionAxis(y.xAxis,g.xAxis.position??`bottom`,C.width,C.height),t.renderAxis(y.xAxis,N,g.xAxis,C.width,`bottom`))}else{g.yAxis?.grid&&n.renderGrid(y.grid,N,g.yAxis.grid,C.width,`horizontal`,t.resolveTickCount(g.yAxis,C.height,`left`));let e=categoryAxis(g.xAxis);e&&(t.positionAxis(y.xAxis,e.position??`bottom`,C.width,C.height),t.renderAxis(y.xAxis,M,e,C.width,`bottom`)),g.yAxis&&(t.positionAxis(y.yAxis,g.yAxis.position??`left`,C.width,C.height),t.renderAxis(y.yAxis,N,g.yAxis,C.height,`left`))}let L=k?0:Number.parseFloat(getComputedStyle(h.svg).getPropertyValue(`--prism-bar-radius`))||0;for(;y.series.children.length>_.length;){let e=y.series.lastElementChild;e&&y.series.removeChild(e)}for(let t=0;t<_.length;t++){let n=_[t],r=y.series.children[t];r||(r=e.createSvgElement(`g`,{class:`prism-bar-series`}),y.series.appendChild(r)),r.setAttribute(`data-series-id`,c.seriesDomId(n,t));let i=E.map((e,n)=>{let r=D[t]?.[n];if(k){let t=F[e]??0,n=t+Math.max(0,r?.value??0);return F[e]=n,{base:t,dash:r?.dash,key:e,opacity:r?.opacity,present:r!==void 0,y:n}}return{base:0,dash:r?.dash,key:e,opacity:r?.opacity,present:r!==void 0,y:r?.value??0}});P[t]=i.map(e=>e.y);let a=k?i.map(e=>N.map(e.base)):void 0;m.renderBars(r,i,M,N,I.baselinePx,{baselineYs:a,borderRadius:n.borderRadius??L,color:d.seriesColor(t,n.color),disposalSignal:h.disposalSignal,horizontal:O,seriesCount:_.length,seriesIndex:t,stacked:k,transition:g.transition})}b?.update(_.map((e,t)=>({color:d.seriesColor(t,e.color),name:e.name}))),x?.hide(),y.series.classList.toggle(`prism-bars-stacked`,k),(!v||!h.chartArea.contains(v))&&(v=e.createSvgElement(`rect`,{"aria-hidden":`true`,class:`prism-bar-band`,"pointer-events":`none`}),h.chartArea.insertBefore(v,y.series)),v.style.display=`none`;let R=_.map((e,t)=>d.seriesColor(t,e.color)),labelOf=e=>String(T.labels.get(E[e])??E[e]),z=-1,valuesAt=e=>_.map((t,n)=>({datum:D[n]?.[e],series:t})),eventAt=(e,t,n)=>{let r=valuesAt(e),i=r[t]?.datum?t:r.findIndex(e=>e.datum),a=r[i]?.datum;return a?{datum:a,originalEvent:n,series:_[i],values:r}:null},setActive=t=>{z=t,y.series.classList.toggle(`prism-bars-focused`,t>=0);for(let e of y.series.children)for(let[n,r]of[...e.children].entries())r.classList.toggle(`prism-bar--active`,n===t);if(!v||(v.style.display=t<0?`none`:``,t<0))return;let n=I.bandCenter(E[t])-M.bandwidth()/2-M.gap()/2,r=M.bandwidth()+M.gap(),i=o.chartArea(h.dimensions.width,h.dimensions.height,h.dimensions.margin);e.setAttributes(v,O?{height:r,width:i.width,x:0,y:n}:{height:i.height,width:r,x:n,y:0})},activate=(e,t,n)=>{let r=eventAt(e,t,n);if(!r)return;setActive(e);let o=r.values??[],s=i.describeValues(labelOf(e),o);if(x){let t=o.map((t,n)=>k?P[n]?.[e]??0:Math.max(0,t.datum?.value??0)),n=N.map(Math.max(...t)),i=I.bandCenter(E[e]),{margin:c}=h.dimensions,l=o.flatMap((e,t)=>e.datum?[{color:R[t],name:e.series.name,value:String(e.datum.value)}]:[]);x.show((O?n:i)+c.left,(O?i:n)+c.top,r.datum,r.series,a.comparisonContent(h.svg.ownerDocument,labelOf(e),l,s))}else h.announcer.announce(s);g.onHover?.(r)},deactivate=()=>{setActive(-1),x?.hide(),h.announcer.clear(),g.onHover?.(null)},hit=e=>{let t=h.dimensions,n=u.getMousePosition(h.svg,e,t.margin.left,t.margin.top),r=o.chartArea(t.width,t.height,t.margin);if(n.x<0||n.x>r.width||n.y<0||n.y>r.height)return null;let i=p.findCatIdx(O?n.y:n.x,E,I);return i===-1?null:{catIdx:i,seriesIdx:p.findSeriesIdx(n,i,E,I,_.length)}},onMouseMove=e=>{let t=hit(e);t?activate(t.catIdx,t.seriesIdx,e):z>=0&&deactivate()},onClick=e=>{let t=g.onClick&&hit(e),n=t&&eventAt(t.catIdx,t.seriesIdx,e);n&&g.onClick?.(n)},onKeyDown=e=>{let t=E.length-1,n=z<0?t:Math.max(0,z-1),r=z<0?0:Math.min(t,z+1),i={ArrowDown:r,ArrowLeft:n,ArrowRight:r,ArrowUp:n,End:t,Home:0};if(e.key in i)e.preventDefault(),activate(i[e.key],0,e);else if((e.key===`Enter`||e.key===` `)&&z>=0&&g.onClick){e.preventDefault();let t=eventAt(z,0,e);t&&g.onClick(t)}else e.key===`Escape`&&deactivate()};return{onClick,onKeyDown,onMouseLeave:deactivate,onMouseMove}},e=>{_=e})}exports.createBarChart=createBarChart;
|
|
2
2
|
//# sourceMappingURL=bar-chart.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bar-chart.cjs","names":[],"sources":["../../../src/charts/bar/bar-chart.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { positionAxis, renderAxis, resolveTickCount } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { normalizeCartesianSeries } from '../../core/cartesian-model';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { describeValues } from '../../interaction/announcer';\nimport { getMousePosition } from '../../interaction/events';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { bandScale } from '../../scales/band';\nimport { linearScale } from '../../scales/linear';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type { BarChartConfig, BarSeriesConfig, BarVariant, ChartEvent, ChartHandle, SeriesValue } from '../../types';\nimport { findCatIdx, findSeriesIdx } from './bar-hit-test';\nimport { renderBars } from './bar-renderer';\nimport type { BarScaleContext } from './bar-scale-context';\n\nfunction variantFlags(variant: BarVariant): { horizontal: boolean; stacked: boolean } {\n return {\n horizontal: variant === 'grouped-horizontal' || variant === 'stacked-horizontal',\n stacked: variant === 'stacked' || variant === 'stacked-horizontal',\n };\n}\n\n// ─── Chart ────────────────────────────────────────────────────────────────────\n\nexport function createBarChart(container: HTMLElement, config: BarChartConfig): ChartHandle<BarSeriesConfig[]> {\n let seriesList = config.series;\n let band: SVGRectElement | null = null;\n\n return createChartScaffold(\n container,\n config,\n (ctx) => {\n const { groups, legend, tooltip } = ctx;\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const sourceData = seriesList.map((series) => series.data);\n const model = normalizeCartesianSeries(seriesList, sourceData);\n const categories = model.domain;\n const allData = model.series.map(({ byKey }) => categories.map((key) => byKey.get(key)));\n const categoryAxis = (axis: BarChartConfig['xAxis'] | BarChartConfig['yAxis']) => {\n if (!axis) return undefined;\n\n return {\n ...axis,\n tickFormat: (value: Date | number | string) => {\n const key = String(value);\n const label = model.labels.get(key) ?? value;\n\n return axis.tickFormat ? axis.tickFormat(label) : String(label);\n },\n };\n };\n\n if (categories.length === 0) {\n clearCartesianDom(groups, legend, tooltip);\n band?.remove();\n band = null;\n\n return;\n }\n\n const { horizontal, stacked } = variantFlags(config.variant ?? 'grouped');\n\n // Value domain\n let vMax: number;\n let vMin: number;\n\n if (stacked) {\n if (allData.some((seriesData) => seriesData.some((datum) => (datum?.value ?? 0) < 0))) {\n warn(\n 'createBarChart: negative values in a stacked/stacked-horizontal series are clamped to 0: stacking mixed-sign data is not supported.',\n );\n }\n\n const sums = categories.map((_, categoryIndex) =>\n allData.reduce((sum, seriesData) => sum + Math.max(0, seriesData[categoryIndex]?.value ?? 0), 0),\n );\n\n vMax = Math.max(...sums);\n vMin = 0;\n } else {\n const allY = allData.flatMap((seriesData) => seriesData.flatMap((datum) => (datum ? [datum.value] : [])));\n\n vMax = Math.max(...allY);\n vMin = Math.min(0, ...allY);\n }\n\n // Build uniform scale context\n const catScale = horizontal\n ? bandScale({ domain: categories, range: [0, area.height] })\n : bandScale({ domain: categories, range: [0, area.width] });\n\n const valScale = horizontal\n ? linearScale({ domain: [vMin, vMax], range: [0, area.width] })\n : linearScale({ domain: [vMin, vMax], range: [area.height, 0] });\n\n const stackedTops: number[][] = [];\n const stackTops = Object.create(null) as Record<string, number>;\n\n for (const cat of categories) stackTops[cat] = 0;\n\n const sc: BarScaleContext = {\n bandCenter: (cat) => catScale.map(cat) + catScale.bandwidth() / 2,\n bandwidth: catScale.bandwidth(),\n baselinePx: valScale.map(0),\n horizontal,\n stacked,\n stackedTops,\n valueScale: valScale,\n };\n\n // Axes & grid\n if (horizontal) {\n if (config.xAxis?.grid) {\n renderGrid(\n groups.grid,\n valScale,\n config.xAxis.grid,\n area.height,\n 'vertical',\n resolveTickCount(config.xAxis, area.width, 'bottom'),\n );\n }\n\n const yAxis = categoryAxis(config.yAxis);\n\n if (yAxis) {\n positionAxis(groups.yAxis, yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, catScale, yAxis, area.height, 'left');\n }\n\n if (config.xAxis) {\n positionAxis(groups.xAxis, config.xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, valScale, config.xAxis, area.width, 'bottom');\n }\n } else {\n if (config.yAxis?.grid) {\n renderGrid(\n groups.grid,\n valScale,\n config.yAxis.grid,\n area.width,\n 'horizontal',\n resolveTickCount(config.yAxis, area.height, 'left'),\n );\n }\n\n const xAxis = categoryAxis(config.xAxis);\n\n if (xAxis) {\n positionAxis(groups.xAxis, xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, catScale, xAxis, area.width, 'bottom');\n }\n\n if (config.yAxis) {\n positionAxis(groups.yAxis, config.yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, valScale, config.yAxis, area.height, 'left');\n }\n }\n\n // Series groups\n // Stacked segments stay square so they join cleanly.\n const themeRadius = stacked\n ? 0\n : Number.parseFloat(getComputedStyle(ctx.svg).getPropertyValue('--prism-bar-radius')) || 0;\n\n while (groups.series.children.length > seriesList.length) {\n const last = groups.series.lastElementChild;\n\n if (last) groups.series.removeChild(last);\n }\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-bar-series' });\n groups.series.appendChild(group);\n }\n\n const barData = categories.map((key, categoryIndex) => {\n const datum = allData[i]?.[categoryIndex];\n\n if (stacked) {\n const base = stackTops[key] ?? 0;\n const top = base + Math.max(0, datum?.value ?? 0);\n\n stackTops[key] = top;\n\n return { base, key, present: datum !== undefined, y: top };\n }\n\n return { base: 0, key, present: datum !== undefined, y: datum?.value ?? 0 };\n });\n\n stackedTops[i] = barData.map((d) => d.y);\n\n const baselineYs = stacked ? barData.map((d) => valScale.map(d.base)) : undefined;\n\n renderBars(group, barData, catScale, valScale, sc.baselinePx, {\n baselineYs,\n borderRadius: series.borderRadius ?? themeRadius,\n color: seriesColor(i, series.color),\n disposalSignal: ctx.disposalSignal,\n horizontal,\n seriesCount: seriesList.length,\n seriesIndex: i,\n stacked,\n transition: config.transition,\n });\n }\n\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n tooltip?.hide();\n groups.series.classList.toggle('prism-bars-stacked', stacked);\n\n if (!band || !ctx.chartArea.contains(band)) {\n band = createSvgElement('rect', { 'aria-hidden': 'true', class: 'prism-bar-band', 'pointer-events': 'none' });\n ctx.chartArea.insertBefore(band, groups.series);\n }\n\n band.style.display = 'none';\n\n // ─── Event handlers (close over render-derived state) ─────────────────────\n\n const colors = seriesList.map((s, i) => seriesColor(i, s.color));\n const labelOf = (catIdx: number): string => String(model.labels.get(categories[catIdx]) ?? categories[catIdx]);\n let activeCat = -1;\n\n const valuesAt = (catIdx: number): SeriesValue[] =>\n seriesList.map((series, si) => ({ datum: allData[si]?.[catIdx], series }));\n\n const eventAt = (catIdx: number, seriesIdx: number, originalEvent: Event): ChartEvent | null => {\n const values = valuesAt(catIdx);\n const preferred = values[seriesIdx]?.datum ? seriesIdx : values.findIndex((v) => v.datum);\n const datum = values[preferred]?.datum;\n\n return datum ? { datum, originalEvent, series: seriesList[preferred], values } : null;\n };\n\n const setActive = (catIdx: number): void => {\n activeCat = catIdx;\n groups.series.classList.toggle('prism-bars-focused', catIdx >= 0);\n\n for (const group of groups.series.children) {\n for (const [i, rect] of [...group.children].entries())\n rect.classList.toggle('prism-bar--active', i === catIdx);\n }\n\n if (!band) return;\n\n band.style.display = catIdx < 0 ? 'none' : '';\n\n if (catIdx < 0) return;\n\n const start = sc.bandCenter(categories[catIdx]) - catScale.bandwidth() / 2 - catScale.gap() / 2;\n const size = catScale.bandwidth() + catScale.gap();\n const a = chartArea(ctx.dimensions.width, ctx.dimensions.height, ctx.dimensions.margin);\n\n setAttributes(\n band,\n horizontal\n ? { height: size, width: a.width, x: 0, y: start }\n : { height: a.height, width: size, x: start, y: 0 },\n );\n };\n\n const activate = (catIdx: number, seriesIdx: number, originalEvent: Event): void => {\n const event = eventAt(catIdx, seriesIdx, originalEvent);\n\n if (!event) return;\n\n setActive(catIdx);\n\n const values = event.values ?? [];\n const spoken = describeValues(labelOf(catIdx), values);\n\n if (tooltip) {\n const tops = values.map((v, si) =>\n stacked ? (stackedTops[si]?.[catIdx] ?? 0) : Math.max(0, v.datum?.value ?? 0),\n );\n const valuePx = valScale.map(Math.max(...tops));\n const bandCenterPx = sc.bandCenter(categories[catIdx]);\n const { margin } = ctx.dimensions;\n const rows = values.flatMap((v, si) =>\n v.datum ? [{ color: colors[si], name: v.series.name, value: String(v.datum.value) }] : [],\n );\n\n tooltip.show(\n (horizontal ? valuePx : bandCenterPx) + margin.left,\n (horizontal ? bandCenterPx : valuePx) + margin.top,\n event.datum,\n event.series,\n comparisonContent(ctx.svg.ownerDocument, labelOf(catIdx), rows, spoken),\n );\n } else {\n ctx.announcer.announce(spoken);\n }\n\n config.onHover?.(event);\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null);\n };\n\n const hit = (event: MouseEvent): { catIdx: number; seriesIdx: number } | null => {\n const d = ctx.dimensions;\n const pos = getMousePosition(ctx.svg, event, d.margin.left, d.margin.top);\n const a = chartArea(d.width, d.height, d.margin);\n\n if (pos.x < 0 || pos.x > a.width || pos.y < 0 || pos.y > a.height) return null;\n\n const catIdx = findCatIdx(horizontal ? pos.y : pos.x, categories, sc);\n\n return catIdx === -1\n ? null\n : { catIdx, seriesIdx: findSeriesIdx(pos, catIdx, categories, sc, seriesList.length) };\n };\n\n const onMouseMove = (event: MouseEvent) => {\n const target = hit(event);\n\n if (target) activate(target.catIdx, target.seriesIdx, event);\n else if (activeCat >= 0) deactivate();\n };\n\n const onClick = (event: MouseEvent) => {\n const target = config.onClick && hit(event);\n const chartEvent = target && eventAt(target.catIdx, target.seriesIdx, event);\n\n if (chartEvent) config.onClick?.(chartEvent);\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n const last = categories.length - 1;\n const prev = activeCat < 0 ? last : Math.max(0, activeCat - 1);\n const next = activeCat < 0 ? 0 : Math.min(last, activeCat + 1);\n const target: Record<string, number> = {\n ArrowDown: next,\n ArrowLeft: prev,\n ArrowRight: next,\n ArrowUp: prev,\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n activate(target[event.key], 0, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeCat >= 0 && config.onClick) {\n event.preventDefault();\n\n const chartEvent = eventAt(activeCat, 0, event);\n\n if (chartEvent) config.onClick(chartEvent);\n } else if (event.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bar-chart.cjs","names":[],"sources":["../../../src/charts/bar/bar-chart.ts"],"sourcesContent":["import { warn } from '../../_dev';\nimport { positionAxis, renderAxis, resolveTickCount } from '../../axes/axis';\nimport { renderGrid } from '../../axes/grid';\nimport { normalizeCartesianSeries } from '../../core/cartesian-model';\nimport { clearCartesianDom, createChartScaffold } from '../../core/chart-scaffold';\nimport { chartArea } from '../../core/layout';\nimport { seriesDomId } from '../../core/series-id';\nimport { describeValues } from '../../interaction/announcer';\nimport { getMousePosition } from '../../interaction/events';\nimport { comparisonContent } from '../../interaction/tooltip';\nimport { bandScale } from '../../scales/band';\nimport { linearScale } from '../../scales/linear';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { seriesColor } from '../../theme';\nimport type { BarChartConfig, BarSeriesConfig, BarVariant, ChartEvent, ChartHandle, SeriesValue } from '../../types';\nimport { findCatIdx, findSeriesIdx } from './bar-hit-test';\nimport { renderBars } from './bar-renderer';\nimport type { BarScaleContext } from './bar-scale-context';\n\nfunction variantFlags(variant: BarVariant): { horizontal: boolean; stacked: boolean } {\n return {\n horizontal: variant === 'grouped-horizontal' || variant === 'stacked-horizontal',\n stacked: variant === 'stacked' || variant === 'stacked-horizontal',\n };\n}\n\n// ─── Chart ────────────────────────────────────────────────────────────────────\n\nexport function createBarChart(container: HTMLElement, config: BarChartConfig): ChartHandle<BarSeriesConfig[]> {\n let seriesList = config.series;\n let band: SVGRectElement | null = null;\n\n return createChartScaffold(\n container,\n config,\n (ctx) => {\n const { groups, legend, tooltip } = ctx;\n const dims = ctx.dimensions;\n const area = chartArea(dims.width, dims.height, dims.margin);\n const sourceData = seriesList.map((series) => series.data);\n const model = normalizeCartesianSeries(seriesList, sourceData);\n const categories = model.domain;\n const allData = model.series.map(({ byKey }) => categories.map((key) => byKey.get(key)));\n const categoryAxis = (axis: BarChartConfig['xAxis'] | BarChartConfig['yAxis']) => {\n if (!axis) return undefined;\n\n return {\n ...axis,\n tickFormat: (value: Date | number | string) => {\n const key = String(value);\n const label = model.labels.get(key) ?? value;\n\n return axis.tickFormat ? axis.tickFormat(label) : String(label);\n },\n };\n };\n\n if (categories.length === 0) {\n clearCartesianDom(groups, legend, tooltip);\n band?.remove();\n band = null;\n\n return;\n }\n\n const { horizontal, stacked } = variantFlags(config.variant ?? 'grouped');\n\n // Value domain\n let vMax: number;\n let vMin: number;\n\n if (stacked) {\n if (allData.some((seriesData) => seriesData.some((datum) => (datum?.value ?? 0) < 0))) {\n warn(\n 'createBarChart: negative values in a stacked/stacked-horizontal series are clamped to 0: stacking mixed-sign data is not supported.',\n );\n }\n\n const sums = categories.map((_, categoryIndex) =>\n allData.reduce((sum, seriesData) => sum + Math.max(0, seriesData[categoryIndex]?.value ?? 0), 0),\n );\n\n vMax = Math.max(...sums);\n vMin = 0;\n } else {\n const allY = allData.flatMap((seriesData) => seriesData.flatMap((datum) => (datum ? [datum.value] : [])));\n\n vMax = Math.max(...allY);\n vMin = Math.min(0, ...allY);\n }\n\n // Build uniform scale context\n const catScale = horizontal\n ? bandScale({ domain: categories, range: [0, area.height] })\n : bandScale({ domain: categories, range: [0, area.width] });\n\n const valScale = horizontal\n ? linearScale({ domain: [vMin, vMax], range: [0, area.width] })\n : linearScale({ domain: [vMin, vMax], range: [area.height, 0] });\n\n const stackedTops: number[][] = [];\n const stackTops = Object.create(null) as Record<string, number>;\n\n for (const cat of categories) stackTops[cat] = 0;\n\n const sc: BarScaleContext = {\n bandCenter: (cat) => catScale.map(cat) + catScale.bandwidth() / 2,\n bandwidth: catScale.bandwidth(),\n baselinePx: valScale.map(0),\n horizontal,\n stacked,\n stackedTops,\n valueScale: valScale,\n };\n\n // Axes & grid\n if (horizontal) {\n if (config.xAxis?.grid) {\n renderGrid(\n groups.grid,\n valScale,\n config.xAxis.grid,\n area.height,\n 'vertical',\n resolveTickCount(config.xAxis, area.width, 'bottom'),\n );\n }\n\n const yAxis = categoryAxis(config.yAxis);\n\n if (yAxis) {\n positionAxis(groups.yAxis, yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, catScale, yAxis, area.height, 'left');\n }\n\n if (config.xAxis) {\n positionAxis(groups.xAxis, config.xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, valScale, config.xAxis, area.width, 'bottom');\n }\n } else {\n if (config.yAxis?.grid) {\n renderGrid(\n groups.grid,\n valScale,\n config.yAxis.grid,\n area.width,\n 'horizontal',\n resolveTickCount(config.yAxis, area.height, 'left'),\n );\n }\n\n const xAxis = categoryAxis(config.xAxis);\n\n if (xAxis) {\n positionAxis(groups.xAxis, xAxis.position ?? 'bottom', area.width, area.height);\n renderAxis(groups.xAxis, catScale, xAxis, area.width, 'bottom');\n }\n\n if (config.yAxis) {\n positionAxis(groups.yAxis, config.yAxis.position ?? 'left', area.width, area.height);\n renderAxis(groups.yAxis, valScale, config.yAxis, area.height, 'left');\n }\n }\n\n // Series groups\n // Stacked segments stay square so they join cleanly.\n const themeRadius = stacked\n ? 0\n : Number.parseFloat(getComputedStyle(ctx.svg).getPropertyValue('--prism-bar-radius')) || 0;\n\n while (groups.series.children.length > seriesList.length) {\n const last = groups.series.lastElementChild;\n\n if (last) groups.series.removeChild(last);\n }\n\n for (let i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n let group = groups.series.children[i] as SVGGElement | undefined;\n\n if (!group) {\n group = createSvgElement('g', { class: 'prism-bar-series' });\n groups.series.appendChild(group);\n }\n\n group.setAttribute('data-series-id', seriesDomId(series, i));\n\n const barData = categories.map((key, categoryIndex) => {\n const datum = allData[i]?.[categoryIndex];\n\n if (stacked) {\n const base = stackTops[key] ?? 0;\n const top = base + Math.max(0, datum?.value ?? 0);\n\n stackTops[key] = top;\n\n return { base, dash: datum?.dash, key, opacity: datum?.opacity, present: datum !== undefined, y: top };\n }\n\n return {\n base: 0,\n dash: datum?.dash,\n key,\n opacity: datum?.opacity,\n present: datum !== undefined,\n y: datum?.value ?? 0,\n };\n });\n\n stackedTops[i] = barData.map((d) => d.y);\n\n const baselineYs = stacked ? barData.map((d) => valScale.map(d.base)) : undefined;\n\n renderBars(group, barData, catScale, valScale, sc.baselinePx, {\n baselineYs,\n borderRadius: series.borderRadius ?? themeRadius,\n color: seriesColor(i, series.color),\n disposalSignal: ctx.disposalSignal,\n horizontal,\n seriesCount: seriesList.length,\n seriesIndex: i,\n stacked,\n transition: config.transition,\n });\n }\n\n legend?.update(seriesList.map((s, i) => ({ color: seriesColor(i, s.color), name: s.name })));\n tooltip?.hide();\n groups.series.classList.toggle('prism-bars-stacked', stacked);\n\n if (!band || !ctx.chartArea.contains(band)) {\n band = createSvgElement('rect', { 'aria-hidden': 'true', class: 'prism-bar-band', 'pointer-events': 'none' });\n ctx.chartArea.insertBefore(band, groups.series);\n }\n\n band.style.display = 'none';\n\n // ─── Event handlers (close over render-derived state) ─────────────────────\n\n const colors = seriesList.map((s, i) => seriesColor(i, s.color));\n const labelOf = (catIdx: number): string => String(model.labels.get(categories[catIdx]) ?? categories[catIdx]);\n let activeCat = -1;\n\n const valuesAt = (catIdx: number): SeriesValue[] =>\n seriesList.map((series, si) => ({ datum: allData[si]?.[catIdx], series }));\n\n const eventAt = (catIdx: number, seriesIdx: number, originalEvent: Event): ChartEvent | null => {\n const values = valuesAt(catIdx);\n const preferred = values[seriesIdx]?.datum ? seriesIdx : values.findIndex((v) => v.datum);\n const datum = values[preferred]?.datum;\n\n return datum ? { datum, originalEvent, series: seriesList[preferred], values } : null;\n };\n\n const setActive = (catIdx: number): void => {\n activeCat = catIdx;\n groups.series.classList.toggle('prism-bars-focused', catIdx >= 0);\n\n for (const group of groups.series.children) {\n for (const [i, rect] of [...group.children].entries())\n rect.classList.toggle('prism-bar--active', i === catIdx);\n }\n\n if (!band) return;\n\n band.style.display = catIdx < 0 ? 'none' : '';\n\n if (catIdx < 0) return;\n\n const start = sc.bandCenter(categories[catIdx]) - catScale.bandwidth() / 2 - catScale.gap() / 2;\n const size = catScale.bandwidth() + catScale.gap();\n const a = chartArea(ctx.dimensions.width, ctx.dimensions.height, ctx.dimensions.margin);\n\n setAttributes(\n band,\n horizontal\n ? { height: size, width: a.width, x: 0, y: start }\n : { height: a.height, width: size, x: start, y: 0 },\n );\n };\n\n const activate = (catIdx: number, seriesIdx: number, originalEvent: Event): void => {\n const event = eventAt(catIdx, seriesIdx, originalEvent);\n\n if (!event) return;\n\n setActive(catIdx);\n\n const values = event.values ?? [];\n const spoken = describeValues(labelOf(catIdx), values);\n\n if (tooltip) {\n const tops = values.map((v, si) =>\n stacked ? (stackedTops[si]?.[catIdx] ?? 0) : Math.max(0, v.datum?.value ?? 0),\n );\n const valuePx = valScale.map(Math.max(...tops));\n const bandCenterPx = sc.bandCenter(categories[catIdx]);\n const { margin } = ctx.dimensions;\n const rows = values.flatMap((v, si) =>\n v.datum ? [{ color: colors[si], name: v.series.name, value: String(v.datum.value) }] : [],\n );\n\n tooltip.show(\n (horizontal ? valuePx : bandCenterPx) + margin.left,\n (horizontal ? bandCenterPx : valuePx) + margin.top,\n event.datum,\n event.series,\n comparisonContent(ctx.svg.ownerDocument, labelOf(catIdx), rows, spoken),\n );\n } else {\n ctx.announcer.announce(spoken);\n }\n\n config.onHover?.(event);\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null);\n };\n\n const hit = (event: MouseEvent): { catIdx: number; seriesIdx: number } | null => {\n const d = ctx.dimensions;\n const pos = getMousePosition(ctx.svg, event, d.margin.left, d.margin.top);\n const a = chartArea(d.width, d.height, d.margin);\n\n if (pos.x < 0 || pos.x > a.width || pos.y < 0 || pos.y > a.height) return null;\n\n const catIdx = findCatIdx(horizontal ? pos.y : pos.x, categories, sc);\n\n return catIdx === -1\n ? null\n : { catIdx, seriesIdx: findSeriesIdx(pos, catIdx, categories, sc, seriesList.length) };\n };\n\n const onMouseMove = (event: MouseEvent) => {\n const target = hit(event);\n\n if (target) activate(target.catIdx, target.seriesIdx, event);\n else if (activeCat >= 0) deactivate();\n };\n\n const onClick = (event: MouseEvent) => {\n const target = config.onClick && hit(event);\n const chartEvent = target && eventAt(target.catIdx, target.seriesIdx, event);\n\n if (chartEvent) config.onClick?.(chartEvent);\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n const last = categories.length - 1;\n const prev = activeCat < 0 ? last : Math.max(0, activeCat - 1);\n const next = activeCat < 0 ? 0 : Math.min(last, activeCat + 1);\n const target: Record<string, number> = {\n ArrowDown: next,\n ArrowLeft: prev,\n ArrowRight: next,\n ArrowUp: prev,\n End: last,\n Home: 0,\n };\n\n if (event.key in target) {\n event.preventDefault();\n activate(target[event.key], 0, event);\n } else if ((event.key === 'Enter' || event.key === ' ') && activeCat >= 0 && config.onClick) {\n event.preventDefault();\n\n const chartEvent = eventAt(activeCat, 0, event);\n\n if (chartEvent) config.onClick(chartEvent);\n } else if (event.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (data) => {\n seriesList = data;\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bar-chart.d.ts","sourceRoot":"","sources":["../../../src/charts/bar/bar-chart.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bar-chart.d.ts","sourceRoot":"","sources":["../../../src/charts/bar/bar-chart.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAA0B,WAAW,EAAe,MAAM,aAAa,CAAC;AAcrH,wBAAgB,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC,eAAe,EAAE,CAAC,CAoW7G"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_dev.js";import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{positionAxis as n,renderAxis as r,resolveTickCount as i}from"../../axes/axis.js";import{renderGrid as a}from"../../axes/grid.js";import{linearScale as o}from"../../scales/linear.js";import{describeValues as s}from"../../interaction/announcer.js";import{comparisonContent as c}from"../../interaction/tooltip.js";import{chartArea as l}from"../../core/layout.js";import{clearCartesianDom as u,createChartScaffold as d}from"../../core/chart-scaffold.js";import{
|
|
1
|
+
import"../../_dev.js";import{createSvgElement as e,setAttributes as t}from"../../svg/element.js";import{positionAxis as n,renderAxis as r,resolveTickCount as i}from"../../axes/axis.js";import{renderGrid as a}from"../../axes/grid.js";import{linearScale as o}from"../../scales/linear.js";import{describeValues as s}from"../../interaction/announcer.js";import{comparisonContent as c}from"../../interaction/tooltip.js";import{chartArea as l}from"../../core/layout.js";import{clearCartesianDom as u,createChartScaffold as d}from"../../core/chart-scaffold.js";import{seriesDomId as f}from"../../core/series-id.js";import{normalizeCartesianSeries as p}from"../../core/cartesian-model.js";import{getMousePosition as m}from"../../interaction/events.js";import{seriesColor as h}from"../../theme/index.js";import{bandScale as g}from"../../scales/band.js";import{findCatIdx as _,findSeriesIdx as v}from"./bar-hit-test.js";import{renderBars as y}from"./bar-renderer.js";function variantFlags(e){return{horizontal:e===`grouped-horizontal`||e===`stacked-horizontal`,stacked:e===`stacked`||e===`stacked-horizontal`}}function createBarChart(b,x){let S=x.series,C=null;return d(b,x,d=>{let{groups:b,legend:w,tooltip:T}=d,E=d.dimensions,D=l(E.width,E.height,E.margin),O=S.map(e=>e.data),k=p(S,O),A=k.domain,j=k.series.map(({byKey:e})=>A.map(t=>e.get(t))),categoryAxis=e=>{if(e)return{...e,tickFormat:t=>{let n=String(t),r=k.labels.get(n)??t;return e.tickFormat?e.tickFormat(r):String(r)}}};if(A.length===0){u(b,w,T),C?.remove(),C=null;return}let{horizontal:M,stacked:N}=variantFlags(x.variant??`grouped`),P,F;if(N){j.some(e=>e.some(e=>(e?.value??0)<0));let e=A.map((e,t)=>j.reduce((e,n)=>e+Math.max(0,n[t]?.value??0),0));P=Math.max(...e),F=0}else{let e=j.flatMap(e=>e.flatMap(e=>e?[e.value]:[]));P=Math.max(...e),F=Math.min(0,...e)}let I=g(M?{domain:A,range:[0,D.height]}:{domain:A,range:[0,D.width]}),L=o(M?{domain:[F,P],range:[0,D.width]}:{domain:[F,P],range:[D.height,0]}),R=[],z=Object.create(null);for(let e of A)z[e]=0;let B={bandCenter:e=>I.map(e)+I.bandwidth()/2,bandwidth:I.bandwidth(),baselinePx:L.map(0),horizontal:M,stacked:N,stackedTops:R,valueScale:L};if(M){x.xAxis?.grid&&a(b.grid,L,x.xAxis.grid,D.height,`vertical`,i(x.xAxis,D.width,`bottom`));let e=categoryAxis(x.yAxis);e&&(n(b.yAxis,e.position??`left`,D.width,D.height),r(b.yAxis,I,e,D.height,`left`)),x.xAxis&&(n(b.xAxis,x.xAxis.position??`bottom`,D.width,D.height),r(b.xAxis,L,x.xAxis,D.width,`bottom`))}else{x.yAxis?.grid&&a(b.grid,L,x.yAxis.grid,D.width,`horizontal`,i(x.yAxis,D.height,`left`));let e=categoryAxis(x.xAxis);e&&(n(b.xAxis,e.position??`bottom`,D.width,D.height),r(b.xAxis,I,e,D.width,`bottom`)),x.yAxis&&(n(b.yAxis,x.yAxis.position??`left`,D.width,D.height),r(b.yAxis,L,x.yAxis,D.height,`left`))}let V=N?0:Number.parseFloat(getComputedStyle(d.svg).getPropertyValue(`--prism-bar-radius`))||0;for(;b.series.children.length>S.length;){let e=b.series.lastElementChild;e&&b.series.removeChild(e)}for(let t=0;t<S.length;t++){let n=S[t],r=b.series.children[t];r||(r=e(`g`,{class:`prism-bar-series`}),b.series.appendChild(r)),r.setAttribute(`data-series-id`,f(n,t));let i=A.map((e,n)=>{let r=j[t]?.[n];if(N){let t=z[e]??0,n=t+Math.max(0,r?.value??0);return z[e]=n,{base:t,dash:r?.dash,key:e,opacity:r?.opacity,present:r!==void 0,y:n}}return{base:0,dash:r?.dash,key:e,opacity:r?.opacity,present:r!==void 0,y:r?.value??0}});R[t]=i.map(e=>e.y);let a=N?i.map(e=>L.map(e.base)):void 0;y(r,i,I,L,B.baselinePx,{baselineYs:a,borderRadius:n.borderRadius??V,color:h(t,n.color),disposalSignal:d.disposalSignal,horizontal:M,seriesCount:S.length,seriesIndex:t,stacked:N,transition:x.transition})}w?.update(S.map((e,t)=>({color:h(t,e.color),name:e.name}))),T?.hide(),b.series.classList.toggle(`prism-bars-stacked`,N),(!C||!d.chartArea.contains(C))&&(C=e(`rect`,{"aria-hidden":`true`,class:`prism-bar-band`,"pointer-events":`none`}),d.chartArea.insertBefore(C,b.series)),C.style.display=`none`;let H=S.map((e,t)=>h(t,e.color)),labelOf=e=>String(k.labels.get(A[e])??A[e]),U=-1,valuesAt=e=>S.map((t,n)=>({datum:j[n]?.[e],series:t})),eventAt=(e,t,n)=>{let r=valuesAt(e),i=r[t]?.datum?t:r.findIndex(e=>e.datum),a=r[i]?.datum;return a?{datum:a,originalEvent:n,series:S[i],values:r}:null},setActive=e=>{U=e,b.series.classList.toggle(`prism-bars-focused`,e>=0);for(let t of b.series.children)for(let[n,r]of[...t.children].entries())r.classList.toggle(`prism-bar--active`,n===e);if(!C||(C.style.display=e<0?`none`:``,e<0))return;let n=B.bandCenter(A[e])-I.bandwidth()/2-I.gap()/2,r=I.bandwidth()+I.gap(),i=l(d.dimensions.width,d.dimensions.height,d.dimensions.margin);t(C,M?{height:r,width:i.width,x:0,y:n}:{height:i.height,width:r,x:n,y:0})},activate=(e,t,n)=>{let r=eventAt(e,t,n);if(!r)return;setActive(e);let i=r.values??[],a=s(labelOf(e),i);if(T){let t=i.map((t,n)=>N?R[n]?.[e]??0:Math.max(0,t.datum?.value??0)),n=L.map(Math.max(...t)),o=B.bandCenter(A[e]),{margin:s}=d.dimensions,l=i.flatMap((e,t)=>e.datum?[{color:H[t],name:e.series.name,value:String(e.datum.value)}]:[]);T.show((M?n:o)+s.left,(M?o:n)+s.top,r.datum,r.series,c(d.svg.ownerDocument,labelOf(e),l,a))}else d.announcer.announce(a);x.onHover?.(r)},deactivate=()=>{setActive(-1),T?.hide(),d.announcer.clear(),x.onHover?.(null)},hit=e=>{let t=d.dimensions,n=m(d.svg,e,t.margin.left,t.margin.top),r=l(t.width,t.height,t.margin);if(n.x<0||n.x>r.width||n.y<0||n.y>r.height)return null;let i=_(M?n.y:n.x,A,B);return i===-1?null:{catIdx:i,seriesIdx:v(n,i,A,B,S.length)}},onMouseMove=e=>{let t=hit(e);t?activate(t.catIdx,t.seriesIdx,e):U>=0&&deactivate()},onClick=e=>{let t=x.onClick&&hit(e),n=t&&eventAt(t.catIdx,t.seriesIdx,e);n&&x.onClick?.(n)},onKeyDown=e=>{let t=A.length-1,n=U<0?t:Math.max(0,U-1),r=U<0?0:Math.min(t,U+1),i={ArrowDown:r,ArrowLeft:n,ArrowRight:r,ArrowUp:n,End:t,Home:0};if(e.key in i)e.preventDefault(),activate(i[e.key],0,e);else if((e.key===`Enter`||e.key===` `)&&U>=0&&x.onClick){e.preventDefault();let t=eventAt(U,0,e);t&&x.onClick(t)}else e.key===`Escape`&&deactivate()};return{onClick,onKeyDown,onMouseLeave:deactivate,onMouseMove}},e=>{S=e})}export{createBarChart};
|
|
2
2
|
//# sourceMappingURL=bar-chart.js.map
|