@milaboratories/miplots4 1.1.0 → 1.2.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.
Files changed (181) hide show
  1. package/dist/MiPlots.d.ts.map +1 -1
  2. package/dist/MiPlots.js +16 -14
  3. package/dist/MiPlots.js.map +1 -1
  4. package/dist/bubble/BubbleSettingsImpl.d.ts +3 -0
  5. package/dist/bubble/BubbleSettingsImpl.d.ts.map +1 -1
  6. package/dist/bubble/BubbleSettingsImpl.js +4 -1
  7. package/dist/bubble/BubbleSettingsImpl.js.map +1 -1
  8. package/dist/bubble/ChartRenderer.d.ts +2 -12
  9. package/dist/bubble/ChartRenderer.d.ts.map +1 -1
  10. package/dist/bubble/ChartRenderer.js +13 -13
  11. package/dist/bubble/ChartRenderer.js.map +1 -1
  12. package/dist/bubble/getGroupedCellsData.d.ts +1 -1
  13. package/dist/bubble/getGroupedCellsData.d.ts.map +1 -1
  14. package/dist/bubble/getGroupedCellsData.js +20 -14
  15. package/dist/bubble/getGroupedCellsData.js.map +1 -1
  16. package/dist/bubble/index.d.ts.map +1 -1
  17. package/dist/bubble/index.js +6 -10
  18. package/dist/bubble/index.js.map +1 -1
  19. package/dist/common/ContinuousAxis.d.ts +3 -1
  20. package/dist/common/ContinuousAxis.d.ts.map +1 -1
  21. package/dist/common/ContinuousAxis.js +8 -8
  22. package/dist/common/ContinuousAxis.js.map +1 -1
  23. package/dist/common/Legend.d.ts +12 -1
  24. package/dist/common/Legend.d.ts.map +1 -1
  25. package/dist/common/Legend.js +14 -6
  26. package/dist/common/Legend.js.map +1 -1
  27. package/dist/heatmap/ChartRenderer.d.ts +2 -12
  28. package/dist/heatmap/ChartRenderer.d.ts.map +1 -1
  29. package/dist/heatmap/ChartRenderer.js +26 -26
  30. package/dist/heatmap/ChartRenderer.js.map +1 -1
  31. package/dist/heatmap/HeatmapSettingsImpl.d.ts +3 -0
  32. package/dist/heatmap/HeatmapSettingsImpl.d.ts.map +1 -1
  33. package/dist/heatmap/HeatmapSettingsImpl.js +5 -2
  34. package/dist/heatmap/HeatmapSettingsImpl.js.map +1 -1
  35. package/dist/heatmap/fillCellsData.d.ts +6 -1
  36. package/dist/heatmap/fillCellsData.d.ts.map +1 -1
  37. package/dist/heatmap/fillCellsData.js +135 -96
  38. package/dist/heatmap/fillCellsData.js.map +1 -1
  39. package/dist/heatmap/getCells.d.ts +4 -1
  40. package/dist/heatmap/getCells.d.ts.map +1 -1
  41. package/dist/heatmap/getCells.js +19 -16
  42. package/dist/heatmap/getCells.js.map +1 -1
  43. package/dist/heatmap/index.d.ts.map +1 -1
  44. package/dist/heatmap/index.js +32 -34
  45. package/dist/heatmap/index.js.map +1 -1
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/selection/ChartRenderer.d.ts +90 -0
  49. package/dist/selection/ChartRenderer.d.ts.map +1 -0
  50. package/dist/selection/ChartRenderer.js +254 -0
  51. package/dist/selection/ChartRenderer.js.map +1 -0
  52. package/dist/selection/SelectionSettingsImpl.d.ts +53 -0
  53. package/dist/selection/SelectionSettingsImpl.d.ts.map +1 -0
  54. package/dist/selection/SelectionSettingsImpl.js +47 -0
  55. package/dist/selection/SelectionSettingsImpl.js.map +1 -0
  56. package/dist/selection/components/Chart/Bars/GroupSelectedBars.d.ts +8 -0
  57. package/dist/selection/components/Chart/Bars/GroupSelectedBars.d.ts.map +1 -0
  58. package/dist/selection/components/Chart/Bars/GroupSelectedBars.js +57 -0
  59. package/dist/selection/components/Chart/Bars/GroupSelectedBars.js.map +1 -0
  60. package/dist/selection/components/Chart/Bars/StackedBars.d.ts +12 -0
  61. package/dist/selection/components/Chart/Bars/StackedBars.d.ts.map +1 -0
  62. package/dist/selection/components/Chart/Bars/StackedBars.js +58 -0
  63. package/dist/selection/components/Chart/Bars/StackedBars.js.map +1 -0
  64. package/dist/selection/components/Chart/Bars/UngroupedBars.d.ts +6 -0
  65. package/dist/selection/components/Chart/Bars/UngroupedBars.d.ts.map +1 -0
  66. package/dist/selection/components/Chart/Bars/UngroupedBars.js +38 -0
  67. package/dist/selection/components/Chart/Bars/UngroupedBars.js.map +1 -0
  68. package/dist/selection/components/Chart/Bars.d.ts +10 -0
  69. package/dist/selection/components/Chart/Bars.d.ts.map +1 -0
  70. package/dist/selection/components/Chart/Bars.js +48 -0
  71. package/dist/selection/components/Chart/Bars.js.map +1 -0
  72. package/dist/selection/components/Chart/ChartAxes.d.ts +7 -0
  73. package/dist/selection/components/Chart/ChartAxes.d.ts.map +1 -0
  74. package/dist/selection/components/Chart/ChartAxes.js +51 -0
  75. package/dist/selection/components/Chart/ChartAxes.js.map +1 -0
  76. package/dist/selection/components/Chart/ChartFrame.d.ts +9 -0
  77. package/dist/selection/components/Chart/ChartFrame.d.ts.map +1 -0
  78. package/dist/selection/components/Chart/ChartFrame.js +41 -0
  79. package/dist/selection/components/Chart/ChartFrame.js.map +1 -0
  80. package/dist/selection/components/Chart/Dividers.d.ts +8 -0
  81. package/dist/selection/components/Chart/Dividers.d.ts.map +1 -0
  82. package/dist/selection/components/Chart/Dividers.js +27 -0
  83. package/dist/selection/components/Chart/Dividers.js.map +1 -0
  84. package/dist/selection/components/Chart/Gridlines.d.ts +10 -0
  85. package/dist/selection/components/Chart/Gridlines.d.ts.map +1 -0
  86. package/dist/selection/components/Chart/Gridlines.js +32 -0
  87. package/dist/selection/components/Chart/Gridlines.js.map +1 -0
  88. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.d.ts +9 -0
  89. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.d.ts.map +1 -0
  90. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.js +36 -0
  91. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.js.map +1 -0
  92. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.d.ts +6 -0
  93. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.d.ts.map +1 -0
  94. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.js +22 -0
  95. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.js.map +1 -0
  96. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.d.ts +10 -0
  97. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.d.ts.map +1 -0
  98. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.js +33 -0
  99. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.js.map +1 -0
  100. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.d.ts +10 -0
  101. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.d.ts.map +1 -0
  102. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.js +65 -0
  103. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.js.map +1 -0
  104. package/dist/selection/components/Chart/Ribbons/ribbonPath.d.ts +10 -0
  105. package/dist/selection/components/Chart/Ribbons/ribbonPath.d.ts.map +1 -0
  106. package/dist/selection/components/Chart/Ribbons/ribbonPath.js +13 -0
  107. package/dist/selection/components/Chart/Ribbons/ribbonPath.js.map +1 -0
  108. package/dist/selection/components/Chart/Ribbons.d.ts +9 -0
  109. package/dist/selection/components/Chart/Ribbons.d.ts.map +1 -0
  110. package/dist/selection/components/Chart/Ribbons.js +58 -0
  111. package/dist/selection/components/Chart/Ribbons.js.map +1 -0
  112. package/dist/selection/components/Chart/StageCounts.d.ts +7 -0
  113. package/dist/selection/components/Chart/StageCounts.d.ts.map +1 -0
  114. package/dist/selection/components/Chart/StageCounts.js +20 -0
  115. package/dist/selection/components/Chart/StageCounts.js.map +1 -0
  116. package/dist/selection/components/Chart/types.d.ts +132 -0
  117. package/dist/selection/components/Chart/types.d.ts.map +1 -0
  118. package/dist/selection/components/Chart.d.ts +22 -0
  119. package/dist/selection/components/Chart.d.ts.map +1 -0
  120. package/dist/selection/components/Chart.js +97 -0
  121. package/dist/selection/components/Chart.js.map +1 -0
  122. package/dist/selection/components/ChartsGroup.d.ts +18 -0
  123. package/dist/selection/components/ChartsGroup.d.ts.map +1 -0
  124. package/dist/selection/components/ChartsGroup.js +181 -0
  125. package/dist/selection/components/ChartsGroup.js.map +1 -0
  126. package/dist/selection/components/FacetCell.d.ts +22 -0
  127. package/dist/selection/components/FacetCell.d.ts.map +1 -0
  128. package/dist/selection/components/FacetCell.js +18 -0
  129. package/dist/selection/components/FacetCell.js.map +1 -0
  130. package/dist/selection/components/types.d.ts +58 -0
  131. package/dist/selection/components/types.d.ts.map +1 -0
  132. package/dist/selection/constants.d.ts +25 -0
  133. package/dist/selection/constants.d.ts.map +1 -0
  134. package/dist/selection/constants.js +4 -0
  135. package/dist/selection/constants.js.map +1 -0
  136. package/dist/selection/createSelectionData.d.ts +50 -0
  137. package/dist/selection/createSelectionData.d.ts.map +1 -0
  138. package/dist/selection/createSelectionData.js +92 -0
  139. package/dist/selection/createSelectionData.js.map +1 -0
  140. package/dist/selection/index.d.ts +26 -0
  141. package/dist/selection/index.d.ts.map +1 -0
  142. package/dist/selection/index.js +96 -0
  143. package/dist/selection/index.js.map +1 -0
  144. package/dist/selection/utils.d.ts +4 -0
  145. package/dist/selection/utils.d.ts.map +1 -0
  146. package/dist/selection/utils.js +13 -0
  147. package/dist/selection/utils.js.map +1 -0
  148. package/dist/types/bubble.d.ts +131 -0
  149. package/dist/types/bubble.d.ts.map +1 -1
  150. package/dist/types/bubble.js +3 -0
  151. package/dist/types/bubble.js.map +1 -1
  152. package/dist/types/common.d.ts +38 -0
  153. package/dist/types/common.d.ts.map +1 -1
  154. package/dist/types/common.js +1 -0
  155. package/dist/types/common.js.map +1 -1
  156. package/dist/types/dendro.d.ts +103 -0
  157. package/dist/types/dendro.d.ts.map +1 -1
  158. package/dist/types/discrete.d.ts +167 -0
  159. package/dist/types/discrete.d.ts.map +1 -1
  160. package/dist/types/heatmap.d.ts +248 -0
  161. package/dist/types/heatmap.d.ts.map +1 -1
  162. package/dist/types/heatmap.js +3 -0
  163. package/dist/types/heatmap.js.map +1 -1
  164. package/dist/types/histogram.d.ts +22 -0
  165. package/dist/types/histogram.d.ts.map +1 -1
  166. package/dist/types/index.d.ts +3 -1
  167. package/dist/types/index.d.ts.map +1 -1
  168. package/dist/types/index.js +1 -0
  169. package/dist/types/scatterplot-umap.d.ts +188 -0
  170. package/dist/types/scatterplot-umap.d.ts.map +1 -1
  171. package/dist/types/scatterplot.d.ts +270 -0
  172. package/dist/types/scatterplot.d.ts.map +1 -1
  173. package/dist/types/selection.d.ts +452 -0
  174. package/dist/types/selection.d.ts.map +1 -0
  175. package/dist/types/selection.js +53 -0
  176. package/dist/types/selection.js.map +1 -0
  177. package/dist/utils/intersect.d.ts +2 -0
  178. package/dist/utils/intersect.d.ts.map +1 -0
  179. package/dist/utils/intersect.js +8 -0
  180. package/dist/utils/intersect.js.map +1 -0
  181. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/selection/ChartRenderer.tsx"],"sourcesContent":["import { scaleOrdinal } from 'd3-scale';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\n\nimport { Error } from '../common/Error';\nimport type { LegendData, LegendItem } from '../common/types';\nimport { TITLE_LINE_HEIGHT, TITLE_MARGIN } from '../constants';\nimport { splitTextByWidth } from '../discrete/utils';\nimport type { ColumnName, FrameType, TitlePosition } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type { Margins } from './components/types';\nimport {\n AGGREGATE_RIBBON_COLOR,\n AXIS_LABEL_LINE_HEIGHT,\n COUNT_LINE_HEIGHT,\n FACET_TITLE_FONT_PX,\n FACET_TITLE_LINE,\n FACET_TITLE_LINE_HEIGHT,\n LABEL_LINE_HEIGHT_PX,\n LABEL_ROTATION_THRESHOLD,\n LABEL_WRAP_WIDTH_PX,\n MIN_MARGIN,\n MIN_PADDING,\n X_COUNT_BOTTOM_PAD,\n X_LABEL_TOP_PAD,\n Y_TICK_RESERVE,\n} from './constants';\nimport type { FacetedSelectionData } from './createSelectionData';\nimport type {\n SelectionFillColor,\n SelectionSettingsImpl,\n SelectionXAxisSettings,\n SelectionYAxisSettings,\n} from './SelectionSettingsImpl';\nimport { formatCount, formatPercent } from './utils';\n\ntype GroupingSettings = NonNullable<SelectionSettingsImpl['grouping']>;\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = <></>;\n\n // Single-cell plot dimensions (inputs to the grid layout).\n cellPlotWidth = 0;\n cellPlotHeight = 0;\n\n // Grid shape.\n nCols = 1;\n nRows = 1;\n isFaceted = false;\n cellLabelHeight = 0;\n orderedFaceted: FacetedSelectionData = { facetKeys: [], byFacet: {}, groupNames: [] };\n facetLabels: Record<string, string[]> = {};\n // Pre-wrapped per-facet title lines, sized to fit `cellPlotWidth`.\n facetTitles: Record<string, string[]> = {};\n\n // Grouping/color resolution.\n grouped = false;\n groupNames: string[] = [];\n colorMap: Map<string, string> = new Map();\n solidColor = '';\n\n // Axis labels (per-facet, multiline support) + auto-rotation decision.\n xLabelsByFacet: Record<string, Record<string, string[]>> = {};\n xCountsByFacet: Record<string, Record<string, string>> = {};\n xLabelsPosition: 'center' | '45deg' | '90deg' = 'center';\n maxLabelLines = 1;\n maxLabelPx = 0;\n\n // Caption-derived padding pieces.\n yTickWidth = 0;\n labelBlock = 0;\n xTitleHeight = 0;\n yTitleWidth = 0;\n // Tick-area reserves: full when labels are shown (room for tick mark + offset\n // + axis title clearance), shrunk to the tick-mark width alone when labels\n // are hidden so the chart can reclaim the freed space.\n yTickReserve = 0;\n xLabelTopReserve = 0;\n\n // Per-cell paddings + grid offsets.\n topPad = 0;\n rightPad = MIN_PADDING;\n fullLeftPad = 0;\n fullBottomPad = 0;\n colLeftPads: number[] = [];\n rowBottomPads: number[] = [];\n colXOffsets: number[] = [0];\n rowYOffsets: number[] = [0];\n gridWidth = 0;\n gridHeight = 0;\n\n // Outer layout.\n legend: LegendData = { width: 0, height: 0, items: [] };\n mainTitle: string[] = [];\n margins: Margins = { top: MIN_MARGIN, bottom: MIN_MARGIN, left: MIN_MARGIN, right: MIN_MARGIN };\n totalWidth = 0;\n totalHeight = 0;\n\n clear() {\n if (this.parentNode && this.rootNode) {\n this.parentNode.removeChild(this.rootNode);\n this.parentNode = null;\n this.rootNode = null;\n }\n setTimeout(() => {\n this.reactRoot?.unmount();\n this.reactRoot = null;\n });\n }\n\n init(node: HTMLElement) {\n if (this.parentNode === null) {\n this.parentNode = node;\n this.rootNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateChartSizes(width: number, height: number) {\n this.cellPlotWidth = width;\n this.cellPlotHeight = height;\n }\n\n updateGrid({\n faceted,\n facetLabels,\n facetBy,\n facetSettings,\n }: {\n faceted: FacetedSelectionData;\n facetLabels: Record<string, string[]>;\n facetBy: ColumnName[];\n facetSettings: SelectionSettingsImpl['facetSettings'];\n }) {\n const orderedFacetKeys = facetSettings.order?.length\n ? facetSettings.order.filter((k) => faceted.facetKeys.includes(k))\n : faceted.facetKeys;\n this.orderedFaceted = { ...faceted, facetKeys: orderedFacetKeys };\n this.facetLabels = facetLabels;\n this.isFaceted = facetBy.length > 0;\n\n if (this.isFaceted) {\n const wrapWidth = Math.max(this.cellPlotWidth, 40);\n this.facetTitles = {};\n let maxLines = 1;\n for (const fk of orderedFacetKeys) {\n const text = (facetLabels[fk] ?? []).join(' / ');\n const lines = text ? splitTextByWidth(text, wrapWidth, FACET_TITLE_FONT_PX) : [];\n this.facetTitles[fk] = lines;\n if (lines.length > maxLines) maxLines = lines.length;\n }\n this.cellLabelHeight = FACET_TITLE_LINE + (maxLines - 1) * FACET_TITLE_LINE_HEIGHT;\n } else {\n this.facetTitles = {};\n this.cellLabelHeight = 0;\n }\n\n const n = orderedFacetKeys.length;\n this.nCols = Math.min(n, facetSettings.nCols ?? Math.max(1, Math.ceil(Math.sqrt(n))));\n this.nRows = facetSettings.nRows ?? Math.max(1, Math.ceil(n / this.nCols));\n }\n\n updateGroupingMaps(grouping: GroupingSettings | undefined, fillColor: SelectionFillColor) {\n // fillColor's shape is the \"fixed vs grouping\" signal (mirrors scatterplot\n // dotFill). When a MappingLink, render grouped/stacked using\n // `grouping.inheritedAes`. When a string, render solid bars in that color.\n const isMappedFill = typeof fillColor === 'object' && fillColor !== null;\n this.grouped = isMappedFill && Boolean(grouping);\n\n const orderedGroupNames = grouping?.order\n ? grouping.order.map(String).filter((n) => this.orderedFaceted.groupNames.includes(n))\n : this.orderedFaceted.groupNames;\n this.groupNames = [\n ...orderedGroupNames,\n ...this.orderedFaceted.groupNames.filter((n) => !orderedGroupNames.includes(n)),\n ];\n\n // colorMap is only consulted on the grouped path (Chart.tsx ungrouped/\n // active-group paths use solidColor instead). Compose populates\n // grouping.inheritedAes whenever fillColor is a MappingLink; missing\n // entries fall back to the solid bar color downstream so the chart still\n // renders if a group key drops out.\n const inheritedAes = grouping?.inheritedAes;\n this.colorMap = new Map<string, string>();\n if (this.grouped && inheritedAes) {\n for (const name of this.groupNames) {\n const c = inheritedAes[name]?.fillColor;\n if (c) this.colorMap.set(name, c);\n }\n }\n\n // Concrete bar color for the ungrouped path. When fillColor is a\n // MappingLink (grouped), Chart.tsx routes the unified ribbon through\n // AGGREGATE_RIBBON_COLOR instead, so this value is only consulted as a\n // (rare) colorMap-miss fallback in the active-group branch.\n this.solidColor = isMappedFill ? AGGREGATE_RIBBON_COLOR : fillColor;\n }\n\n createAxisLabels(xAxis: SelectionXAxisSettings) {\n const tm = new TextMeasurer('500 14px Manrope');\n const facetKeys = this.orderedFaceted.facetKeys;\n\n // Auto-rotate decision: the same `cellPlotWidth` drives every cell, so one\n // decision applies to all. Rotate when any label is >65% of its band\n // width — below that threshold a centered (possibly two-line) label still\n // fits.\n const nStages = facetKeys\n .map((fk) => this.orderedFaceted.byFacet[fk]?.stages.length ?? 0)\n .reduce((a, b) => Math.max(a, b), 0);\n let maxLabelPx = 0;\n for (const fk of facetKeys) {\n for (const stage of this.orderedFaceted.byFacet[fk]?.stages ?? []) {\n maxLabelPx = Math.max(maxLabelPx, tm.getTextWidth(stage.label));\n }\n }\n this.maxLabelPx = maxLabelPx;\n const bandWidth = nStages > 0 ? this.cellPlotWidth / nStages : this.cellPlotWidth;\n // User override (form-set rotation) wins over the auto-decision.\n this.xLabelsPosition =\n xAxis.labelsPosition ??\n (maxLabelPx > bandWidth * LABEL_ROTATION_THRESHOLD ? '90deg' : 'center');\n const rotateLabels = this.xLabelsPosition !== 'center';\n\n // Per-facet stage labels + counts. Centered → wrap to two lines at 120px;\n // rotated 90° → one line per stage.\n this.xLabelsByFacet = {};\n this.xCountsByFacet = {};\n this.maxLabelLines = 1;\n for (const fk of facetKeys) {\n const stages = this.orderedFaceted.byFacet[fk]?.stages ?? [];\n const labels: Record<string, string[]> = {};\n const counts: Record<string, string> = {};\n for (const [i, stage] of stages.entries()) {\n const lines = rotateLabels\n ? [stage.label]\n : splitTextByWidth(stage.label, LABEL_WRAP_WIDTH_PX, LABEL_LINE_HEIGHT_PX);\n labels[String(i)] = lines;\n counts[String(i)] = formatCount(stage.total);\n this.maxLabelLines = Math.max(this.maxLabelLines, lines.length);\n }\n this.xLabelsByFacet[fk] = labels;\n this.xCountsByFacet[fk] = counts;\n }\n }\n\n updateCaptionsSize(xAxis: SelectionXAxisSettings, yAxis: SelectionYAxisSettings) {\n const tm = new TextMeasurer('500 14px Manrope');\n\n // Y axis: when labels are hidden, drop tick-label width AND most of the\n // tick reserve (room for tick mark + offset + axis-title clearance).\n // Histogram pattern: hidden → just tick-mark size, no offset.\n if (yAxis.hiddenLabels) {\n this.yTickWidth = 0;\n this.yTickReserve = yAxis.showTicks ? 4 : 0;\n } else {\n // \"100%\" is the widest formatPercent output for selection's [0, 100]\n // Y scale, regardless of d3's tick count choice.\n this.yTickWidth = tm.getTextWidth(formatPercent(100));\n this.yTickReserve = Y_TICK_RESERVE;\n }\n\n // X axis: same gating for label height block + the gap above the label.\n if (xAxis.hiddenLabels) {\n this.labelBlock = 0;\n this.xLabelTopReserve = xAxis.showTicks ? 4 : 0;\n } else {\n const rotateLabels = this.xLabelsPosition !== 'center';\n this.labelBlock = !rotateLabels\n ? this.maxLabelLines * AXIS_LABEL_LINE_HEIGHT\n : this.xLabelsPosition === '45deg'\n ? Math.ceil(this.maxLabelPx * 0.71) + 10\n : Math.ceil(this.maxLabelPx) + 10;\n this.xLabelTopReserve = X_LABEL_TOP_PAD;\n }\n\n this.xTitleHeight = xAxis.title ? AXIS_LABEL_LINE_HEIGHT + 6 : 0;\n this.yTitleWidth = yAxis.title ? AXIS_LABEL_LINE_HEIGHT + 4 : 0;\n }\n\n updateChartDimensions() {\n // Axis paddings: full = reserve space for labels/title; slim = MIN_PADDING.\n // Selection always uses edge-only axes when faceted (stages and Y range\n // are structurally identical across cells), mirroring histogram's layout.\n this.fullLeftPad = this.yTitleWidth + this.yTickWidth + this.yTickReserve;\n this.fullBottomPad = this.xLabelTopReserve + this.labelBlock + this.xTitleHeight;\n // topPad reserves only the count-label strip above each bar — vertical\n // breathing room between rows comes from `cellLabelHeight` (facet title)\n // + the previous row's `bottomPad`. Adding MIN_MARGIN here would\n // double-count that gap and the stacked padding looks too loose\n // compared to histogram/discrete.\n this.topPad = COUNT_LINE_HEIGHT + X_COUNT_BOTTOM_PAD;\n this.rightPad = MIN_PADDING;\n\n // Per-column / per-row paddings. When faceted, only col 0 reserves the\n // full Y-axis space and only the row(s) hosting bottom-edge cells reserve\n // full X-axis-label space; other cells use MIN_PADDING. Non-faceted (a\n // single cell) reserves both axes for that one cell.\n this.colLeftPads = Array.from({ length: this.nCols }, (_, c) =>\n !this.isFaceted || c === 0 ? this.fullLeftPad : MIN_PADDING,\n );\n // A row is \"bottom-edge\" if it's the last row, or it's nRows-2 in a\n // ragged grid (some columns have only nRows-1 cells, so their last cell\n // sits in row nRows-2 and needs the X-axis label space).\n const n = this.orderedFaceted.facetKeys.length;\n const isRagged = n % this.nCols !== 0;\n this.rowBottomPads = Array.from({ length: this.nRows }, (_, r) => {\n const isBottomRow = r === this.nRows - 1 || (r === this.nRows - 2 && isRagged);\n return !this.isFaceted || isBottomRow ? this.fullBottomPad : MIN_PADDING;\n });\n\n this.colXOffsets = [0];\n for (const [c, leftPad] of this.colLeftPads.entries()) {\n this.colXOffsets.push(this.colXOffsets[c] + leftPad + this.cellPlotWidth + this.rightPad);\n }\n this.rowYOffsets = [0];\n for (const [r, bottomPad] of this.rowBottomPads.entries()) {\n this.rowYOffsets.push(\n this.rowYOffsets[r] + this.topPad + this.cellLabelHeight + this.cellPlotHeight + bottomPad,\n );\n }\n this.gridWidth = this.colXOffsets[this.nCols];\n this.gridHeight = this.rowYOffsets[this.nRows];\n }\n\n updateLegendSize(showLegend: boolean, grouping: GroupingSettings | undefined) {\n if (!showLegend || !this.grouped || this.groupNames.length === 0) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n const legendItems: LegendItem[] = [\n {\n id: 'selection-group',\n type: 'discreteColor',\n title: grouping?.columnName.label ?? grouping?.columnName.value ?? '',\n width: 0,\n height: 0,\n left: 0,\n top: 0,\n values: this.groupNames,\n scale: scaleOrdinal<string, string>()\n .domain(this.groupNames)\n .range(this.groupNames.map((n) => this.colorMap.get(n) ?? '')),\n labels: Object.fromEntries(\n this.groupNames.map((n) => [\n n,\n n === 'null' ? (grouping?.columnName.nullValueLabel ?? 'N/A') : n,\n ]),\n ),\n },\n ];\n // Legend height matches the grid's plot-body strip, like discrete.\n const arranged = arrangeLegendParts(legendItems, this.cellPlotHeight);\n const maxRight = arranged.reduce((m, it) => Math.max(m, it.left + it.width), 0);\n this.legend = { width: maxRight + MIN_MARGIN, height: this.cellPlotHeight, items: arranged };\n }\n\n createMainTitle(title: string, showTitle: boolean) {\n this.mainTitle =\n showTitle && title ? splitTextByWidth(title, Math.max(this.cellPlotWidth, 40), 20) : [];\n }\n\n updateMargins() {\n const titleBlock =\n this.mainTitle.length > 0 ? this.mainTitle.length * TITLE_LINE_HEIGHT + TITLE_MARGIN * 2 : 0;\n this.margins = {\n top: Math.max(titleBlock, MIN_MARGIN),\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN + this.legend.width,\n };\n this.totalWidth = this.margins.left + this.gridWidth + this.margins.right;\n this.totalHeight = this.margins.top + this.gridHeight + this.margins.bottom;\n }\n\n render({\n faceted,\n facetLabels,\n width,\n height,\n title,\n showTitle,\n grouping,\n showLegend,\n facetBy,\n facetSettings,\n xAxis,\n yAxis,\n frame,\n titlePosition,\n fillColor,\n opacity,\n }: {\n faceted: FacetedSelectionData;\n facetLabels: Record<string, string[]>;\n width: number;\n height: number;\n title: string;\n showTitle: boolean;\n grouping: GroupingSettings | undefined;\n showLegend: boolean;\n facetBy: ColumnName[];\n facetSettings: SelectionSettingsImpl['facetSettings'];\n xAxis: SelectionXAxisSettings;\n yAxis: SelectionYAxisSettings;\n frame: FrameType;\n titlePosition: TitlePosition;\n fillColor: SelectionFillColor;\n opacity: number;\n }) {\n this.updateChartSizes(width, height);\n this.updateGrid({ faceted, facetLabels, facetBy, facetSettings });\n this.updateGroupingMaps(grouping, fillColor);\n this.createAxisLabels(xAxis);\n this.updateCaptionsSize(xAxis, yAxis);\n this.updateChartDimensions();\n this.updateLegendSize(showLegend, grouping);\n this.createMainTitle(title, showTitle);\n this.updateMargins();\n\n const component = (\n <ChartsGroup\n facetData={{\n faceted: this.orderedFaceted,\n facetLabels: this.facetLabels,\n facetTitles: this.facetTitles,\n }}\n gridLayout={{\n nRows: this.nRows,\n nCols: this.nCols,\n totalWidth: this.totalWidth,\n totalHeight: this.totalHeight,\n margins: this.margins,\n cellPlotWidth: this.cellPlotWidth,\n cellPlotHeight: this.cellPlotHeight,\n cellLabelHeight: this.cellLabelHeight,\n topPad: this.topPad,\n rightPad: this.rightPad,\n colLeftPads: this.colLeftPads,\n rowBottomPads: this.rowBottomPads,\n colXOffsets: this.colXOffsets,\n rowYOffsets: this.rowYOffsets,\n sharedX: this.isFaceted,\n sharedY: this.isFaceted,\n }}\n xAxis={{\n labelsByFacet: this.xLabelsByFacet,\n countsByFacet: this.xCountsByFacet,\n countsFontSize: 14,\n labelsPosition: this.xLabelsPosition,\n showGrid: xAxis.showGrid,\n showTicks: xAxis.showTicks,\n hiddenLabels: xAxis.hiddenLabels,\n title: xAxis.title,\n }}\n yAxis={{\n showGrid: yAxis.showGrid,\n showTicks: yAxis.showTicks,\n hiddenLabels: yAxis.hiddenLabels,\n title: yAxis.title,\n }}\n style={{\n frameType: this.isFaceted ? 'full' : frame,\n barColor: this.solidColor,\n opacity,\n colorMap: this.colorMap,\n nullValueLabel: grouping?.columnName.nullValueLabel,\n }}\n title={{\n text: this.mainTitle,\n show: this.mainTitle.length > 0,\n position: titlePosition,\n }}\n legend={this.legend}\n showFacetLabels={this.isFaceted}\n grouped={this.grouped}\n orderedGroupNames={this.groupNames}\n />\n );\n this.component = component;\n this.reactRoot?.render(component);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { AesRecord, ColumnName, DataValue, FrameType, SettingsInterface, TitlePosition } from '../types';
