@adminiumjs/charts 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/dist/components/AnomalyChart.d.ts +30 -0
- package/dist/components/AnomalyChart.d.ts.map +1 -0
- package/dist/components/AnomalyChart.js +32 -0
- package/dist/components/AnomalyChart.js.map +1 -0
- package/dist/components/BarChart.d.ts +33 -0
- package/dist/components/BarChart.d.ts.map +1 -0
- package/dist/components/BarChart.js +40 -0
- package/dist/components/BarChart.js.map +1 -0
- package/dist/components/BoxPlotChart.d.ts +23 -0
- package/dist/components/BoxPlotChart.d.ts.map +1 -0
- package/dist/components/BoxPlotChart.js +24 -0
- package/dist/components/BoxPlotChart.js.map +1 -0
- package/dist/components/BulletChart.d.ts +27 -0
- package/dist/components/BulletChart.d.ts.map +1 -0
- package/dist/components/BulletChart.js +24 -0
- package/dist/components/BulletChart.js.map +1 -0
- package/dist/components/BumpChart.d.ts +27 -0
- package/dist/components/BumpChart.d.ts.map +1 -0
- package/dist/components/BumpChart.js +17 -0
- package/dist/components/BumpChart.js.map +1 -0
- package/dist/components/CandlestickChart.d.ts +26 -0
- package/dist/components/CandlestickChart.d.ts.map +1 -0
- package/dist/components/CandlestickChart.js +22 -0
- package/dist/components/CandlestickChart.js.map +1 -0
- package/dist/components/ChartSurface.d.ts +52 -0
- package/dist/components/ChartSurface.d.ts.map +1 -0
- package/dist/components/ChartSurface.js +15 -0
- package/dist/components/ChartSurface.js.map +1 -0
- package/dist/components/Chord.d.ts +30 -0
- package/dist/components/Chord.d.ts.map +1 -0
- package/dist/components/Chord.js +14 -0
- package/dist/components/Chord.js.map +1 -0
- package/dist/components/ChoroplethGridChart.d.ts +32 -0
- package/dist/components/ChoroplethGridChart.d.ts.map +1 -0
- package/dist/components/ChoroplethGridChart.js +15 -0
- package/dist/components/ChoroplethGridChart.js.map +1 -0
- package/dist/components/CohortMatrixChart.d.ts +30 -0
- package/dist/components/CohortMatrixChart.d.ts.map +1 -0
- package/dist/components/CohortMatrixChart.js +13 -0
- package/dist/components/CohortMatrixChart.js.map +1 -0
- package/dist/components/CorrelationMatrixChart.d.ts +24 -0
- package/dist/components/CorrelationMatrixChart.d.ts.map +1 -0
- package/dist/components/CorrelationMatrixChart.js +29 -0
- package/dist/components/CorrelationMatrixChart.js.map +1 -0
- package/dist/components/DonutChart.d.ts +31 -0
- package/dist/components/DonutChart.d.ts.map +1 -0
- package/dist/components/DonutChart.js +19 -0
- package/dist/components/DonutChart.js.map +1 -0
- package/dist/components/ForecastChart.d.ts +37 -0
- package/dist/components/ForecastChart.d.ts.map +1 -0
- package/dist/components/ForecastChart.js +39 -0
- package/dist/components/ForecastChart.js.map +1 -0
- package/dist/components/Funnel.d.ts +27 -0
- package/dist/components/Funnel.d.ts.map +1 -0
- package/dist/components/Funnel.js +25 -0
- package/dist/components/Funnel.js.map +1 -0
- package/dist/components/HeatCalendarChart.d.ts +39 -0
- package/dist/components/HeatCalendarChart.d.ts.map +1 -0
- package/dist/components/HeatCalendarChart.js +37 -0
- package/dist/components/HeatCalendarChart.js.map +1 -0
- package/dist/components/HeatMonthChart.d.ts +30 -0
- package/dist/components/HeatMonthChart.d.ts.map +1 -0
- package/dist/components/HeatMonthChart.js +14 -0
- package/dist/components/HeatMonthChart.js.map +1 -0
- package/dist/components/HexbinChart.d.ts +22 -0
- package/dist/components/HexbinChart.d.ts.map +1 -0
- package/dist/components/HexbinChart.js +31 -0
- package/dist/components/HexbinChart.js.map +1 -0
- package/dist/components/LineAreaChart.d.ts +26 -0
- package/dist/components/LineAreaChart.d.ts.map +1 -0
- package/dist/components/LineAreaChart.js +62 -0
- package/dist/components/LineAreaChart.js.map +1 -0
- package/dist/components/MarimekkoChart.d.ts +24 -0
- package/dist/components/MarimekkoChart.d.ts.map +1 -0
- package/dist/components/MarimekkoChart.js +20 -0
- package/dist/components/MarimekkoChart.js.map +1 -0
- package/dist/components/MultiLineChart.d.ts +36 -0
- package/dist/components/MultiLineChart.d.ts.map +1 -0
- package/dist/components/MultiLineChart.js +62 -0
- package/dist/components/MultiLineChart.js.map +1 -0
- package/dist/components/ParallelCoordinatesChart.d.ts +22 -0
- package/dist/components/ParallelCoordinatesChart.d.ts.map +1 -0
- package/dist/components/ParallelCoordinatesChart.js +16 -0
- package/dist/components/ParallelCoordinatesChart.js.map +1 -0
- package/dist/components/ParetoChart.d.ts +26 -0
- package/dist/components/ParetoChart.d.ts.map +1 -0
- package/dist/components/ParetoChart.js +26 -0
- package/dist/components/ParetoChart.js.map +1 -0
- package/dist/components/Radar.d.ts +27 -0
- package/dist/components/Radar.d.ts.map +1 -0
- package/dist/components/Radar.js +19 -0
- package/dist/components/Radar.js.map +1 -0
- package/dist/components/RadialBar.d.ts +25 -0
- package/dist/components/RadialBar.d.ts.map +1 -0
- package/dist/components/RadialBar.js +12 -0
- package/dist/components/RadialBar.js.map +1 -0
- package/dist/components/RankingBars.d.ts +27 -0
- package/dist/components/RankingBars.d.ts.map +1 -0
- package/dist/components/RankingBars.js +25 -0
- package/dist/components/RankingBars.js.map +1 -0
- package/dist/components/RidgelineChart.d.ts +23 -0
- package/dist/components/RidgelineChart.d.ts.map +1 -0
- package/dist/components/RidgelineChart.js +20 -0
- package/dist/components/RidgelineChart.js.map +1 -0
- package/dist/components/SankeyChart.d.ts +29 -0
- package/dist/components/SankeyChart.d.ts.map +1 -0
- package/dist/components/SankeyChart.js +21 -0
- package/dist/components/SankeyChart.js.map +1 -0
- package/dist/components/ScatterBubbleChart.d.ts +26 -0
- package/dist/components/ScatterBubbleChart.d.ts.map +1 -0
- package/dist/components/ScatterBubbleChart.js +31 -0
- package/dist/components/ScatterBubbleChart.js.map +1 -0
- package/dist/components/SlopeChart.d.ts +28 -0
- package/dist/components/SlopeChart.d.ts.map +1 -0
- package/dist/components/SlopeChart.js +18 -0
- package/dist/components/SlopeChart.js.map +1 -0
- package/dist/components/Sparkline.d.ts +15 -0
- package/dist/components/Sparkline.d.ts.map +1 -0
- package/dist/components/Sparkline.js +27 -0
- package/dist/components/Sparkline.js.map +1 -0
- package/dist/components/StackedBar100.d.ts +30 -0
- package/dist/components/StackedBar100.d.ts.map +1 -0
- package/dist/components/StackedBar100.js +21 -0
- package/dist/components/StackedBar100.js.map +1 -0
- package/dist/components/StreamChart.d.ts +23 -0
- package/dist/components/StreamChart.d.ts.map +1 -0
- package/dist/components/StreamChart.js +56 -0
- package/dist/components/StreamChart.js.map +1 -0
- package/dist/components/Sunburst.d.ts +24 -0
- package/dist/components/Sunburst.d.ts.map +1 -0
- package/dist/components/Sunburst.js +13 -0
- package/dist/components/Sunburst.js.map +1 -0
- package/dist/components/TimelineLanesChart.d.ts +25 -0
- package/dist/components/TimelineLanesChart.d.ts.map +1 -0
- package/dist/components/TimelineLanesChart.js +41 -0
- package/dist/components/TimelineLanesChart.js.map +1 -0
- package/dist/components/Treemap.d.ts +28 -0
- package/dist/components/Treemap.d.ts.map +1 -0
- package/dist/components/Treemap.js +22 -0
- package/dist/components/Treemap.js.map +1 -0
- package/dist/components/ViolinChart.d.ts +22 -0
- package/dist/components/ViolinChart.d.ts.map +1 -0
- package/dist/components/ViolinChart.js +21 -0
- package/dist/components/ViolinChart.js.map +1 -0
- package/dist/components/WaterfallChart.d.ts +23 -0
- package/dist/components/WaterfallChart.d.ts.map +1 -0
- package/dist/components/WaterfallChart.js +29 -0
- package/dist/components/WaterfallChart.js.map +1 -0
- package/dist/components/WordCloud.d.ts +24 -0
- package/dist/components/WordCloud.d.ts.map +1 -0
- package/dist/components/WordCloud.js +22 -0
- package/dist/components/WordCloud.js.map +1 -0
- package/dist/demo/barsRanking.d.ts +26 -0
- package/dist/demo/barsRanking.d.ts.map +1 -0
- package/dist/demo/barsRanking.js +80 -0
- package/dist/demo/barsRanking.js.map +1 -0
- package/dist/demo/generators.d.ts +44 -0
- package/dist/demo/generators.d.ts.map +1 -0
- package/dist/demo/generators.js +72 -0
- package/dist/demo/generators.js.map +1 -0
- package/dist/demo/mulberry32.d.ts +10 -0
- package/dist/demo/mulberry32.d.ts.map +1 -0
- package/dist/demo/mulberry32.js +26 -0
- package/dist/demo/mulberry32.js.map +1 -0
- package/dist/geometry/anomaly.d.ts +22 -0
- package/dist/geometry/anomaly.d.ts.map +1 -0
- package/dist/geometry/anomaly.js +52 -0
- package/dist/geometry/anomaly.js.map +1 -0
- package/dist/geometry/bars.d.ts +46 -0
- package/dist/geometry/bars.d.ts.map +1 -0
- package/dist/geometry/bars.js +68 -0
- package/dist/geometry/bars.js.map +1 -0
- package/dist/geometry/bullet.d.ts +53 -0
- package/dist/geometry/bullet.d.ts.map +1 -0
- package/dist/geometry/bullet.js +67 -0
- package/dist/geometry/bullet.js.map +1 -0
- package/dist/geometry/bump.d.ts +42 -0
- package/dist/geometry/bump.d.ts.map +1 -0
- package/dist/geometry/bump.js +29 -0
- package/dist/geometry/bump.js.map +1 -0
- package/dist/geometry/candles.d.ts +39 -0
- package/dist/geometry/candles.d.ts.map +1 -0
- package/dist/geometry/candles.js +42 -0
- package/dist/geometry/candles.js.map +1 -0
- package/dist/geometry/chord.d.ts +53 -0
- package/dist/geometry/chord.d.ts.map +1 -0
- package/dist/geometry/chord.js +111 -0
- package/dist/geometry/chord.js.map +1 -0
- package/dist/geometry/choropleth.d.ts +58 -0
- package/dist/geometry/choropleth.d.ts.map +1 -0
- package/dist/geometry/choropleth.js +101 -0
- package/dist/geometry/choropleth.js.map +1 -0
- package/dist/geometry/cohort.d.ts +54 -0
- package/dist/geometry/cohort.d.ts.map +1 -0
- package/dist/geometry/cohort.js +70 -0
- package/dist/geometry/cohort.js.map +1 -0
- package/dist/geometry/correlation.d.ts +138 -0
- package/dist/geometry/correlation.d.ts.map +1 -0
- package/dist/geometry/correlation.js +161 -0
- package/dist/geometry/correlation.js.map +1 -0
- package/dist/geometry/distribution.d.ts +115 -0
- package/dist/geometry/distribution.d.ts.map +1 -0
- package/dist/geometry/distribution.js +131 -0
- package/dist/geometry/distribution.js.map +1 -0
- package/dist/geometry/donut.d.ts +37 -0
- package/dist/geometry/donut.d.ts.map +1 -0
- package/dist/geometry/donut.js +46 -0
- package/dist/geometry/donut.js.map +1 -0
- package/dist/geometry/forecast.d.ts +30 -0
- package/dist/geometry/forecast.d.ts.map +1 -0
- package/dist/geometry/forecast.js +75 -0
- package/dist/geometry/forecast.js.map +1 -0
- package/dist/geometry/funnel.d.ts +37 -0
- package/dist/geometry/funnel.d.ts.map +1 -0
- package/dist/geometry/funnel.js +42 -0
- package/dist/geometry/funnel.js.map +1 -0
- package/dist/geometry/heat.d.ts +34 -0
- package/dist/geometry/heat.d.ts.map +1 -0
- package/dist/geometry/heat.js +50 -0
- package/dist/geometry/heat.js.map +1 -0
- package/dist/geometry/heatCalendar.d.ts +43 -0
- package/dist/geometry/heatCalendar.d.ts.map +1 -0
- package/dist/geometry/heatCalendar.js +82 -0
- package/dist/geometry/heatCalendar.js.map +1 -0
- package/dist/geometry/heatMonth.d.ts +47 -0
- package/dist/geometry/heatMonth.d.ts.map +1 -0
- package/dist/geometry/heatMonth.js +72 -0
- package/dist/geometry/heatMonth.js.map +1 -0
- package/dist/geometry/lineArea.d.ts +17 -0
- package/dist/geometry/lineArea.d.ts.map +1 -0
- package/dist/geometry/lineArea.js +37 -0
- package/dist/geometry/lineArea.js.map +1 -0
- package/dist/geometry/marimekko.d.ts +43 -0
- package/dist/geometry/marimekko.d.ts.map +1 -0
- package/dist/geometry/marimekko.js +45 -0
- package/dist/geometry/marimekko.js.map +1 -0
- package/dist/geometry/multiLine.d.ts +19 -0
- package/dist/geometry/multiLine.d.ts.map +1 -0
- package/dist/geometry/multiLine.js +25 -0
- package/dist/geometry/multiLine.js.map +1 -0
- package/dist/geometry/pareto.d.ts +44 -0
- package/dist/geometry/pareto.d.ts.map +1 -0
- package/dist/geometry/pareto.js +65 -0
- package/dist/geometry/pareto.js.map +1 -0
- package/dist/geometry/radar.d.ts +60 -0
- package/dist/geometry/radar.d.ts.map +1 -0
- package/dist/geometry/radar.js +67 -0
- package/dist/geometry/radar.js.map +1 -0
- package/dist/geometry/radialBar.d.ts +31 -0
- package/dist/geometry/radialBar.d.ts.map +1 -0
- package/dist/geometry/radialBar.js +53 -0
- package/dist/geometry/radialBar.js.map +1 -0
- package/dist/geometry/ranking.d.ts +48 -0
- package/dist/geometry/ranking.d.ts.map +1 -0
- package/dist/geometry/ranking.js +42 -0
- package/dist/geometry/ranking.js.map +1 -0
- package/dist/geometry/sankey.d.ts +60 -0
- package/dist/geometry/sankey.d.ts.map +1 -0
- package/dist/geometry/sankey.js +130 -0
- package/dist/geometry/sankey.js.map +1 -0
- package/dist/geometry/scales.d.ts +14 -0
- package/dist/geometry/scales.d.ts.map +1 -0
- package/dist/geometry/scales.js +33 -0
- package/dist/geometry/scales.js.map +1 -0
- package/dist/geometry/slope.d.ts +34 -0
- package/dist/geometry/slope.d.ts.map +1 -0
- package/dist/geometry/slope.js +44 -0
- package/dist/geometry/slope.js.map +1 -0
- package/dist/geometry/sparkline.d.ts +20 -0
- package/dist/geometry/sparkline.d.ts.map +1 -0
- package/dist/geometry/sparkline.js +43 -0
- package/dist/geometry/sparkline.js.map +1 -0
- package/dist/geometry/stacked100.d.ts +33 -0
- package/dist/geometry/stacked100.d.ts.map +1 -0
- package/dist/geometry/stacked100.js +34 -0
- package/dist/geometry/stacked100.js.map +1 -0
- package/dist/geometry/streamStack.d.ts +32 -0
- package/dist/geometry/streamStack.d.ts.map +1 -0
- package/dist/geometry/streamStack.js +56 -0
- package/dist/geometry/streamStack.js.map +1 -0
- package/dist/geometry/sunburst.d.ts +37 -0
- package/dist/geometry/sunburst.d.ts.map +1 -0
- package/dist/geometry/sunburst.js +84 -0
- package/dist/geometry/sunburst.js.map +1 -0
- package/dist/geometry/timelineLanes.d.ts +46 -0
- package/dist/geometry/timelineLanes.d.ts.map +1 -0
- package/dist/geometry/timelineLanes.js +52 -0
- package/dist/geometry/timelineLanes.js.map +1 -0
- package/dist/geometry/treemap.d.ts +42 -0
- package/dist/geometry/treemap.d.ts.map +1 -0
- package/dist/geometry/treemap.js +134 -0
- package/dist/geometry/treemap.js.map +1 -0
- package/dist/geometry/waterfall.d.ts +40 -0
- package/dist/geometry/waterfall.d.ts.map +1 -0
- package/dist/geometry/waterfall.js +80 -0
- package/dist/geometry/waterfall.js.map +1 -0
- package/dist/geometry/wordcloud.d.ts +46 -0
- package/dist/geometry/wordcloud.d.ts.map +1 -0
- package/dist/geometry/wordcloud.js +79 -0
- package/dist/geometry/wordcloud.js.map +1 -0
- package/dist/hooks/useChartSize.d.ts +6 -0
- package/dist/hooks/useChartSize.d.ts.map +1 -0
- package/dist/hooks/useChartSize.js +32 -0
- package/dist/hooks/useChartSize.js.map +1 -0
- package/dist/hooks/useMountAnimation.d.ts +4 -0
- package/dist/hooks/useMountAnimation.d.ts.map +1 -0
- package/dist/hooks/useMountAnimation.js +40 -0
- package/dist/hooks/useMountAnimation.js.map +1 -0
- package/dist/hooks/useRtl.d.ts +7 -0
- package/dist/hooks/useRtl.d.ts.map +1 -0
- package/dist/hooks/useRtl.js +18 -0
- package/dist/hooks/useRtl.js.map +1 -0
- package/dist/index.d.ts +110 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/format.d.ts +5 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +24 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/stats.d.ts +23 -0
- package/dist/utils/stats.d.ts.map +1 -0
- package/dist/utils/stats.js +82 -0
- package/dist/utils/stats.js.map +1 -0
- package/package.json +36 -0
- package/src/styles.css +205 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineArea.d.ts","sourceRoot":"","sources":["../../src/geometry/lineArea.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,qBAAqB;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,qBAAqB;IACrB,CAAC,EAAE,MAAM,CAAC;CACX;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE,MAAM,UAAQ,GAAG,MAAM,GAAG,IAAI,CAMlF;AAED,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,GAAG,IAAI,CAOrG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAW9E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Pure, DOM-free line/area path builders (d3-shape only). */
|
|
2
|
+
import { area, curveLinear, curveMonotoneX, line } from 'd3-shape';
|
|
3
|
+
/** SVG path for a polyline through pixel-space points. Null when < 1 point. */
|
|
4
|
+
export function linePath(points, smooth = false) {
|
|
5
|
+
const generator = line()
|
|
6
|
+
.x((d) => d.x)
|
|
7
|
+
.y((d) => d.y)
|
|
8
|
+
.curve(smooth ? curveMonotoneX : curveLinear);
|
|
9
|
+
return generator([...points]);
|
|
10
|
+
}
|
|
11
|
+
/** SVG path for the area under the line, closed at `baselineY`. */
|
|
12
|
+
export function areaPath(points, baselineY, smooth = false) {
|
|
13
|
+
const generator = area()
|
|
14
|
+
.x((d) => d.x)
|
|
15
|
+
.y0(baselineY)
|
|
16
|
+
.y1((d) => d.y)
|
|
17
|
+
.curve(smooth ? curveMonotoneX : curveLinear);
|
|
18
|
+
return generator([...points]);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Index of the point whose pixel x is nearest to `targetX`. Works for both
|
|
22
|
+
* ascending (LTR) and descending (RTL categorical) x sequences — linear scan,
|
|
23
|
+
* chart series are small. Returns -1 for empty input.
|
|
24
|
+
*/
|
|
25
|
+
export function nearestIndexByX(xs, targetX) {
|
|
26
|
+
let best = -1;
|
|
27
|
+
let bestDistance = Infinity;
|
|
28
|
+
for (let i = 0; i < xs.length; i += 1) {
|
|
29
|
+
const distance = Math.abs((xs[i] ?? Infinity) - targetX);
|
|
30
|
+
if (distance < bestDistance) {
|
|
31
|
+
bestDistance = distance;
|
|
32
|
+
best = i;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return best;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=lineArea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineArea.js","sourceRoot":"","sources":["../../src/geometry/lineArea.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AASnE,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,MAA0B,EAAE,MAAM,GAAG,KAAK;IACjE,MAAM,SAAS,GAAG,IAAI,EAAW;SAC9B,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACb,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACb,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAChD,OAAO,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,QAAQ,CAAC,MAA0B,EAAE,SAAiB,EAAE,MAAM,GAAG,KAAK;IACpF,MAAM,SAAS,GAAG,IAAI,EAAW;SAC9B,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACb,EAAE,CAAC,SAAS,CAAC;SACb,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACd,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAChD,OAAO,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,EAAqB,EAAE,OAAe;IACpE,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,IAAI,YAAY,GAAG,QAAQ,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,OAAO,CAAC,CAAC;QACzD,IAAI,QAAQ,GAAG,YAAY,EAAE,CAAC;YAC5B,YAAY,GAAG,QAAQ,CAAC;YACxB,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure Marimekko / Mekko layout (`chart-marimekko`, research/widget-registry.md
|
|
3
|
+
* §2): column width = outer share, vertical segments = inner mix. DOM-free.
|
|
4
|
+
* Input is a `matrix` (rowKeys = inner categories, colKeys = outer columns,
|
|
5
|
+
* cells[row][col] = value). Columns mirror in RTL (first column at inline-start,
|
|
6
|
+
* the right edge under `rtl`); vertical stacking is direction-invariant.
|
|
7
|
+
*/
|
|
8
|
+
export interface MarimekkoSegment {
|
|
9
|
+
rowIndex: number;
|
|
10
|
+
rowKey: string;
|
|
11
|
+
value: number;
|
|
12
|
+
/** Share of the column total, 0..1. */
|
|
13
|
+
share: number;
|
|
14
|
+
y: number;
|
|
15
|
+
height: number;
|
|
16
|
+
}
|
|
17
|
+
export interface MarimekkoColumn {
|
|
18
|
+
colIndex: number;
|
|
19
|
+
colKey: string;
|
|
20
|
+
total: number;
|
|
21
|
+
/** Share of the grand total, 0..1. */
|
|
22
|
+
share: number;
|
|
23
|
+
x: number;
|
|
24
|
+
width: number;
|
|
25
|
+
segments: MarimekkoSegment[];
|
|
26
|
+
}
|
|
27
|
+
export interface MarimekkoLayout {
|
|
28
|
+
columns: MarimekkoColumn[];
|
|
29
|
+
grandTotal: number;
|
|
30
|
+
}
|
|
31
|
+
export interface MarimekkoLayoutOptions {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
rtl: boolean;
|
|
35
|
+
/** Gap between columns in px (default 2). */
|
|
36
|
+
gap?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* `cells[rowIndex][colIndex]` — the widget adapts the §3 `matrix` envelope
|
|
40
|
+
* (rowKeys × colKeys × cells) into this shape.
|
|
41
|
+
*/
|
|
42
|
+
export declare function layoutMarimekko(rowKeys: readonly string[], colKeys: readonly string[], cells: readonly (readonly number[])[], options: MarimekkoLayoutOptions): MarimekkoLayout;
|
|
43
|
+
//# sourceMappingURL=marimekko.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marimekko.d.ts","sourceRoot":"","sources":["../../src/geometry/marimekko.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EACrC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAuCjB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure Marimekko / Mekko layout (`chart-marimekko`, research/widget-registry.md
|
|
3
|
+
* §2): column width = outer share, vertical segments = inner mix. DOM-free.
|
|
4
|
+
* Input is a `matrix` (rowKeys = inner categories, colKeys = outer columns,
|
|
5
|
+
* cells[row][col] = value). Columns mirror in RTL (first column at inline-start,
|
|
6
|
+
* the right edge under `rtl`); vertical stacking is direction-invariant.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* `cells[rowIndex][colIndex]` — the widget adapts the §3 `matrix` envelope
|
|
10
|
+
* (rowKeys × colKeys × cells) into this shape.
|
|
11
|
+
*/
|
|
12
|
+
export function layoutMarimekko(rowKeys, colKeys, cells, options) {
|
|
13
|
+
const { width, height, rtl, gap = 2 } = options;
|
|
14
|
+
const cols = colKeys.length;
|
|
15
|
+
if (cols === 0 || rowKeys.length === 0 || width <= 0 || height <= 0) {
|
|
16
|
+
return { columns: [], grandTotal: 0 };
|
|
17
|
+
}
|
|
18
|
+
const columnTotals = colKeys.map((_col, colIndex) => rowKeys.reduce((sum, _row, rowIndex) => sum + Math.max(0, cells[rowIndex]?.[colIndex] ?? 0), 0));
|
|
19
|
+
const grandTotal = columnTotals.reduce((sum, t) => sum + t, 0);
|
|
20
|
+
const totalGap = gap * Math.max(0, cols - 1);
|
|
21
|
+
const usableWidth = Math.max(0, width - totalGap);
|
|
22
|
+
// Column x positions accumulate inline-start → inline-end; the whole strip
|
|
23
|
+
// mirrors by reflecting the accumulated inline-start offset in RTL.
|
|
24
|
+
let cursor = 0;
|
|
25
|
+
const columns = colKeys.map((colKey, colIndex) => {
|
|
26
|
+
const total = columnTotals[colIndex] ?? 0;
|
|
27
|
+
const share = grandTotal > 0 ? total / grandTotal : 1 / cols;
|
|
28
|
+
const colWidth = usableWidth * share;
|
|
29
|
+
const inlineStart = cursor;
|
|
30
|
+
cursor += colWidth + gap;
|
|
31
|
+
const x = rtl ? width - inlineStart - colWidth : inlineStart;
|
|
32
|
+
let segCursor = 0;
|
|
33
|
+
const segments = rowKeys.map((rowKey, rowIndex) => {
|
|
34
|
+
const value = Math.max(0, cells[rowIndex]?.[colIndex] ?? 0);
|
|
35
|
+
const segShare = total > 0 ? value / total : 0;
|
|
36
|
+
const segHeight = segShare * height;
|
|
37
|
+
const y = segCursor;
|
|
38
|
+
segCursor += segHeight;
|
|
39
|
+
return { rowIndex, rowKey, value, share: segShare, y, height: segHeight };
|
|
40
|
+
});
|
|
41
|
+
return { colIndex, colKey, total, share, x, width: colWidth, segments };
|
|
42
|
+
});
|
|
43
|
+
return { columns, grandTotal };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=marimekko.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marimekko.js","sourceRoot":"","sources":["../../src/geometry/marimekko.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { XYPoint } from './lineArea.js';
|
|
2
|
+
export interface PixelSeries {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
/** Pixel-space points; gaps (null values) are pre-filtered by the caller. */
|
|
6
|
+
points: XYPoint[];
|
|
7
|
+
}
|
|
8
|
+
export interface SeriesPath {
|
|
9
|
+
key: string;
|
|
10
|
+
label: string;
|
|
11
|
+
path: string | null;
|
|
12
|
+
/** Last plotted point — anchor for end dots + end labels. */
|
|
13
|
+
end: XYPoint | null;
|
|
14
|
+
}
|
|
15
|
+
/** One SVG path string per series through its pixel points, plus the end anchor. */
|
|
16
|
+
export declare function multiSeriesPaths(series: readonly PixelSeries[], smooth?: boolean): SeriesPath[];
|
|
17
|
+
/** Categorical series color var: series i → `--viz-((i mod 8)+1)` (viz.css order). */
|
|
18
|
+
export declare function seriesColorVar(index: number): string;
|
|
19
|
+
//# sourceMappingURL=multiLine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multiLine.d.ts","sourceRoot":"","sources":["../../src/geometry/multiLine.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6DAA6D;IAC7D,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;CACrB;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,MAAM,UAAQ,GAAG,UAAU,EAAE,CAW7F;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure multi-series polyline geometry (d3-shape only) — the core of
|
|
3
|
+
* `chart-multiline` and `chart-bump` (research/widget-registry.md §2). DOM-free
|
|
4
|
+
* so scheduled-report workers reuse it; identical path strings in Node and the
|
|
5
|
+
* browser (04 §7.1, acceptance #10).
|
|
6
|
+
*/
|
|
7
|
+
import { curveLinear, curveMonotoneX, line } from 'd3-shape';
|
|
8
|
+
/** One SVG path string per series through its pixel points, plus the end anchor. */
|
|
9
|
+
export function multiSeriesPaths(series, smooth = false) {
|
|
10
|
+
const generator = line()
|
|
11
|
+
.x((d) => d.x)
|
|
12
|
+
.y((d) => d.y)
|
|
13
|
+
.curve(smooth ? curveMonotoneX : curveLinear);
|
|
14
|
+
return series.map((s) => ({
|
|
15
|
+
key: s.key,
|
|
16
|
+
label: s.label,
|
|
17
|
+
path: s.points.length > 0 ? generator([...s.points]) : null,
|
|
18
|
+
end: s.points.at(-1) ?? null,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
/** Categorical series color var: series i → `--viz-((i mod 8)+1)` (viz.css order). */
|
|
22
|
+
export function seriesColorVar(index) {
|
|
23
|
+
return `var(--viz-${(index % 8) + 1})`;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=multiLine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multiLine.js","sourceRoot":"","sources":["../../src/geometry/multiLine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAmB7D,oFAAoF;AACpF,MAAM,UAAU,gBAAgB,CAAC,MAA8B,EAAE,MAAM,GAAG,KAAK;IAC7E,MAAM,SAAS,GAAG,IAAI,EAAW;SAC9B,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACb,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACb,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxB,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;QAC3D,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;KAC7B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,aAAa,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { XYPoint } from './lineArea.js';
|
|
2
|
+
export interface ParetoInput {
|
|
3
|
+
label: string;
|
|
4
|
+
value: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ParetoBar {
|
|
7
|
+
index: number;
|
|
8
|
+
label: string;
|
|
9
|
+
value: number;
|
|
10
|
+
/** Cumulative share up to and including this bar, 0..1. */
|
|
11
|
+
cumulative: number;
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
/** Center x (used for the cumulative-line vertex + tick anchor). */
|
|
17
|
+
centerX: number;
|
|
18
|
+
/** Cumulative-line vertex y (right axis). */
|
|
19
|
+
lineY: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ParetoLayout {
|
|
22
|
+
bars: ParetoBar[];
|
|
23
|
+
/** Cumulative polyline path (right axis). Null when < 1 bar. */
|
|
24
|
+
linePath: string | null;
|
|
25
|
+
linePoints: XYPoint[];
|
|
26
|
+
/** Nice value ticks for the left axis (ascending). */
|
|
27
|
+
yTicks: number[];
|
|
28
|
+
yFor: (value: number) => number;
|
|
29
|
+
/** Cutline y (right axis) or null when disabled. */
|
|
30
|
+
cutlineY: number | null;
|
|
31
|
+
cutline: number;
|
|
32
|
+
total: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ParetoLayoutOptions {
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
rtl: boolean;
|
|
38
|
+
/** Cumulative cutline fraction, 0..1 (default 0.8); null disables it. */
|
|
39
|
+
cutline?: number | null;
|
|
40
|
+
smooth?: boolean;
|
|
41
|
+
tickCount?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare function layoutPareto(items: readonly ParetoInput[], options: ParetoLayoutOptions): ParetoLayout;
|
|
44
|
+
//# sourceMappingURL=pareto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pareto.d.ts","sourceRoot":"","sources":["../../src/geometry/pareto.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB,sDAAsD;IACtD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAChC,oDAAoD;IACpD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,YAAY,CA6DtG"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure Pareto layout (`chart-pareto`, research/widget-registry.md §2): sorted
|
|
3
|
+
* bars + a cumulative-% line, with an optional cutline (default 80%). DOM-free.
|
|
4
|
+
* Categorical x mirrors in RTL (band-scale range flip); the cumulative line is
|
|
5
|
+
* built in the same visual order so it tracks the mirrored bars. Y for bars is
|
|
6
|
+
* value-scaled (left axis); the line uses the 0..1 cumulative axis (right).
|
|
7
|
+
*/
|
|
8
|
+
import { categoricalBandScale } from './scales.js';
|
|
9
|
+
import { linePath } from './lineArea.js';
|
|
10
|
+
import { niceTicks } from '../utils/stats.js';
|
|
11
|
+
export function layoutPareto(items, options) {
|
|
12
|
+
const { width, height, rtl, cutline = 0.8, smooth = false, tickCount = 3 } = options;
|
|
13
|
+
const empty = {
|
|
14
|
+
bars: [],
|
|
15
|
+
linePath: null,
|
|
16
|
+
linePoints: [],
|
|
17
|
+
yTicks: [],
|
|
18
|
+
yFor: () => 0,
|
|
19
|
+
cutlineY: null,
|
|
20
|
+
cutline: cutline ?? 0.8,
|
|
21
|
+
total: 0,
|
|
22
|
+
};
|
|
23
|
+
if (items.length === 0 || width <= 0 || height <= 0)
|
|
24
|
+
return empty;
|
|
25
|
+
const total = items.reduce((sum, item) => sum + Math.max(0, item.value), 0);
|
|
26
|
+
const peak = items.reduce((m, item) => Math.max(m, item.value), 0);
|
|
27
|
+
const yTicks = peak <= 0 ? [0, 1] : niceTicks(0, peak, tickCount);
|
|
28
|
+
const domainHi = yTicks.at(-1) ?? Math.max(peak, 1);
|
|
29
|
+
const yFor = (value) => height - (Math.max(0, value) / (domainHi || 1)) * height;
|
|
30
|
+
/** Right (cumulative) axis maps 0..1 → bottom..top. */
|
|
31
|
+
const cumulativeY = (frac) => height - Math.max(0, Math.min(1, frac)) * height;
|
|
32
|
+
const band = categoricalBandScale(items.map((item) => item.label), width, rtl, { paddingInner: 0.28, paddingOuter: 0.16 });
|
|
33
|
+
const bandwidth = band.bandwidth();
|
|
34
|
+
let running = 0;
|
|
35
|
+
const bars = items.map((item, index) => {
|
|
36
|
+
running += Math.max(0, item.value);
|
|
37
|
+
const cumulative = total > 0 ? running / total : 0;
|
|
38
|
+
const x = band(item.label) ?? 0;
|
|
39
|
+
const barTop = yFor(item.value);
|
|
40
|
+
return {
|
|
41
|
+
index,
|
|
42
|
+
label: item.label,
|
|
43
|
+
value: item.value,
|
|
44
|
+
cumulative,
|
|
45
|
+
x,
|
|
46
|
+
y: barTop,
|
|
47
|
+
width: bandwidth,
|
|
48
|
+
height: height - barTop,
|
|
49
|
+
centerX: x + bandwidth / 2,
|
|
50
|
+
lineY: cumulativeY(cumulative),
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
const linePoints = bars.map((bar) => ({ x: bar.centerX, y: bar.lineY }));
|
|
54
|
+
return {
|
|
55
|
+
bars,
|
|
56
|
+
linePath: linePath(linePoints, smooth),
|
|
57
|
+
linePoints,
|
|
58
|
+
yTicks,
|
|
59
|
+
yFor,
|
|
60
|
+
cutlineY: cutline === null ? null : cumulativeY(cutline),
|
|
61
|
+
cutline: cutline ?? 0.8,
|
|
62
|
+
total,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=pareto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pareto.js","sourceRoot":"","sources":["../../src/geometry/pareto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure radar geometry (`chart-radar`, research/widget-registry.md §2): N named
|
|
3
|
+
* axes arranged on a regular polygon, one polygon per series (current vs an
|
|
4
|
+
* optional target overlay), normalized to a shared max. First axis points up
|
|
5
|
+
* (12 o'clock); subsequent axes step clockwise (LTR) or counter-clockwise (RTL)
|
|
6
|
+
* so the categorical axis order mirrors per §7.4. DOM-free + deterministic.
|
|
7
|
+
*/
|
|
8
|
+
export interface RadarSeriesInput {
|
|
9
|
+
label: string;
|
|
10
|
+
/** One value per axis, in axis order. */
|
|
11
|
+
values: readonly number[];
|
|
12
|
+
}
|
|
13
|
+
export interface RadarPoint {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
}
|
|
17
|
+
export interface RadarAxis {
|
|
18
|
+
label: string;
|
|
19
|
+
/** Outer vertex of the axis spoke (on the unit ring). */
|
|
20
|
+
point: RadarPoint;
|
|
21
|
+
angle: number;
|
|
22
|
+
}
|
|
23
|
+
export interface RadarSeries {
|
|
24
|
+
label: string;
|
|
25
|
+
points: RadarPoint[];
|
|
26
|
+
/** Closed polygon path string (`M … Z`). */
|
|
27
|
+
path: string;
|
|
28
|
+
colorVar: string;
|
|
29
|
+
}
|
|
30
|
+
export interface RadarGridRing {
|
|
31
|
+
/** 0..1 level. */
|
|
32
|
+
level: number;
|
|
33
|
+
/** Polygon vertices for this concentric level. */
|
|
34
|
+
points: RadarPoint[];
|
|
35
|
+
path: string;
|
|
36
|
+
}
|
|
37
|
+
export interface RadarLayout {
|
|
38
|
+
axes: RadarAxis[];
|
|
39
|
+
series: RadarSeries[];
|
|
40
|
+
rings: RadarGridRing[];
|
|
41
|
+
radius: number;
|
|
42
|
+
center: RadarPoint;
|
|
43
|
+
/** Domain max the values were normalized against. */
|
|
44
|
+
max: number;
|
|
45
|
+
}
|
|
46
|
+
export interface RadarOptions {
|
|
47
|
+
size: number;
|
|
48
|
+
/** Concentric grid rings (default 4). */
|
|
49
|
+
levels?: number;
|
|
50
|
+
/** Explicit domain max; defaults to the max value across all series (min 1). */
|
|
51
|
+
max?: number;
|
|
52
|
+
rtl?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Radar polygons for 1–2 series over `axisLabels`. Series values are truncated
|
|
56
|
+
* or zero-padded to the axis count. Returns empty axes/series when there are
|
|
57
|
+
* fewer than 3 axes (a polygon needs ≥3 vertices).
|
|
58
|
+
*/
|
|
59
|
+
export declare function radarLayout(axisLabels: readonly string[], seriesInput: readonly RadarSeriesInput[], options: RadarOptions): RadarLayout;
|
|
60
|
+
//# sourceMappingURL=radar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radar.d.ts","sourceRoot":"","sources":["../../src/geometry/radar.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,qDAAqD;IACrD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAiBD;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,WAAW,EAAE,SAAS,gBAAgB,EAAE,EACxC,OAAO,EAAE,YAAY,GACpB,WAAW,CAmDb"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure radar geometry (`chart-radar`, research/widget-registry.md §2): N named
|
|
3
|
+
* axes arranged on a regular polygon, one polygon per series (current vs an
|
|
4
|
+
* optional target overlay), normalized to a shared max. First axis points up
|
|
5
|
+
* (12 o'clock); subsequent axes step clockwise (LTR) or counter-clockwise (RTL)
|
|
6
|
+
* so the categorical axis order mirrors per §7.4. DOM-free + deterministic.
|
|
7
|
+
*/
|
|
8
|
+
function vizColor(index) {
|
|
9
|
+
return `var(--viz-${(index % 8) + 1})`;
|
|
10
|
+
}
|
|
11
|
+
function angleFor(index, count, rtl) {
|
|
12
|
+
// Start at 12 o'clock (-90°); step clockwise (LTR) or CCW (RTL).
|
|
13
|
+
const step = (Math.PI * 2) / count;
|
|
14
|
+
return -Math.PI / 2 + (rtl ? -1 : 1) * index * step;
|
|
15
|
+
}
|
|
16
|
+
function polygonPath(points) {
|
|
17
|
+
if (points.length === 0)
|
|
18
|
+
return '';
|
|
19
|
+
return `${points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x.toFixed(3)},${p.y.toFixed(3)}`).join('')}Z`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Radar polygons for 1–2 series over `axisLabels`. Series values are truncated
|
|
23
|
+
* or zero-padded to the axis count. Returns empty axes/series when there are
|
|
24
|
+
* fewer than 3 axes (a polygon needs ≥3 vertices).
|
|
25
|
+
*/
|
|
26
|
+
export function radarLayout(axisLabels, seriesInput, options) {
|
|
27
|
+
const { size, levels = 4, rtl = false } = options;
|
|
28
|
+
const count = axisLabels.length;
|
|
29
|
+
const radius = Math.max(0, size / 2);
|
|
30
|
+
const center = { x: radius, y: radius };
|
|
31
|
+
if (count < 3 || radius <= 0) {
|
|
32
|
+
return { axes: [], series: [], rings: [], radius, center, max: 1 };
|
|
33
|
+
}
|
|
34
|
+
const domainMax = options.max ??
|
|
35
|
+
Math.max(1, ...seriesInput.flatMap((s) => s.values.map((v) => (Number.isFinite(v) ? v : 0))));
|
|
36
|
+
const angles = Array.from({ length: count }, (_, i) => angleFor(i, count, rtl));
|
|
37
|
+
const axes = axisLabels.map((label, i) => {
|
|
38
|
+
const angle = angles[i];
|
|
39
|
+
return {
|
|
40
|
+
label,
|
|
41
|
+
angle,
|
|
42
|
+
point: { x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius },
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
const rings = Array.from({ length: levels }, (_, l) => {
|
|
46
|
+
const level = (l + 1) / levels;
|
|
47
|
+
const points = angles.map((angle) => ({
|
|
48
|
+
x: center.x + Math.cos(angle) * radius * level,
|
|
49
|
+
y: center.y + Math.sin(angle) * radius * level,
|
|
50
|
+
}));
|
|
51
|
+
return { level, points, path: polygonPath(points) };
|
|
52
|
+
});
|
|
53
|
+
const series = seriesInput.map((s, si) => {
|
|
54
|
+
const points = angles.map((angle, i) => {
|
|
55
|
+
const raw = s.values[i];
|
|
56
|
+
const v = Number.isFinite(raw) ? Math.max(0, raw) : 0;
|
|
57
|
+
const norm = Math.min(1, v / domainMax);
|
|
58
|
+
return {
|
|
59
|
+
x: center.x + Math.cos(angle) * radius * norm,
|
|
60
|
+
y: center.y + Math.sin(angle) * radius * norm,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
return { label: s.label, points, path: polygonPath(points), colorVar: vizColor(si) };
|
|
64
|
+
});
|
|
65
|
+
return { axes, series, rings, radius, center, max: domainMax };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=radar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radar.js","sourceRoot":"","sources":["../../src/geometry/radar.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuDH,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,aAAa,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa,EAAE,GAAY;IAC1D,iEAAiE;IACjE,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;AACtD,CAAC;AAED,SAAS,WAAW,CAAC,MAA6B;IAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;AAC1G,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,UAA6B,EAC7B,WAAwC,EACxC,OAAqB;IAErB,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,MAAM,GAAe,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpD,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACrE,CAAC;IAED,MAAM,SAAS,GACb,OAAO,CAAC,GAAG;QACX,IAAI,CAAC,GAAG,CACN,CAAC,EACD,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACjF,CAAC;IAEJ,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAEhF,MAAM,IAAI,GAAgB,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAW,CAAC;QAClC,OAAO;YACL,KAAK;YACL,KAAK;YACL,KAAK,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE;SAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAoB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrE,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,KAAK;YAC9C,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,KAAK;SAC/C,CAAC,CAAC,CAAC;QACJ,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAkB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YACrC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YACxC,OAAO;gBACL,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI;gBAC7C,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,IAAI;aAC9C,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface RadialBarInput {
|
|
2
|
+
label: string;
|
|
3
|
+
/** Percent 0..100 (values are clamped). */
|
|
4
|
+
value: number;
|
|
5
|
+
}
|
|
6
|
+
export interface RadialBarRing {
|
|
7
|
+
label: string;
|
|
8
|
+
value: number;
|
|
9
|
+
/** 0..1 clamped fraction. */
|
|
10
|
+
fraction: number;
|
|
11
|
+
radius: number;
|
|
12
|
+
/** Background track arc (full ring), centered on (0,0). */
|
|
13
|
+
trackPath: string;
|
|
14
|
+
/** Foreground value arc from 12 o'clock clockwise. */
|
|
15
|
+
valuePath: string;
|
|
16
|
+
colorVar: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RadialBarOptions {
|
|
19
|
+
/** Outer diameter in px. */
|
|
20
|
+
size: number;
|
|
21
|
+
thickness?: number;
|
|
22
|
+
/** Gap between concentric rings in px (default 6). */
|
|
23
|
+
gap?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Concentric rings from the outside in, in input order. An empty input (or
|
|
27
|
+
* non-positive size) yields []. Each ring's value arc sweeps clockwise from the
|
|
28
|
+
* top; a zero-percent ring has an empty value path.
|
|
29
|
+
*/
|
|
30
|
+
export declare function radialBarRings(input: readonly RadialBarInput[], options: RadialBarOptions): RadialBarRing[];
|
|
31
|
+
//# sourceMappingURL=radialBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radialBar.d.ts","sourceRoot":"","sources":["../../src/geometry/radialBar.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAWD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,aAAa,EAAE,CA8B3G"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure radial-bar geometry (`chart-radial-bar`, research/widget-registry.md §2):
|
|
3
|
+
* concentric progress rings, one per category (≤4), each a stroke-dashoffset
|
|
4
|
+
* sweep of its percent from 12 o'clock clockwise. DOM-free + deterministic so
|
|
5
|
+
* the same arc paths render in Node and the browser (04 §7.1).
|
|
6
|
+
*
|
|
7
|
+
* Rings never mirror in RTL (clockwise rotation is direction-neutral, like the
|
|
8
|
+
* donut §7.4) — only the surrounding legend flips, which is plain flex CSS.
|
|
9
|
+
*/
|
|
10
|
+
import { arc } from 'd3-shape';
|
|
11
|
+
const TAU = Math.PI * 2;
|
|
12
|
+
function vizColor(index) {
|
|
13
|
+
return `var(--viz-${(index % 8) + 1})`;
|
|
14
|
+
}
|
|
15
|
+
function clampFraction(value) {
|
|
16
|
+
if (!Number.isFinite(value))
|
|
17
|
+
return 0;
|
|
18
|
+
return Math.min(1, Math.max(0, value / 100));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Concentric rings from the outside in, in input order. An empty input (or
|
|
22
|
+
* non-positive size) yields []. Each ring's value arc sweeps clockwise from the
|
|
23
|
+
* top; a zero-percent ring has an empty value path.
|
|
24
|
+
*/
|
|
25
|
+
export function radialBarRings(input, options) {
|
|
26
|
+
const { size, thickness = 12, gap = 6 } = options;
|
|
27
|
+
if (size <= 0 || input.length === 0)
|
|
28
|
+
return [];
|
|
29
|
+
const outer = size / 2;
|
|
30
|
+
return input.map((item, index) => {
|
|
31
|
+
const radius = outer - index * (thickness + gap) - thickness / 2;
|
|
32
|
+
const r = Math.max(0, radius);
|
|
33
|
+
const inner = Math.max(0, r - thickness / 2);
|
|
34
|
+
const outerR = r + thickness / 2;
|
|
35
|
+
const fraction = clampFraction(item.value);
|
|
36
|
+
const track = arc()
|
|
37
|
+
.innerRadius(inner)
|
|
38
|
+
.outerRadius(outerR)
|
|
39
|
+
.cornerRadius(thickness / 2);
|
|
40
|
+
const trackPath = track({ startAngle: 0, endAngle: TAU }) ?? '';
|
|
41
|
+
const valuePath = fraction > 0 ? (track({ startAngle: 0, endAngle: fraction * TAU }) ?? '') : '';
|
|
42
|
+
return {
|
|
43
|
+
label: item.label,
|
|
44
|
+
value: item.value,
|
|
45
|
+
fraction,
|
|
46
|
+
radius: r,
|
|
47
|
+
trackPath,
|
|
48
|
+
valuePath,
|
|
49
|
+
colorVar: vizColor(index),
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=radialBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radialBar.js","sourceRoot":"","sources":["../../src/geometry/radialBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AA6BxB,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,aAAa,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC,EAAE,OAAyB;IACxF,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;IAClD,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE/C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;QACjE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE3C,MAAM,KAAK,GAAG,GAAG,EAA4C;aAC1D,WAAW,CAAC,KAAK,CAAC;aAClB,WAAW,CAAC,MAAM,CAAC;aACnB,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,SAAS,GACb,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEjF,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ;YACR,MAAM,EAAE,CAAC;YACT,SAAS;YACT,SAAS;YACT,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC;SAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure ranking-bar layout (`chart-ranking-bars`, research/widget-registry.md
|
|
3
|
+
* §2): label + proportional horizontal bar (leader solid, rest dimmed) + mono
|
|
4
|
+
* value. DOM-free so scheduled-report workers reuse it. Horizontal value axis
|
|
5
|
+
* mirrors in RTL (annex §7.4: categorical/ranking scales flip; bars anchor at
|
|
6
|
+
* inline-start, which is the right edge under `rtl`).
|
|
7
|
+
*/
|
|
8
|
+
export interface RankingInput {
|
|
9
|
+
label: string;
|
|
10
|
+
value: number;
|
|
11
|
+
}
|
|
12
|
+
export interface RankingBar {
|
|
13
|
+
index: number;
|
|
14
|
+
label: string;
|
|
15
|
+
value: number;
|
|
16
|
+
/** Row top y. */
|
|
17
|
+
rowY: number;
|
|
18
|
+
/** Bar top y (centered in the row). */
|
|
19
|
+
y: number;
|
|
20
|
+
/** Bar inline-start x (left in LTR, right-anchored in RTL). */
|
|
21
|
+
x: number;
|
|
22
|
+
/** Bar length in px. */
|
|
23
|
+
width: number;
|
|
24
|
+
barHeight: number;
|
|
25
|
+
/** True for the single largest value (the leader). */
|
|
26
|
+
isLeader: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface RankingLayout {
|
|
29
|
+
bars: RankingBar[];
|
|
30
|
+
rowHeight: number;
|
|
31
|
+
}
|
|
32
|
+
export interface RankingLayoutOptions {
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
rtl: boolean;
|
|
36
|
+
/** Fraction of the row occupied by the bar (default 0.5). */
|
|
37
|
+
barRatio?: number;
|
|
38
|
+
/** Cap the number of rows (top-N). */
|
|
39
|
+
max?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Lay out top-N horizontal bars. Input is assumed pre-sorted descending (the
|
|
43
|
+
* server returns sorted `categorical`); the leader is whichever row holds the
|
|
44
|
+
* maximum value. Bar length is proportional to the maximum value so the leader
|
|
45
|
+
* fills the track.
|
|
46
|
+
*/
|
|
47
|
+
export declare function layoutRanking(items: readonly RankingInput[], options: RankingLayoutOptions): RankingLayout;
|
|
48
|
+
//# sourceMappingURL=ranking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ranking.d.ts","sourceRoot":"","sources":["../../src/geometry/ranking.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,CAAC,EAAE,MAAM,CAAC;IACV,+DAA+D;IAC/D,CAAC,EAAE,MAAM,CAAC;IACV,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA6B1G"}
|