2
+ import { SelectionSettings } from '../types/selection';
3
+ export type SelectionFillColor = string | {
4
+ type: string;
5
+ value?: string;
6
+ };
7
+ export type SelectionXAxisSettings = {
8
+ title: string;
9
+ showGrid: boolean;
10
+ showTicks: boolean;
11
+ hiddenLabels: boolean;
12
+ labelsPosition: 'center' | '45deg' | '90deg' | null;
13
+ };
14
+ export type SelectionYAxisSettings = {
15
+ title: string;
16
+ showGrid: boolean;
17
+ showTicks: boolean;
18
+ hiddenLabels: boolean;
19
+ };
20
+ export declare class SelectionSettingsImpl implements SettingsInterface {
21
+ readonly id: string;
22
+ readonly type = "selection";
23
+ readonly selectionStage: ColumnName;
24
+ readonly weight: ColumnName | undefined;
25
+ readonly grouping: {
26
+ columnName: ColumnName;
27
+ order?: DataValue[];
28
+ inheritedAes?: AesRecord;
29
+ } | undefined;
30
+ readonly showLegend: boolean;
31
+ readonly facetBy: ColumnName[];
32
+ readonly facetSettings: {
33
+ order?: string[];
34
+ nRows?: number;
35
+ nCols?: number;
36
+ };
37
+ readonly title: {
38
+ name: string;
39
+ show: boolean;
40
+ position: TitlePosition;
41
+ };
42
+ readonly xAxis: SelectionXAxisSettings;
43
+ readonly yAxis: SelectionYAxisSettings;
44
+ readonly frame: FrameType;
45
+ readonly fillColor: SelectionFillColor;
46
+ readonly opacity: number;
47
+ readonly size: {
48
+ width: number;
49
+ height: number;
50
+ };
51
+ constructor(settings: SelectionSettings);
52
+ }
53
+ //# sourceMappingURL=SelectionSettingsImpl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionSettingsImpl.d.ts","sourceRoot":"","sources":["../../src/selection/SelectionSettingsImpl.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,aAAa,EACd,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,eAAe;IAE5B,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAExC,QAAQ,CAAC,QAAQ,EACb;QACE,UAAU,EAAE,UAAU,CAAC;QACvB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;QACpB,YAAY,CAAC,EAAE,SAAS,CAAC;KAC1B,GACD,SAAS,CAAC;IACd,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAE7B,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE;QACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,QAAQ,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC;IACzE,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAE1B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;gBAErC,QAAQ,EAAE,iBAAiB;CA4CxC"}
@@ -0,0 +1,47 @@
1
+ import { SelectionSettingsSchema as e } from "../types/selection.js";
2
+ import t from "lodash";
3
+ var n = class {
4
+ id;
5
+ type = "selection";
6
+ selectionStage;
7
+ weight;
8
+ grouping;
9
+ showLegend;
10
+ facetBy;
11
+ facetSettings;
12
+ title;
13
+ xAxis;
14
+ yAxis;
15
+ frame;
16
+ fillColor;
17
+ opacity;
18
+ size;
19
+ constructor(n) {
20
+ e.parse(n), this.id = t.uniqueId("settings"), this.selectionStage = n.selectionStage, this.weight = n.weight, this.grouping = n.grouping, this.showLegend = n.legend?.show ?? !0, this.facetBy = n.facetBy ?? [], this.facetSettings = {
21
+ order: n.facetSettings?.order,
22
+ nRows: n.facetSettings?.nRows,
23
+ nCols: n.facetSettings?.nCols
24
+ }, this.title = {
25
+ name: n.title.name,
26
+ show: n.title.show ?? !0,
27
+ position: n.title.position ?? "center"
28
+ }, this.xAxis = {
29
+ title: n.xAxis?.title ?? "",
30
+ showGrid: n.xAxis?.showGrid ?? !1,
31
+ showTicks: n.xAxis?.showTicks ?? !0,
32
+ hiddenLabels: n.xAxis?.hiddenLabels ?? !1,
33
+ labelsPosition: n.xAxis?.labelsPosition ?? null
34
+ }, this.yAxis = {
35
+ title: n.yAxis?.title ?? "",
36
+ showGrid: n.yAxis?.showGrid ?? !0,
37
+ showTicks: n.yAxis?.showTicks ?? !0,
38
+ hiddenLabels: n.yAxis?.hiddenLabels ?? !1
39
+ }, this.frame = n.frame?.type ?? "left-bottom", this.fillColor = n.fillColor, this.opacity = n.opacity ?? 1, this.size = {
40
+ width: n.size?.width ?? 800,
41
+ height: n.size?.height ?? 500
42
+ };
43
+ }
44
+ };
45
+ export { n as SelectionSettingsImpl };
46
+
47
+ //# sourceMappingURL=SelectionSettingsImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionSettingsImpl.js","names":[],"sources":["../../src/selection/SelectionSettingsImpl.ts"],"sourcesContent":["import lodash from 'lodash';\n\nimport type {\n AesRecord,\n ColumnName,\n DataValue,\n FrameType,\n SettingsInterface,\n TitlePosition,\n} from '../types';\nimport { SelectionSettingsSchema } from '../types/selection';\nimport type { SelectionSettings } from '../types/selection';\n\nexport type SelectionFillColor = string | { type: string; value?: string };\n\nexport type SelectionXAxisSettings = {\n title: string;\n showGrid: boolean;\n showTicks: boolean;\n hiddenLabels: boolean;\n labelsPosition: 'center' | '45deg' | '90deg' | null;\n};\n\nexport type SelectionYAxisSettings = {\n title: string;\n showGrid: boolean;\n showTicks: boolean;\n hiddenLabels: boolean;\n};\n\nexport class SelectionSettingsImpl implements SettingsInterface {\n readonly id: string;\n readonly type = 'selection';\n\n readonly selectionStage: ColumnName;\n readonly weight: ColumnName | undefined;\n\n readonly grouping:\n | {\n columnName: ColumnName;\n order?: DataValue[];\n inheritedAes?: AesRecord;\n }\n | undefined;\n readonly showLegend: boolean;\n\n readonly facetBy: ColumnName[];\n readonly facetSettings: {\n order?: string[];\n nRows?: number;\n nCols?: number;\n };\n\n readonly title: { name: string; show: boolean; position: TitlePosition };\n readonly xAxis: SelectionXAxisSettings;\n readonly yAxis: SelectionYAxisSettings;\n readonly frame: FrameType;\n\n readonly fillColor: SelectionFillColor;\n readonly opacity: number;\n readonly size: { width: number; height: number };\n\n constructor(settings: SelectionSettings) {\n SelectionSettingsSchema.parse(settings);\n this.id = lodash.uniqueId('settings');\n\n this.selectionStage = settings.selectionStage;\n this.weight = settings.weight;\n this.grouping = settings.grouping;\n this.showLegend = settings.legend?.show ?? true;\n\n this.facetBy = settings.facetBy ?? [];\n this.facetSettings = {\n order: settings.facetSettings?.order,\n nRows: settings.facetSettings?.nRows,\n nCols: settings.facetSettings?.nCols,\n };\n\n this.title = {\n name: settings.title.name,\n show: settings.title.show ?? true,\n position: settings.title.position ?? 'center',\n };\n\n this.xAxis = {\n title: settings.xAxis?.title ?? '',\n showGrid: settings.xAxis?.showGrid ?? false,\n showTicks: settings.xAxis?.showTicks ?? true,\n hiddenLabels: settings.xAxis?.hiddenLabels ?? false,\n labelsPosition: settings.xAxis?.labelsPosition ?? null,\n };\n this.yAxis = {\n title: settings.yAxis?.title ?? '',\n showGrid: settings.yAxis?.showGrid ?? true,\n showTicks: settings.yAxis?.showTicks ?? true,\n hiddenLabels: settings.yAxis?.hiddenLabels ?? false,\n };\n this.frame = settings.frame?.type ?? 'left-bottom';\n this.fillColor = settings.fillColor;\n this.opacity = settings.opacity ?? 1;\n\n this.size = {\n width: settings.size?.width ?? 800,\n height: settings.size?.height ?? 500,\n };\n }\n}\n"],"mappings":";;AA8BA,IAAa,IAAb,MAAgE;CAC9D;CACA,OAAgB;CAEhB;CACA;CAEA;CAOA;CAEA;CACA;CAMA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA,YAAY,GAA6B;AAuCvC,EAtCA,EAAwB,MAAM,EAAS,EACvC,KAAK,KAAK,EAAO,SAAS,WAAW,EAErC,KAAK,iBAAiB,EAAS,gBAC/B,KAAK,SAAS,EAAS,QACvB,KAAK,WAAW,EAAS,UACzB,KAAK,aAAa,EAAS,QAAQ,QAAQ,IAE3C,KAAK,UAAU,EAAS,WAAW,EAAE,EACrC,KAAK,gBAAgB;GACnB,OAAO,EAAS,eAAe;GAC/B,OAAO,EAAS,eAAe;GAC/B,OAAO,EAAS,eAAe;GAChC,EAED,KAAK,QAAQ;GACX,MAAM,EAAS,MAAM;GACrB,MAAM,EAAS,MAAM,QAAQ;GAC7B,UAAU,EAAS,MAAM,YAAY;GACtC,EAED,KAAK,QAAQ;GACX,OAAO,EAAS,OAAO,SAAS;GAChC,UAAU,EAAS,OAAO,YAAY;GACtC,WAAW,EAAS,OAAO,aAAa;GACxC,cAAc,EAAS,OAAO,gBAAgB;GAC9C,gBAAgB,EAAS,OAAO,kBAAkB;GACnD,EACD,KAAK,QAAQ;GACX,OAAO,EAAS,OAAO,SAAS;GAChC,UAAU,EAAS,OAAO,YAAY;GACtC,WAAW,EAAS,OAAO,aAAa;GACxC,cAAc,EAAS,OAAO,gBAAgB;GAC/C,EACD,KAAK,QAAQ,EAAS,OAAO,QAAQ,eACrC,KAAK,YAAY,EAAS,WAC1B,KAAK,UAAU,EAAS,WAAW,GAEnC,KAAK,OAAO;GACV,OAAO,EAAS,MAAM,SAAS;GAC/B,QAAQ,EAAS,MAAM,UAAU;GAClC"}
@@ -0,0 +1,8 @@
1
+ import { BarsCommon } from '../types';
2
+ export declare const GroupSelectedBars: import('react').NamedExoticComponent<{
3
+ common: BarsCommon;
4
+ facetActiveGroup: string;
5
+ color: string;
6
+ onGroupClick: (name: string) => void;
7
+ }>;
8
+ //# sourceMappingURL=GroupSelectedBars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupSelectedBars.d.ts","sourceRoot":"","sources":["../../../../../src/selection/components/Chart/Bars/GroupSelectedBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,eAAO,MAAM,iBAAiB;YAMpB,UAAU;sBACA,MAAM;WACjB,MAAM;kBACC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;EAuEpC,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { useFunction as e } from "../../../../utils/hooks/useFunction.js";
2
+ import "../../../constants.js";
3
+ import { toPercent as t } from "../../../utils.js";
4
+ import { memo as n } from "react";
5
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ const o = n(function({ common: n, facetActiveGroup: o, color: s, onGroupClick: c }) {
7
+ let { stageIndex: l, stage: u, geometry: d, layerOpacity: f, tooltip: p } = n, { left: m, width: h, centerX: g, height: _, yScale: v } = d, y = u.groups.find((e) => e.name === o), b = y?.surviving ?? 0, x = b + (y?.discarded ?? 0);
8
+ if (x <= 0) return null;
9
+ let S = v(t(x / u.total)), C = v(t(b / u.total)), w = C - S, T = _ - C, E = e((e, t) => {
10
+ p.onEnter({
11
+ stageIndex: l,
12
+ section: e,
13
+ stage: u,
14
+ anchorX: g,
15
+ anchorY: t,
16
+ groupName: o
17
+ });
18
+ }), D = e(() => c(o));
19
+ return /* @__PURE__ */ a(r, { children: [
20
+ w > 0 && /* @__PURE__ */ i("rect", {
21
+ x: m,
22
+ y: S,
23
+ width: h,
24
+ height: w,
25
+ fill: s,
26
+ opacity: .4 * f,
27
+ onMouseEnter: () => E("discarded", S + w / 2),
28
+ onMouseLeave: p.onLeave,
29
+ onClick: D,
30
+ style: { cursor: "pointer" }
31
+ }),
32
+ T > 0 && /* @__PURE__ */ i("rect", {
33
+ x: m,
34
+ y: C,
35
+ width: h,
36
+ height: T,
37
+ fill: s,
38
+ opacity: f,
39
+ onMouseEnter: () => E("preserved", C + T / 2),
40
+ onMouseLeave: p.onLeave,
41
+ onClick: D,
42
+ style: { cursor: "pointer" }
43
+ }),
44
+ w > 0 && T > 0 && /* @__PURE__ */ i("line", {
45
+ x1: m,
46
+ y1: C,
47
+ x2: m + h,
48
+ y2: C,
49
+ stroke: "#333",
50
+ strokeWidth: 1,
51
+ strokeDasharray: "4,3"
52
+ })
53
+ ] });
54
+ });
55
+ export { o as GroupSelectedBars };
56
+
57
+ //# sourceMappingURL=GroupSelectedBars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupSelectedBars.js","names":[],"sources":["../../../../../src/selection/components/Chart/Bars/GroupSelectedBars.tsx"],"sourcesContent":["import { memo } from 'react';\n\nimport { useFunction } from '../../../../utils/hooks/useFunction';\nimport { DESATURATE_ALPHA, DIVIDER_STROKE } from '../../../constants';\nimport { toPercent } from '../../../utils';\nimport type { BarsCommon } from '../types';\n\n// Group-selected bars: only the active group is drawn, with its preserved /\n// discarded segments at actual heights and a dashed divider between them.\nexport const GroupSelectedBars = memo(function GroupSelectedBars({\n common,\n facetActiveGroup,\n color,\n onGroupClick,\n}: {\n common: BarsCommon;\n facetActiveGroup: string;\n color: string;\n onGroupClick: (name: string) => void;\n}) {\n const { stageIndex, stage, geometry, layerOpacity, tooltip } = common;\n const { left, width, centerX, height, yScale } = geometry;\n\n const groupData = stage.groups.find((g) => g.name === facetActiveGroup);\n const gSurviving = groupData?.surviving ?? 0;\n const gDiscarded = groupData?.discarded ?? 0;\n const gTotal = gSurviving + gDiscarded;\n if (gTotal <= 0) return null;\n\n const yOverlayTop = yScale(toPercent(gTotal / stage.total));\n const ySurvivingTop = yScale(toPercent(gSurviving / stage.total));\n const discardedHeight = ySurvivingTop - yOverlayTop;\n const preservedHeight = height - ySurvivingTop;\n\n const handleEnter = useFunction((section: 'preserved' | 'discarded', anchorY: number) => {\n tooltip.onEnter({\n stageIndex,\n section,\n stage,\n anchorX: centerX,\n anchorY,\n groupName: facetActiveGroup,\n });\n });\n const handleClick = useFunction(() => onGroupClick(facetActiveGroup));\n\n return (\n <>\n {discardedHeight > 0 && (\n <rect\n x={left}\n y={yOverlayTop}\n width={width}\n height={discardedHeight}\n fill={color}\n opacity={DESATURATE_ALPHA * layerOpacity}\n onMouseEnter={() => handleEnter('discarded', yOverlayTop + discardedHeight / 2)}\n onMouseLeave={tooltip.onLeave}\n onClick={handleClick}\n style={{ cursor: 'pointer' }}\n />\n )}\n {preservedHeight > 0 && (\n <rect\n x={left}\n y={ySurvivingTop}\n width={width}\n height={preservedHeight}\n fill={color}\n opacity={layerOpacity}\n onMouseEnter={() => handleEnter('preserved', ySurvivingTop + preservedHeight / 2)}\n onMouseLeave={tooltip.onLeave}\n onClick={handleClick}\n style={{ cursor: 'pointer' }}\n />\n )}\n {discardedHeight > 0 && preservedHeight > 0 && (\n <line\n x1={left}\n y1={ySurvivingTop}\n x2={left + width}\n y2={ySurvivingTop}\n stroke={DIVIDER_STROKE}\n strokeWidth={1}\n strokeDasharray=\"4,3\"\n />\n )}\n </>\n );\n});\n"],"mappings":";;;;;AASA,MAAa,IAAoB,EAAK,SAA2B,EAC/D,WACA,qBACA,UACA,mBAMC;CACD,IAAM,EAAE,eAAY,UAAO,aAAU,iBAAc,eAAY,GACzD,EAAE,SAAM,UAAO,YAAS,WAAQ,cAAW,GAE3C,IAAY,EAAM,OAAO,MAAM,MAAM,EAAE,SAAS,EAAiB,EACjE,IAAa,GAAW,aAAa,GAErC,IAAS,KADI,GAAW,aAAa;AAE3C,KAAI,KAAU,EAAG,QAAO;CAExB,IAAM,IAAc,EAAO,EAAU,IAAS,EAAM,MAAM,CAAC,EACrD,IAAgB,EAAO,EAAU,IAAa,EAAM,MAAM,CAAC,EAC3D,IAAkB,IAAgB,GAClC,IAAkB,IAAS,GAE3B,IAAc,GAAa,GAAoC,MAAoB;AACvF,IAAQ,QAAQ;GACd;GACA;GACA;GACA,SAAS;GACT;GACA,WAAW;GACZ,CAAC;GACF,EACI,IAAc,QAAkB,EAAa,EAAiB,CAAC;AAErE,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,IAAkB,KACjB,kBAAC,QAAD;GACE,GAAG;GACH,GAAG;GACI;GACP,QAAQ;GACR,MAAM;GACN,SAAA,KAA4B;GAC5B,oBAAoB,EAAY,aAAa,IAAc,IAAkB,EAAE;GAC/E,cAAc,EAAQ;GACtB,SAAS;GACT,OAAO,EAAE,QAAQ,WAAW;GAC5B,CAAA;EAEH,IAAkB,KACjB,kBAAC,QAAD;GACE,GAAG;GACH,GAAG;GACI;GACP,QAAQ;GACR,MAAM;GACN,SAAS;GACT,oBAAoB,EAAY,aAAa,IAAgB,IAAkB,EAAE;GACjF,cAAc,EAAQ;GACtB,SAAS;GACT,OAAO,EAAE,QAAQ,WAAW;GAC5B,CAAA;EAEH,IAAkB,KAAK,IAAkB,KACxC,kBAAC,QAAD;GACE,IAAI;GACJ,IAAI;GACJ,IAAI,IAAO;GACX,IAAI;GACJ,QAAA;GACA,aAAa;GACb,iBAAgB;GAChB,CAAA;EAEH,EAAA,CAAA;EAEL"}
@@ -0,0 +1,12 @@
1
+ import { default as React } from 'react';
2
+ import { BarsCommon } from '../types';
3
+ export declare const StackedBars: React.NamedExoticComponent<{
4
+ common: BarsCommon;
5
+ stackOrder: string[];
6
+ colorMap: Map<string, string>;
7
+ fallbackColor: string;
8
+ hoveredGroup: string | null;
9
+ onGroupHover: (name: string | null) => void;
10
+ onGroupClick: (name: string) => void;
11
+ }>;
12
+ //# sourceMappingURL=StackedBars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StackedBars.d.ts","sourceRoot":"","sources":["../../../../../src/selection/components/Chart/Bars/StackedBars.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAKpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,eAAO,MAAM,WAAW;YASd,UAAU;gBACN,MAAM,EAAE;cACV,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;mBACd,MAAM;kBACP,MAAM,GAAG,IAAI;kBACb,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;kBAC7B,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;EA+EpC,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { useFunction as e } from "../../../../utils/hooks/useFunction.js";
2
+ import { DESATURATE_ALPHA as t, DIM_OPACITY as n } from "../../../constants.js";
3
+ import { toPercent as r } from "../../../utils.js";
4
+ import { memo as i } from "react";
5
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
6
+ const c = i(function({ common: i, stackOrder: c, colorMap: l, fallbackColor: u, hoveredGroup: d, onGroupHover: f, onGroupClick: p }) {
7
+ let { stageIndex: m, stage: h, geometry: g, layerOpacity: _, tooltip: v } = i, { left: y, width: b, centerX: x, height: S, yScale: C } = g, w = e((e, t, n) => {
8
+ f(e), v.onEnter({
9
+ stageIndex: m,
10
+ section: t,
11
+ stage: h,
12
+ anchorX: x,
13
+ anchorY: n,
14
+ groupName: e
15
+ });
16
+ }), T = e(() => {
17
+ f(null), v.onLeave();
18
+ }), E = e((e) => p(e)), D = new Map(h.groups.map((e) => [e.name, e])), O = h.total > 0 ? C(r(h.surviving / h.total)) : S, k = [], A = [], j = O, M = 0;
19
+ for (let e of c) {
20
+ let r = D.get(e);
21
+ if (!r) continue;
22
+ let i = r.surviving / h.total * S, a = r.discarded / h.total * S, s = d && d !== e;
23
+ if (i > 0) {
24
+ let t = j + i / 2;
25
+ k.push(/* @__PURE__ */ o("rect", {
26
+ x: y,
27
+ y: j,
28
+ width: b,
29
+ height: i,
30
+ fill: l.get(e) ?? u,
31
+ opacity: (s ? n : 1) * _,
32
+ onMouseEnter: () => w(e, "preserved", t),
33
+ onMouseLeave: T,
34
+ onClick: () => E(e),
35
+ style: { cursor: "pointer" }
36
+ }, `bar-p-${m}-${e}`)), j += i;
37
+ }
38
+ if (a > 0) {
39
+ let r = M + a / 2;
40
+ A.push(/* @__PURE__ */ o("rect", {
41
+ x: y,
42
+ y: M,
43
+ width: b,
44
+ height: a,
45
+ fill: l.get(e) ?? u,
46
+ opacity: (s ? n : t) * _,
47
+ onMouseEnter: () => w(e, "discarded", r),
48
+ onMouseLeave: T,
49
+ onClick: () => E(e),
50
+ style: { cursor: "pointer" }
51
+ }, `bar-d-${m}-${e}`)), M += a;
52
+ }
53
+ }
54
+ return /* @__PURE__ */ s(a, { children: [k, A] });
55
+ });
56
+ export { c as StackedBars };
57
+
58
+ //# sourceMappingURL=StackedBars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StackedBars.js","names":[],"sources":["../../../../../src/selection/components/Chart/Bars/StackedBars.tsx"],"sourcesContent":["import React, { memo } from 'react';\n\nimport { useFunction } from '../../../../utils/hooks/useFunction';\nimport { DESATURATE_ALPHA, DIM_OPACITY } from '../../../constants';\nimport { toPercent } from '../../../utils';\nimport type { BarsCommon } from '../types';\n\n// Stacked-grouped bars: per-group rects above and below the divider, stacked\n// in caller-provided order. Hover dims non-hovered groups.\nexport const StackedBars = memo(function StackedBars({\n common,\n stackOrder,\n colorMap,\n fallbackColor,\n hoveredGroup,\n onGroupHover,\n onGroupClick,\n}: {\n common: BarsCommon;\n stackOrder: string[];\n colorMap: Map<string, string>;\n fallbackColor: string;\n hoveredGroup: string | null;\n onGroupHover: (name: string | null) => void;\n onGroupClick: (name: string) => void;\n}) {\n const { stageIndex, stage, geometry, layerOpacity, tooltip } = common;\n const { left, width, centerX, height, yScale } = geometry;\n\n const handleEnter = useFunction(\n (groupName: string, section: 'preserved' | 'discarded', anchorY: number) => {\n onGroupHover(groupName);\n tooltip.onEnter({ stageIndex, section, stage, anchorX: centerX, anchorY, groupName });\n },\n );\n const handleLeave = useFunction(() => {\n onGroupHover(null);\n tooltip.onLeave();\n });\n const handleClick = useFunction((groupName: string) => onGroupClick(groupName));\n\n const groupByName = new Map(stage.groups.map((g) => [g.name, g]));\n const dividerY = stage.total > 0 ? yScale(toPercent(stage.surviving / stage.total)) : height;\n const preserved: React.JSX.Element[] = [];\n const discarded: React.JSX.Element[] = [];\n // Both halves stack top-to-bottom in stackOrder so a given group appears at\n // the same vertical reading order in preserved and discarded — without this\n // the two halves are mirrored around the divider and the same group ends up\n // adjacent to the divider on both sides.\n let yP = dividerY;\n let yD = 0;\n for (const groupName of stackOrder) {\n const groupData = groupByName.get(groupName);\n if (!groupData) continue;\n const survivingHeight = (groupData.surviving / stage.total) * height;\n const discardedHeight = (groupData.discarded / stage.total) * height;\n const dimmed = hoveredGroup && hoveredGroup !== groupName;\n\n if (survivingHeight > 0) {\n const anchorY = yP + survivingHeight / 2;\n preserved.push(\n <rect\n key={`bar-p-${stageIndex}-${groupName}`}\n x={left}\n y={yP}\n width={width}\n height={survivingHeight}\n fill={colorMap.get(groupName) ?? fallbackColor}\n opacity={(dimmed ? DIM_OPACITY : 1) * layerOpacity}\n onMouseEnter={() => handleEnter(groupName, 'preserved', anchorY)}\n onMouseLeave={handleLeave}\n onClick={() => handleClick(groupName)}\n style={{ cursor: 'pointer' }}\n />,\n );\n yP += survivingHeight;\n }\n if (discardedHeight > 0) {\n const anchorY = yD + discardedHeight / 2;\n discarded.push(\n <rect\n key={`bar-d-${stageIndex}-${groupName}`}\n x={left}\n y={yD}\n width={width}\n height={discardedHeight}\n fill={colorMap.get(groupName) ?? fallbackColor}\n opacity={(dimmed ? DIM_OPACITY : DESATURATE_ALPHA) * layerOpacity}\n onMouseEnter={() => handleEnter(groupName, 'discarded', anchorY)}\n onMouseLeave={handleLeave}\n onClick={() => handleClick(groupName)}\n style={{ cursor: 'pointer' }}\n />,\n );\n yD += discardedHeight;\n }\n }\n return (\n <>\n {preserved}\n {discarded}\n </>\n );\n});\n"],"mappings":";;;;;AASA,MAAa,IAAc,EAAK,SAAqB,EACnD,WACA,eACA,aACA,kBACA,iBACA,iBACA,mBASC;CACD,IAAM,EAAE,eAAY,UAAO,aAAU,iBAAc,eAAY,GACzD,EAAE,SAAM,UAAO,YAAS,WAAQ,cAAW,GAE3C,IAAc,GACjB,GAAmB,GAAoC,MAAoB;AAE1E,EADA,EAAa,EAAU,EACvB,EAAQ,QAAQ;GAAE;GAAY;GAAS;GAAO,SAAS;GAAS;GAAS;GAAW,CAAC;GAExF,EACK,IAAc,QAAkB;AAEpC,EADA,EAAa,KAAK,EAClB,EAAQ,SAAS;GACjB,EACI,IAAc,GAAa,MAAsB,EAAa,EAAU,CAAC,EAEzE,IAAc,IAAI,IAAI,EAAM,OAAO,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAC3D,IAAW,EAAM,QAAQ,IAAI,EAAO,EAAU,EAAM,YAAY,EAAM,MAAM,CAAC,GAAG,GAChF,IAAiC,EAAE,EACnC,IAAiC,EAAE,EAKrC,IAAK,GACL,IAAK;AACT,MAAK,IAAM,KAAa,GAAY;EAClC,IAAM,IAAY,EAAY,IAAI,EAAU;AAC5C,MAAI,CAAC,EAAW;EAChB,IAAM,IAAmB,EAAU,YAAY,EAAM,QAAS,GACxD,IAAmB,EAAU,YAAY,EAAM,QAAS,GACxD,IAAS,KAAgB,MAAiB;AAEhD,MAAI,IAAkB,GAAG;GACvB,IAAM,IAAU,IAAK,IAAkB;AAgBvC,GAfA,EAAU,KACR,kBAAC,QAAD;IAEE,GAAG;IACH,GAAG;IACI;IACP,QAAQ;IACR,MAAM,EAAS,IAAI,EAAU,IAAI;IACjC,UAAU,IAAS,IAAc,KAAK;IACtC,oBAAoB,EAAY,GAAW,aAAa,EAAQ;IAChE,cAAc;IACd,eAAe,EAAY,EAAU;IACrC,OAAO,EAAE,QAAQ,WAAW;IAC5B,EAXK,SAAS,EAAW,GAAG,IAW5B,CACH,EACD,KAAM;;AAER,MAAI,IAAkB,GAAG;GACvB,IAAM,IAAU,IAAK,IAAkB;AAgBvC,GAfA,EAAU,KACR,kBAAC,QAAD;IAEE,GAAG;IACH,GAAG;IACI;IACP,QAAQ;IACR,MAAM,EAAS,IAAI,EAAU,IAAI;IACjC,UAAU,IAAS,IAAc,KAAoB;IACrD,oBAAoB,EAAY,GAAW,aAAa,EAAQ;IAChE,cAAc;IACd,eAAe,EAAY,EAAU;IACrC,OAAO,EAAE,QAAQ,WAAW;IAC5B,EAXK,SAAS,EAAW,GAAG,IAW5B,CACH,EACD,KAAM;;;AAGV,QACE,kBAAA,GAAA,EAAA,UAAA,CACG,GACA,EACA,EAAA,CAAA;EAEL"}
@@ -0,0 +1,6 @@
1
+ import { BarsCommon } from '../types';
2
+ export declare const UngroupedBars: import('react').NamedExoticComponent<{
3
+ common: BarsCommon;
4
+ barColor: string;
5
+ }>;
6
+ //# sourceMappingURL=UngroupedBars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UngroupedBars.d.ts","sourceRoot":"","sources":["../../../../../src/selection/components/Chart/Bars/UngroupedBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C,eAAO,MAAM,aAAa;YAIhB,UAAU;cACR,MAAM;EAqChB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { useFunction as e } from "../../../../utils/hooks/useFunction.js";
2
+ import { DESATURATE_ALPHA as t } from "../../../constants.js";
3
+ import { toPercent as n } from "../../../utils.js";
4
+ import { memo as r } from "react";
5
+ import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
6
+ const s = r(function({ common: r, barColor: s }) {
7
+ let { stageIndex: c, stage: l, geometry: u, layerOpacity: d, tooltip: f } = r, { left: p, width: m, centerX: h, height: g, yScale: _ } = u, v = l.total > 0 ? _(n(l.surviving / l.total)) : g, y = g - v, b = v, x = e((e, t) => {
8
+ f.onEnter({
9
+ stageIndex: c,
10
+ section: e,
11
+ stage: l,
12
+ anchorX: h,
13
+ anchorY: t
14
+ });
15
+ });
16
+ return /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("rect", {
17
+ x: p,
18
+ y: v,
19
+ width: m,
20
+ height: y,
21
+ fill: s,
22
+ opacity: d,
23
+ onMouseEnter: () => x("preserved", v + y / 2),
24
+ onMouseLeave: f.onLeave
25
+ }), /* @__PURE__ */ a("rect", {
26
+ x: p,
27
+ y: 0,
28
+ width: m,
29
+ height: b,
30
+ fill: s,
31
+ opacity: t * d,
32
+ onMouseEnter: () => x("discarded", b / 2),
33
+ onMouseLeave: f.onLeave
34
+ })] });
35
+ });
36
+ export { s as UngroupedBars };
37
+
38
+ //# sourceMappingURL=UngroupedBars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UngroupedBars.js","names":[],"sources":["../../../../../src/selection/components/Chart/Bars/UngroupedBars.tsx"],"sourcesContent":["import { memo } from 'react';\n\nimport { useFunction } from '../../../../utils/hooks/useFunction';\nimport { DESATURATE_ALPHA } from '../../../constants';\nimport { toPercent } from '../../../utils';\nimport type { BarsCommon } from '../types';\n\n// Ungrouped bars: a single bar split into preserved (bottom, vivid) and\n// discarded (top, desaturated).\nexport const UngroupedBars = memo(function UngroupedBars({\n common,\n barColor,\n}: {\n common: BarsCommon;\n barColor: string;\n}) {\n const { stageIndex, stage, geometry, layerOpacity, tooltip } = common;\n const { left, width, centerX, height, yScale } = geometry;\n\n const dividerY = stage.total > 0 ? yScale(toPercent(stage.surviving / stage.total)) : height;\n const preservedHeight = height - dividerY;\n const discardedHeight = dividerY;\n\n const handleEnter = useFunction((section: 'preserved' | 'discarded', anchorY: number) => {\n tooltip.onEnter({ stageIndex, section, stage, anchorX: centerX, anchorY });\n });\n\n return (\n <>\n <rect\n x={left}\n y={dividerY}\n width={width}\n height={preservedHeight}\n fill={barColor}\n opacity={layerOpacity}\n onMouseEnter={() => handleEnter('preserved', dividerY + preservedHeight / 2)}\n onMouseLeave={tooltip.onLeave}\n />\n <rect\n x={left}\n y={0}\n width={width}\n height={discardedHeight}\n fill={barColor}\n opacity={DESATURATE_ALPHA * layerOpacity}\n onMouseEnter={() => handleEnter('discarded', discardedHeight / 2)}\n onMouseLeave={tooltip.onLeave}\n />\n </>\n );\n});\n"],"mappings":";;;;;AASA,MAAa,IAAgB,EAAK,SAAuB,EACvD,WACA,eAIC;CACD,IAAM,EAAE,eAAY,UAAO,aAAU,iBAAc,eAAY,GACzD,EAAE,SAAM,UAAO,YAAS,WAAQ,cAAW,GAE3C,IAAW,EAAM,QAAQ,IAAI,EAAO,EAAU,EAAM,YAAY,EAAM,MAAM,CAAC,GAAG,GAChF,IAAkB,IAAS,GAC3B,IAAkB,GAElB,IAAc,GAAa,GAAoC,MAAoB;AACvF,IAAQ,QAAQ;GAAE;GAAY;GAAS;GAAO,SAAS;GAAS;GAAS,CAAC;GAC1E;AAEF,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;EACE,GAAG;EACH,GAAG;EACI;EACP,QAAQ;EACR,MAAM;EACN,SAAS;EACT,oBAAoB,EAAY,aAAa,IAAW,IAAkB,EAAE;EAC5E,cAAc,EAAQ;EACtB,CAAA,EACF,kBAAC,QAAD;EACE,GAAG;EACH,GAAG;EACI;EACP,QAAQ;EACR,MAAM;EACN,SAAS,IAAmB;EAC5B,oBAAoB,EAAY,aAAa,IAAkB,EAAE;EACjE,cAAc,EAAQ;EACtB,CAAA,CACD,EAAA,CAAA;EAEL"}
@@ -0,0 +1,10 @@
1
+ import { StageInfo } from '../../createSelectionData';
2
+ import { ChartStyle, GroupContext, StageGeometry, StageHandlers } from './types';
3
+ export declare const Bars: import('react').NamedExoticComponent<{
4
+ stages: StageInfo[];
5
+ geometry: StageGeometry;
6
+ groupCtx: GroupContext;
7
+ style: ChartStyle;
8
+ handlers: StageHandlers;
9
+ }>;
10
+ //# sourceMappingURL=Bars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bars.d.ts","sourceRoot":"","sources":["../../../../src/selection/components/Chart/Bars.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3D,OAAO,KAAK,EAAc,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAMlG,eAAO,MAAM,IAAI;YAOP,SAAS,EAAE;cACT,aAAa;cACb,YAAY;WACf,UAAU;cACP,aAAa;EAoDvB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { GroupSelectedBars as e } from "./Bars/GroupSelectedBars.js";
2
+ import { StackedBars as t } from "./Bars/StackedBars.js";
3
+ import { UngroupedBars as n } from "./Bars/UngroupedBars.js";
4
+ import { memo as r } from "react";
5
+ import { jsx as i } from "react/jsx-runtime";
6
+ const a = r(function({ stages: r, geometry: a, groupCtx: o, style: s, handlers: c }) {
7
+ let { xScale: l, yScale: u, height: d } = a, { grouped: f, groupNames: p, facetActiveGroup: m, facetHoveredGroup: h, stackOrder: g } = o, { barColor: _, opacity: v, colorMap: y } = s, { onGroupClick: b, onGroupHover: x, onTooltipEnter: S, onTooltipLeave: C } = c, w = l.bandwidth(), T = [];
8
+ for (let [a, o] of r.entries()) {
9
+ if (o.total === 0) continue;
10
+ let r = l(String(a)) ?? 0, s = {
11
+ stageIndex: a,
12
+ stage: o,
13
+ geometry: {
14
+ left: r,
15
+ width: w,
16
+ centerX: r + w / 2,
17
+ height: d,
18
+ yScale: u
19
+ },
20
+ layerOpacity: v,
21
+ tooltip: {
22
+ onEnter: S,
23
+ onLeave: C
24
+ }
25
+ };
26
+ f && p.length > 0 && m ? T.push(/* @__PURE__ */ i(e, {
27
+ common: s,
28
+ facetActiveGroup: m,
29
+ color: y.get(m) ?? _,
30
+ onGroupClick: b
31
+ }, `bars-${a}`)) : f && p.length > 0 ? T.push(/* @__PURE__ */ i(t, {
32
+ common: s,
33
+ stackOrder: g,
34
+ colorMap: y,
35
+ fallbackColor: _,
36
+ hoveredGroup: h,
37
+ onGroupHover: x,
38
+ onGroupClick: b
39
+ }, `bars-${a}`)) : T.push(/* @__PURE__ */ i(n, {
40
+ common: s,
41
+ barColor: _
42
+ }, `bars-${a}`));
43
+ }
44
+ return /* @__PURE__ */ i("g", { children: T });
45
+ });
46
+ export { a as Bars };
47
+
48
+ //# sourceMappingURL=Bars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bars.js","names":[],"sources":["../../../../src/selection/components/Chart/Bars.tsx"],"sourcesContent":["import { memo } from 'react';\nimport type { ReactElement } from 'react';\n\nimport type { StageInfo } from '../../createSelectionData';\nimport { GroupSelectedBars } from './Bars/GroupSelectedBars';\nimport { StackedBars } from './Bars/StackedBars';\nimport { UngroupedBars } from './Bars/UngroupedBars';\nimport type { BarsCommon, ChartStyle, GroupContext, StageGeometry, StageHandlers } from './types';\n\n// Picks the bar component per stage based on grouping state:\n// - facetActiveGroup set → GroupSelectedBars (single-group overlay)\n// - grouped, no active group → StackedBars (stacked-by-group)\n// - ungrouped → UngroupedBars (single combined bar)\nexport const Bars = memo(function Bars({\n stages,\n geometry,\n groupCtx,\n style,\n handlers,\n}: {\n stages: StageInfo[];\n geometry: StageGeometry;\n groupCtx: GroupContext;\n style: ChartStyle;\n handlers: StageHandlers;\n}) {\n const { xScale, yScale, height } = geometry;\n const { grouped, groupNames, facetActiveGroup, facetHoveredGroup, stackOrder } = groupCtx;\n const { barColor, opacity: layerOpacity, colorMap } = style;\n const { onGroupClick, onGroupHover, onTooltipEnter, onTooltipLeave } = handlers;\n\n const barWidth = xScale.bandwidth();\n const elements: ReactElement[] = [];\n\n for (const [stageIndex, stage] of stages.entries()) {\n if (stage.total === 0) continue;\n const left = xScale(String(stageIndex)) ?? 0;\n const common: BarsCommon = {\n stageIndex,\n stage,\n geometry: { left, width: barWidth, centerX: left + barWidth / 2, height, yScale },\n layerOpacity,\n tooltip: { onEnter: onTooltipEnter, onLeave: onTooltipLeave },\n };\n\n if (grouped && groupNames.length > 0 && facetActiveGroup) {\n elements.push(\n <GroupSelectedBars\n key={`bars-${stageIndex}`}\n common={common}\n facetActiveGroup={facetActiveGroup}\n color={colorMap.get(facetActiveGroup) ?? barColor}\n onGroupClick={onGroupClick}\n />,\n );\n } else if (grouped && groupNames.length > 0) {\n elements.push(\n <StackedBars\n key={`bars-${stageIndex}`}\n common={common}\n stackOrder={stackOrder}\n colorMap={colorMap}\n fallbackColor={barColor}\n hoveredGroup={facetHoveredGroup}\n onGroupHover={onGroupHover}\n onGroupClick={onGroupClick}\n />,\n );\n } else {\n elements.push(\n <UngroupedBars key={`bars-${stageIndex}`} common={common} barColor={barColor} />,\n );\n }\n }\n\n return <g>{elements}</g>;\n});\n"],"mappings":";;;;;AAaA,MAAa,IAAO,EAAK,SAAc,EACrC,WACA,aACA,aACA,UACA,eAOC;CACD,IAAM,EAAE,WAAQ,WAAQ,cAAW,GAC7B,EAAE,YAAS,eAAY,qBAAkB,sBAAmB,kBAAe,GAC3E,EAAE,aAAU,SAAS,GAAc,gBAAa,GAChD,EAAE,iBAAc,iBAAc,mBAAgB,sBAAmB,GAEjE,IAAW,EAAO,WAAW,EAC7B,IAA2B,EAAE;AAEnC,MAAK,IAAM,CAAC,GAAY,MAAU,EAAO,SAAS,EAAE;AAClD,MAAI,EAAM,UAAU,EAAG;EACvB,IAAM,IAAO,EAAO,OAAO,EAAW,CAAC,IAAI,GACrC,IAAqB;GACzB;GACA;GACA,UAAU;IAAE;IAAM,OAAO;IAAU,SAAS,IAAO,IAAW;IAAG;IAAQ;IAAQ;GACjF;GACA,SAAS;IAAE,SAAS;IAAgB,SAAS;IAAgB;GAC9D;AAED,EAAI,KAAW,EAAW,SAAS,KAAK,IACtC,EAAS,KACP,kBAAC,GAAD;GAEU;GACU;GAClB,OAAO,EAAS,IAAI,EAAiB,IAAI;GAC3B;GACd,EALK,QAAQ,IAKb,CACH,GACQ,KAAW,EAAW,SAAS,IACxC,EAAS,KACP,kBAAC,GAAD;GAEU;GACI;GACF;GACV,eAAe;GACf,cAAc;GACA;GACA;GACd,EARK,QAAQ,IAQb,CACH,GAED,EAAS,KACP,kBAAC,GAAD;GAAkD;GAAkB;GAAY,EAA5D,QAAQ,IAAoD,CACjF;;AAIL,QAAO,kBAAC,KAAD,EAAA,UAAI,GAAa,CAAA;EACxB"}
@@ -0,0 +1,7 @@
1
+ import { CellLayout, ChartXAxis, ChartYAxis } from './types';
2
+ export declare const ChartAxes: import('react').NamedExoticComponent<{
3
+ layout: CellLayout;
4
+ xAxis: ChartXAxis;
5
+ yAxis: ChartYAxis;
6
+ }>;
7
+ //# sourceMappingURL=ChartAxes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartAxes.d.ts","sourceRoot":"","sources":["../../../../src/selection/components/Chart/ChartAxes.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKlE,eAAO,MAAM,SAAS;YAKZ,UAAU;WACX,UAAU;WACV,UAAU;EAkEjB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import "../../../constants.js";
2
+ import { BandAxis as e } from "../../../common/BandAxis.js";
3
+ import { ContinuousAxis as t } from "../../../common/ContinuousAxis.js";
4
+ import { formatPercent as n } from "../../utils.js";
5
+ import { memo as r } from "react";
6
+ import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
7
+ const s = r(function({ layout: r, xAxis: s, yAxis: c }) {
8
+ let { xScale: l, yScale: u, width: d, height: f, paddingLeft: p, paddingBottom: m, showXAxis: h, showYAxis: g } = r, { labelsPosition: _ = "center", showTicks: v = !0, hiddenLabels: y = !1, title: b = "" } = s, { showTicks: x = !0, hiddenLabels: S = !1, title: C = "" } = c;
9
+ return /* @__PURE__ */ o(i, { children: [
10
+ h && /* @__PURE__ */ a("g", {
11
+ transform: `translate(0,${f})`,
12
+ children: /* @__PURE__ */ a(e, {
13
+ scale: l,
14
+ orient: "bottom",
15
+ labels: s.labels,
16
+ labelsPosition: _,
17
+ tickSize: v ? 4 : 0,
18
+ hiddenLabels: y
19
+ })
20
+ }),
21
+ g && /* @__PURE__ */ a(t, {
22
+ scale: u,
23
+ orient: "left",
24
+ tickSize: x ? 4 : 0,
25
+ tickFormat: n,
26
+ hiddenLabels: S
27
+ }),
28
+ b && /* @__PURE__ */ a("text", {
29
+ x: d / 2,
30
+ y: f + m - 6,
31
+ textAnchor: "middle",
32
+ fontSize: "14px",
33
+ fontWeight: "500",
34
+ fontFamily: "Manrope",
35
+ fill: "#110529",
36
+ children: b
37
+ }),
38
+ C && /* @__PURE__ */ a("text", {
39
+ transform: `translate(${-p + 14},${f / 2}) rotate(-90)`,
40
+ textAnchor: "middle",
41
+ fontSize: "14px",
42
+ fontWeight: "500",
43
+ fontFamily: "Manrope",
44
+ fill: "#110529",
45
+ children: C
46
+ })
47
+ ] });
48
+ });
49
+ export { s as ChartAxes };
50
+
51
+ //# sourceMappingURL=ChartAxes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartAxes.js","names":[],"sources":["../../../../src/selection/components/Chart/ChartAxes.tsx"],"sourcesContent":["import { memo } from 'react';\n\nimport { BandAxis } from '../../../common/BandAxis';\nimport { ContinuousAxis } from '../../../common/ContinuousAxis';\nimport { BLACK } from '../../../constants';\nimport { formatPercent } from '../../utils';\nimport type { CellLayout, ChartXAxis, ChartYAxis } from './types';\n\n// X (band) axis at the bottom + Y (continuous, percent) axis on the left.\n// Each is gated by show flag; titles render as separate <text> nodes outside\n// the axis components for layout independence.\nexport const ChartAxes = memo(function ChartAxes({\n layout,\n xAxis,\n yAxis,\n}: {\n layout: CellLayout;\n xAxis: ChartXAxis;\n yAxis: ChartYAxis;\n}) {\n const { xScale, yScale, width, height, paddingLeft, paddingBottom, showXAxis, showYAxis } =\n layout;\n const {\n labelsPosition: xLabelsPosition = 'center',\n showTicks: xShowTicks = true,\n hiddenLabels: xHiddenLabels = false,\n title: xAxisTitle = '',\n } = xAxis;\n const {\n showTicks: yShowTicks = true,\n hiddenLabels: yHiddenLabels = false,\n title: yAxisTitle = '',\n } = yAxis;\n\n return (\n <>\n {showXAxis && (\n <g transform={`translate(0,${height})`}>\n <BandAxis\n scale={xScale}\n orient=\"bottom\"\n labels={xAxis.labels}\n labelsPosition={xLabelsPosition}\n tickSize={xShowTicks ? 4 : 0}\n hiddenLabels={xHiddenLabels}\n />\n </g>\n )}\n {showYAxis && (\n <ContinuousAxis\n scale={yScale}\n orient=\"left\"\n tickSize={yShowTicks ? 4 : 0}\n tickFormat={formatPercent}\n hiddenLabels={yHiddenLabels}\n />\n )}\n {xAxisTitle && (\n <text\n x={width / 2}\n y={height + paddingBottom - 6}\n textAnchor=\"middle\"\n fontSize=\"14px\"\n fontWeight=\"500\"\n fontFamily=\"Manrope\"\n fill={BLACK}\n >\n {xAxisTitle}\n </text>\n )}\n {yAxisTitle && (\n <text\n transform={`translate(${-paddingLeft + 14},${height / 2}) rotate(-90)`}\n textAnchor=\"middle\"\n fontSize=\"14px\"\n fontWeight=\"500\"\n fontFamily=\"Manrope\"\n fill={BLACK}\n >\n {yAxisTitle}\n </text>\n )}\n </>\n );\n});\n"],"mappings":";;;;;;AAWA,MAAa,IAAY,EAAK,SAAmB,EAC/C,WACA,UACA,YAKC;CACD,IAAM,EAAE,WAAQ,WAAQ,UAAO,WAAQ,gBAAa,kBAAe,cAAW,iBAC5E,GACI,EACJ,gBAAgB,IAAkB,UAClC,WAAW,IAAa,IACxB,cAAc,IAAgB,IAC9B,OAAO,IAAa,OAClB,GACE,EACJ,WAAW,IAAa,IACxB,cAAc,IAAgB,IAC9B,OAAO,IAAa,OAClB;AAEJ,QACE,kBAAA,GAAA,EAAA,UAAA;EACG,KACC,kBAAC,KAAD;GAAG,WAAW,eAAe,EAAO;aAClC,kBAAC,GAAD;IACE,OAAO;IACP,QAAO;IACP,QAAQ,EAAM;IACd,gBAAgB;IAChB,UAAU,IAAa,IAAI;IAC3B,cAAc;IACd,CAAA;GACA,CAAA;EAEL,KACC,kBAAC,GAAD;GACE,OAAO;GACP,QAAO;GACP,UAAU,IAAa,IAAI;GAC3B,YAAY;GACZ,cAAc;GACd,CAAA;EAEH,KACC,kBAAC,QAAD;GACE,GAAG,IAAQ;GACX,GAAG,IAAS,IAAgB;GAC5B,YAAW;GACX,UAAS;GACT,YAAW;GACX,YAAW;GACX,MAAA;aAEC;GACI,CAAA;EAER,KACC,kBAAC,QAAD;GACE,WAAW,aAAa,CAAC,IAAc,GAAG,GAAG,IAAS,EAAE;GACxD,YAAW;GACX,UAAS;GACT,YAAW;GACX,YAAW;GACX,MAAA;aAEC;GACI,CAAA;EAER,EAAA,CAAA;EAEL"}
@@ -0,0 +1,9 @@
1
+ import { FrameType } from '../../../types';
2
+ export declare const ChartFrame: import('react').NamedExoticComponent<{
3
+ width: number;
4
+ height: number;
5
+ frameType: FrameType;
6
+ xShowGrid: boolean;
7
+ yShowGrid: boolean;
8
+ }>;
9
+ //# sourceMappingURL=ChartFrame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartFrame.d.ts","sourceRoot":"","sources":["../../../../src/selection/components/Chart/ChartFrame.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD,eAAO,MAAM,UAAU;WAOd,MAAM;YACL,MAAM;eACH,SAAS;eACT,OAAO;eACP,OAAO;EAqClB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import "../../../constants.js";
2
+ import { memo as e } from "react";
3
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
4
+ const r = e(function({ width: e, height: r, frameType: i, xShowGrid: a, yShowGrid: o }) {
5
+ return i === "empty" ? null : /* @__PURE__ */ n("g", {
6
+ strokeWidth: 1,
7
+ children: [
8
+ (a || i !== "left") && /* @__PURE__ */ t("line", {
9
+ stroke: i === "left" ? "#E1E3EB" : "#110529",
10
+ x1: "0",
11
+ x2: e,
12
+ y1: r,
13
+ y2: r
14
+ }),
15
+ (a || i !== "bottom") && /* @__PURE__ */ t("line", {
16
+ stroke: i === "bottom" ? "#E1E3EB" : "#110529",
17
+ x1: "0",
18
+ x2: "0",
19
+ y1: "0",
20
+ y2: r
21
+ }),
22
+ (a || i === "full") && /* @__PURE__ */ t("line", {
23
+ stroke: i === "full" ? "#110529" : "#E1E3EB",
24
+ x1: e,
25
+ x2: e,
26
+ y1: "0",
27
+ y2: r
28
+ }),
29
+ (o || i === "full") && /* @__PURE__ */ t("line", {
30
+ stroke: i === "full" ? "#110529" : "#E1E3EB",
31
+ x1: "0",
32
+ x2: e,
33
+ y1: "0",
34
+ y2: "0"
35
+ })
36
+ ]
37
+ });
38
+ });
39
+ export { r as ChartFrame };
40
+
41
+ //# sourceMappingURL=ChartFrame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChartFrame.js","names":[],"sources":["../../../../src/selection/components/Chart/ChartFrame.tsx"],"sourcesContent":["import { memo } from 'react';\n\nimport { BLACK, GRID_GRAY } from '../../../constants';\nimport type { FrameType } from '../../../types';\n\n// Border lines around the plot body. `frameType` picks which sides are BLACK\n// (drawn as the prominent axis line) vs GRID_GRAY (drawn for visual closure\n// only when the corresponding gridline is on or `frameType === 'full'`).\nexport const ChartFrame = memo(function ChartFrame({\n width,\n height,\n frameType,\n xShowGrid,\n yShowGrid,\n}: {\n width: number;\n height: number;\n frameType: FrameType;\n xShowGrid: boolean;\n yShowGrid: boolean;\n}) {\n if (frameType === 'empty') return null;\n return (\n <g strokeWidth={1}>\n {(xShowGrid || frameType !== 'left') && (\n <line\n stroke={frameType === 'left' ? GRID_GRAY : BLACK}\n x1=\"0\"\n x2={width}\n y1={height}\n y2={height}\n />\n )}\n {(xShowGrid || frameType !== 'bottom') && (\n <line\n stroke={frameType === 'bottom' ? GRID_GRAY : BLACK}\n x1=\"0\"\n x2=\"0\"\n y1=\"0\"\n y2={height}\n />\n )}\n {(xShowGrid || frameType === 'full') && (\n <line\n stroke={frameType === 'full' ? BLACK : GRID_GRAY}\n x1={width}\n x2={width}\n y1=\"0\"\n y2={height}\n />\n )}\n {(yShowGrid || frameType === 'full') && (\n <line stroke={frameType === 'full' ? BLACK : GRID_GRAY} x1=\"0\" x2={width} y1=\"0\" y2=\"0\" />\n )}\n </g>\n );\n});\n"],"mappings":";;;AAQA,MAAa,IAAa,EAAK,SAAoB,EACjD,UACA,WACA,cACA,cACA,gBAOC;AAED,QADI,MAAc,UAAgB,OAEhC,kBAAC,KAAD;EAAG,aAAa;YAAhB;IACI,KAAa,MAAc,WAC3B,kBAAC,QAAD;IACE,QAAQ,MAAc,SAAA,YAAA;IACtB,IAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,CAAA;IAEF,KAAa,MAAc,aAC3B,kBAAC,QAAD;IACE,QAAQ,MAAc,WAAA,YAAA;IACtB,IAAG;IACH,IAAG;IACH,IAAG;IACH,IAAI;IACJ,CAAA;IAEF,KAAa,MAAc,WAC3B,kBAAC,QAAD;IACE,QAAQ,MAAc,SAAA,YAAA;IACtB,IAAI;IACJ,IAAI;IACJ,IAAG;IACH,IAAI;IACJ,CAAA;IAEF,KAAa,MAAc,WAC3B,kBAAC,QAAD;IAAM,QAAQ,MAAc,SAAA,YAAA;IAA4B,IAAG;IAAI,IAAI;IAAO,IAAG;IAAI,IAAG;IAAM,CAAA;GAE1F;;EAEN"}