@milaboratories/miplots4 1.1.0 → 1.2.0

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 (139) 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/common/ContinuousAxis.d.ts +3 -1
  5. package/dist/common/ContinuousAxis.d.ts.map +1 -1
  6. package/dist/common/ContinuousAxis.js +8 -8
  7. package/dist/common/ContinuousAxis.js.map +1 -1
  8. package/dist/common/Legend.d.ts +12 -1
  9. package/dist/common/Legend.d.ts.map +1 -1
  10. package/dist/common/Legend.js +14 -6
  11. package/dist/common/Legend.js.map +1 -1
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/selection/ChartRenderer.d.ts +90 -0
  15. package/dist/selection/ChartRenderer.d.ts.map +1 -0
  16. package/dist/selection/ChartRenderer.js +254 -0
  17. package/dist/selection/ChartRenderer.js.map +1 -0
  18. package/dist/selection/SelectionSettingsImpl.d.ts +53 -0
  19. package/dist/selection/SelectionSettingsImpl.d.ts.map +1 -0
  20. package/dist/selection/SelectionSettingsImpl.js +47 -0
  21. package/dist/selection/SelectionSettingsImpl.js.map +1 -0
  22. package/dist/selection/components/Chart/Bars/GroupSelectedBars.d.ts +8 -0
  23. package/dist/selection/components/Chart/Bars/GroupSelectedBars.d.ts.map +1 -0
  24. package/dist/selection/components/Chart/Bars/GroupSelectedBars.js +57 -0
  25. package/dist/selection/components/Chart/Bars/GroupSelectedBars.js.map +1 -0
  26. package/dist/selection/components/Chart/Bars/StackedBars.d.ts +12 -0
  27. package/dist/selection/components/Chart/Bars/StackedBars.d.ts.map +1 -0
  28. package/dist/selection/components/Chart/Bars/StackedBars.js +58 -0
  29. package/dist/selection/components/Chart/Bars/StackedBars.js.map +1 -0
  30. package/dist/selection/components/Chart/Bars/UngroupedBars.d.ts +6 -0
  31. package/dist/selection/components/Chart/Bars/UngroupedBars.d.ts.map +1 -0
  32. package/dist/selection/components/Chart/Bars/UngroupedBars.js +38 -0
  33. package/dist/selection/components/Chart/Bars/UngroupedBars.js.map +1 -0
  34. package/dist/selection/components/Chart/Bars.d.ts +10 -0
  35. package/dist/selection/components/Chart/Bars.d.ts.map +1 -0
  36. package/dist/selection/components/Chart/Bars.js +48 -0
  37. package/dist/selection/components/Chart/Bars.js.map +1 -0
  38. package/dist/selection/components/Chart/ChartAxes.d.ts +7 -0
  39. package/dist/selection/components/Chart/ChartAxes.d.ts.map +1 -0
  40. package/dist/selection/components/Chart/ChartAxes.js +51 -0
  41. package/dist/selection/components/Chart/ChartAxes.js.map +1 -0
  42. package/dist/selection/components/Chart/ChartFrame.d.ts +9 -0
  43. package/dist/selection/components/Chart/ChartFrame.d.ts.map +1 -0
  44. package/dist/selection/components/Chart/ChartFrame.js +41 -0
  45. package/dist/selection/components/Chart/ChartFrame.js.map +1 -0
  46. package/dist/selection/components/Chart/Dividers.d.ts +8 -0
  47. package/dist/selection/components/Chart/Dividers.d.ts.map +1 -0
  48. package/dist/selection/components/Chart/Dividers.js +27 -0
  49. package/dist/selection/components/Chart/Dividers.js.map +1 -0
  50. package/dist/selection/components/Chart/Gridlines.d.ts +10 -0
  51. package/dist/selection/components/Chart/Gridlines.d.ts.map +1 -0
  52. package/dist/selection/components/Chart/Gridlines.js +32 -0
  53. package/dist/selection/components/Chart/Gridlines.js.map +1 -0
  54. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.d.ts +9 -0
  55. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.d.ts.map +1 -0
  56. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.js +36 -0
  57. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.js.map +1 -0
  58. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.d.ts +6 -0
  59. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.d.ts.map +1 -0
  60. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.js +22 -0
  61. package/dist/selection/components/Chart/Ribbons/MultiGroupRibbon.js.map +1 -0
  62. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.d.ts +10 -0
  63. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.d.ts.map +1 -0
  64. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.js +33 -0
  65. package/dist/selection/components/Chart/Ribbons/SimpleRibbon.js.map +1 -0
  66. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.d.ts +10 -0
  67. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.d.ts.map +1 -0
  68. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.js +65 -0
  69. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.js.map +1 -0
  70. package/dist/selection/components/Chart/Ribbons/ribbonPath.d.ts +10 -0
  71. package/dist/selection/components/Chart/Ribbons/ribbonPath.d.ts.map +1 -0
  72. package/dist/selection/components/Chart/Ribbons/ribbonPath.js +13 -0
  73. package/dist/selection/components/Chart/Ribbons/ribbonPath.js.map +1 -0
  74. package/dist/selection/components/Chart/Ribbons.d.ts +9 -0
  75. package/dist/selection/components/Chart/Ribbons.d.ts.map +1 -0
  76. package/dist/selection/components/Chart/Ribbons.js +58 -0
  77. package/dist/selection/components/Chart/Ribbons.js.map +1 -0
  78. package/dist/selection/components/Chart/StageCounts.d.ts +7 -0
  79. package/dist/selection/components/Chart/StageCounts.d.ts.map +1 -0
  80. package/dist/selection/components/Chart/StageCounts.js +20 -0
  81. package/dist/selection/components/Chart/StageCounts.js.map +1 -0
  82. package/dist/selection/components/Chart/types.d.ts +132 -0
  83. package/dist/selection/components/Chart/types.d.ts.map +1 -0
  84. package/dist/selection/components/Chart.d.ts +22 -0
  85. package/dist/selection/components/Chart.d.ts.map +1 -0
  86. package/dist/selection/components/Chart.js +97 -0
  87. package/dist/selection/components/Chart.js.map +1 -0
  88. package/dist/selection/components/ChartsGroup.d.ts +18 -0
  89. package/dist/selection/components/ChartsGroup.d.ts.map +1 -0
  90. package/dist/selection/components/ChartsGroup.js +181 -0
  91. package/dist/selection/components/ChartsGroup.js.map +1 -0
  92. package/dist/selection/components/FacetCell.d.ts +22 -0
  93. package/dist/selection/components/FacetCell.d.ts.map +1 -0
  94. package/dist/selection/components/FacetCell.js +18 -0
  95. package/dist/selection/components/FacetCell.js.map +1 -0
  96. package/dist/selection/components/types.d.ts +58 -0
  97. package/dist/selection/components/types.d.ts.map +1 -0
  98. package/dist/selection/constants.d.ts +25 -0
  99. package/dist/selection/constants.d.ts.map +1 -0
  100. package/dist/selection/constants.js +4 -0
  101. package/dist/selection/constants.js.map +1 -0
  102. package/dist/selection/createSelectionData.d.ts +50 -0
  103. package/dist/selection/createSelectionData.d.ts.map +1 -0
  104. package/dist/selection/createSelectionData.js +92 -0
  105. package/dist/selection/createSelectionData.js.map +1 -0
  106. package/dist/selection/index.d.ts +26 -0
  107. package/dist/selection/index.d.ts.map +1 -0
  108. package/dist/selection/index.js +96 -0
  109. package/dist/selection/index.js.map +1 -0
  110. package/dist/selection/utils.d.ts +4 -0
  111. package/dist/selection/utils.d.ts.map +1 -0
  112. package/dist/selection/utils.js +13 -0
  113. package/dist/selection/utils.js.map +1 -0
  114. package/dist/types/bubble.d.ts +42 -0
  115. package/dist/types/bubble.d.ts.map +1 -1
  116. package/dist/types/common.d.ts +38 -0
  117. package/dist/types/common.d.ts.map +1 -1
  118. package/dist/types/common.js +1 -0
  119. package/dist/types/common.js.map +1 -1
  120. package/dist/types/dendro.d.ts +103 -0
  121. package/dist/types/dendro.d.ts.map +1 -1
  122. package/dist/types/discrete.d.ts +167 -0
  123. package/dist/types/discrete.d.ts.map +1 -1
  124. package/dist/types/heatmap.d.ts +159 -0
  125. package/dist/types/heatmap.d.ts.map +1 -1
  126. package/dist/types/histogram.d.ts +22 -0
  127. package/dist/types/histogram.d.ts.map +1 -1
  128. package/dist/types/index.d.ts +3 -1
  129. package/dist/types/index.d.ts.map +1 -1
  130. package/dist/types/index.js +1 -0
  131. package/dist/types/scatterplot-umap.d.ts +188 -0
  132. package/dist/types/scatterplot-umap.d.ts.map +1 -1
  133. package/dist/types/scatterplot.d.ts +270 -0
  134. package/dist/types/scatterplot.d.ts.map +1 -1
  135. package/dist/types/selection.d.ts +452 -0
  136. package/dist/types/selection.d.ts.map +1 -0
  137. package/dist/types/selection.js +53 -0
  138. package/dist/types/selection.js.map +1 -0
  139. package/package.json +2 -2
@@ -0,0 +1,254 @@
1
+ import { Error as e } from "../common/Error.js";
2
+ import { TextMeasurer as t } from "../utils/TextMeasurer/TextMeasurer.js";
3
+ import { arrangeLegendParts as n } from "../utils/arrangeLegendParts.js";
4
+ import { splitTextByWidth as r } from "../utils/splitTextByWidth.js";
5
+ import "../discrete/utils/index.js";
6
+ import { AGGREGATE_RIBBON_COLOR as i } from "./constants.js";
7
+ import { formatCount as a, formatPercent as o } from "./utils.js";
8
+ import { ChartsGroup as s } from "./components/ChartsGroup.js";
9
+ import { scaleOrdinal as c } from "d3-scale";
10
+ import { createRoot as l } from "react-dom/client";
11
+ import { Fragment as u, jsx as d } from "react/jsx-runtime";
12
+ var f = class {
13
+ reactRoot = null;
14
+ parentNode = null;
15
+ rootNode = null;
16
+ component = /* @__PURE__ */ d(u, {});
17
+ cellPlotWidth = 0;
18
+ cellPlotHeight = 0;
19
+ nCols = 1;
20
+ nRows = 1;
21
+ isFaceted = !1;
22
+ cellLabelHeight = 0;
23
+ orderedFaceted = {
24
+ facetKeys: [],
25
+ byFacet: {},
26
+ groupNames: []
27
+ };
28
+ facetLabels = {};
29
+ facetTitles = {};
30
+ grouped = !1;
31
+ groupNames = [];
32
+ colorMap = /* @__PURE__ */ new Map();
33
+ solidColor = "";
34
+ xLabelsByFacet = {};
35
+ xCountsByFacet = {};
36
+ xLabelsPosition = "center";
37
+ maxLabelLines = 1;
38
+ maxLabelPx = 0;
39
+ yTickWidth = 0;
40
+ labelBlock = 0;
41
+ xTitleHeight = 0;
42
+ yTitleWidth = 0;
43
+ yTickReserve = 0;
44
+ xLabelTopReserve = 0;
45
+ topPad = 0;
46
+ rightPad = 12;
47
+ fullLeftPad = 0;
48
+ fullBottomPad = 0;
49
+ colLeftPads = [];
50
+ rowBottomPads = [];
51
+ colXOffsets = [0];
52
+ rowYOffsets = [0];
53
+ gridWidth = 0;
54
+ gridHeight = 0;
55
+ legend = {
56
+ width: 0,
57
+ height: 0,
58
+ items: []
59
+ };
60
+ mainTitle = [];
61
+ margins = {
62
+ top: 24,
63
+ bottom: 24,
64
+ left: 24,
65
+ right: 24
66
+ };
67
+ totalWidth = 0;
68
+ totalHeight = 0;
69
+ clear() {
70
+ this.parentNode && this.rootNode && (this.parentNode.removeChild(this.rootNode), this.parentNode = null, this.rootNode = null), setTimeout(() => {
71
+ this.reactRoot?.unmount(), this.reactRoot = null;
72
+ });
73
+ }
74
+ init(e) {
75
+ this.parentNode === null && (this.parentNode = e, this.rootNode = document.createElement("div"), this.parentNode.appendChild(this.rootNode), this.reactRoot = l(this.rootNode));
76
+ }
77
+ updateChartSizes(e, t) {
78
+ this.cellPlotWidth = e, this.cellPlotHeight = t;
79
+ }
80
+ updateGrid({ faceted: e, facetLabels: t, facetBy: n, facetSettings: i }) {
81
+ let a = i.order?.length ? i.order.filter((t) => e.facetKeys.includes(t)) : e.facetKeys;
82
+ if (this.orderedFaceted = {
83
+ ...e,
84
+ facetKeys: a
85
+ }, this.facetLabels = t, this.isFaceted = n.length > 0, this.isFaceted) {
86
+ let e = Math.max(this.cellPlotWidth, 40);
87
+ this.facetTitles = {};
88
+ let n = 1;
89
+ for (let i of a) {
90
+ let a = (t[i] ?? []).join(" / "), o = a ? r(a, e, 20) : [];
91
+ this.facetTitles[i] = o, o.length > n && (n = o.length);
92
+ }
93
+ this.cellLabelHeight = 48 + (n - 1) * 24;
94
+ } else this.facetTitles = {}, this.cellLabelHeight = 0;
95
+ let o = a.length;
96
+ this.nCols = Math.min(o, i.nCols ?? Math.max(1, Math.ceil(Math.sqrt(o)))), this.nRows = i.nRows ?? Math.max(1, Math.ceil(o / this.nCols));
97
+ }
98
+ updateGroupingMaps(e, t) {
99
+ let n = typeof t == "object" && !!t;
100
+ this.grouped = n && !!e;
101
+ let r = e?.order ? e.order.map(String).filter((e) => this.orderedFaceted.groupNames.includes(e)) : this.orderedFaceted.groupNames;
102
+ this.groupNames = [...r, ...this.orderedFaceted.groupNames.filter((e) => !r.includes(e))];
103
+ let a = e?.inheritedAes;
104
+ if (this.colorMap = /* @__PURE__ */ new Map(), this.grouped && a) for (let e of this.groupNames) {
105
+ let t = a[e]?.fillColor;
106
+ t && this.colorMap.set(e, t);
107
+ }
108
+ this.solidColor = n ? i : t;
109
+ }
110
+ createAxisLabels(e) {
111
+ let n = new t("500 14px Manrope"), i = this.orderedFaceted.facetKeys, o = i.map((e) => this.orderedFaceted.byFacet[e]?.stages.length ?? 0).reduce((e, t) => Math.max(e, t), 0), s = 0;
112
+ for (let e of i) for (let t of this.orderedFaceted.byFacet[e]?.stages ?? []) s = Math.max(s, n.getTextWidth(t.label));
113
+ this.maxLabelPx = s;
114
+ let c = o > 0 ? this.cellPlotWidth / o : this.cellPlotWidth;
115
+ this.xLabelsPosition = e.labelsPosition ?? (s > c * .65 ? "90deg" : "center");
116
+ let l = this.xLabelsPosition !== "center";
117
+ this.xLabelsByFacet = {}, this.xCountsByFacet = {}, this.maxLabelLines = 1;
118
+ for (let e of i) {
119
+ let t = this.orderedFaceted.byFacet[e]?.stages ?? [], n = {}, i = {};
120
+ for (let [e, o] of t.entries()) {
121
+ let t = l ? [o.label] : r(o.label, 120, 14);
122
+ n[String(e)] = t, i[String(e)] = a(o.total), this.maxLabelLines = Math.max(this.maxLabelLines, t.length);
123
+ }
124
+ this.xLabelsByFacet[e] = n, this.xCountsByFacet[e] = i;
125
+ }
126
+ }
127
+ updateCaptionsSize(e, n) {
128
+ let r = new t("500 14px Manrope");
129
+ n.hiddenLabels ? (this.yTickWidth = 0, this.yTickReserve = n.showTicks ? 4 : 0) : (this.yTickWidth = r.getTextWidth(o(100)), this.yTickReserve = 40), e.hiddenLabels ? (this.labelBlock = 0, this.xLabelTopReserve = e.showTicks ? 4 : 0) : (this.labelBlock = this.xLabelsPosition === "center" ? this.maxLabelLines * 20 : this.xLabelsPosition === "45deg" ? Math.ceil(this.maxLabelPx * .71) + 10 : Math.ceil(this.maxLabelPx) + 10, this.xLabelTopReserve = 6), this.xTitleHeight = e.title ? 26 : 0, this.yTitleWidth = n.title ? 24 : 0;
130
+ }
131
+ updateChartDimensions() {
132
+ this.fullLeftPad = this.yTitleWidth + this.yTickWidth + this.yTickReserve, this.fullBottomPad = this.xLabelTopReserve + this.labelBlock + this.xTitleHeight, this.topPad = 20, this.rightPad = 12, this.colLeftPads = Array.from({ length: this.nCols }, (e, t) => !this.isFaceted || t === 0 ? this.fullLeftPad : 12);
133
+ let e = this.orderedFaceted.facetKeys.length % this.nCols !== 0;
134
+ this.rowBottomPads = Array.from({ length: this.nRows }, (t, n) => {
135
+ let r = n === this.nRows - 1 || n === this.nRows - 2 && e;
136
+ return !this.isFaceted || r ? this.fullBottomPad : 12;
137
+ }), this.colXOffsets = [0];
138
+ for (let [e, t] of this.colLeftPads.entries()) this.colXOffsets.push(this.colXOffsets[e] + t + this.cellPlotWidth + this.rightPad);
139
+ this.rowYOffsets = [0];
140
+ for (let [e, t] of this.rowBottomPads.entries()) this.rowYOffsets.push(this.rowYOffsets[e] + this.topPad + this.cellLabelHeight + this.cellPlotHeight + t);
141
+ this.gridWidth = this.colXOffsets[this.nCols], this.gridHeight = this.rowYOffsets[this.nRows];
142
+ }
143
+ updateLegendSize(e, t) {
144
+ if (!e || !this.grouped || this.groupNames.length === 0) {
145
+ this.legend = {
146
+ width: 0,
147
+ height: 0,
148
+ items: []
149
+ };
150
+ return;
151
+ }
152
+ let r = n([{
153
+ id: "selection-group",
154
+ type: "discreteColor",
155
+ title: t?.columnName.label ?? t?.columnName.value ?? "",
156
+ width: 0,
157
+ height: 0,
158
+ left: 0,
159
+ top: 0,
160
+ values: this.groupNames,
161
+ scale: c().domain(this.groupNames).range(this.groupNames.map((e) => this.colorMap.get(e) ?? "")),
162
+ labels: Object.fromEntries(this.groupNames.map((e) => [e, e === "null" ? t?.columnName.nullValueLabel ?? "N/A" : e]))
163
+ }], this.cellPlotHeight);
164
+ this.legend = {
165
+ width: r.reduce((e, t) => Math.max(e, t.left + t.width), 0) + 24,
166
+ height: this.cellPlotHeight,
167
+ items: r
168
+ };
169
+ }
170
+ createMainTitle(e, t) {
171
+ this.mainTitle = t && e ? r(e, Math.max(this.cellPlotWidth, 40), 20) : [];
172
+ }
173
+ updateMargins() {
174
+ let e = this.mainTitle.length > 0 ? this.mainTitle.length * 24 + 48 : 0;
175
+ this.margins = {
176
+ top: Math.max(e, 24),
177
+ bottom: 24,
178
+ left: 24,
179
+ right: 24 + this.legend.width
180
+ }, this.totalWidth = this.margins.left + this.gridWidth + this.margins.right, this.totalHeight = this.margins.top + this.gridHeight + this.margins.bottom;
181
+ }
182
+ render({ faceted: e, facetLabels: t, width: n, height: r, title: i, showTitle: a, grouping: o, showLegend: c, facetBy: l, facetSettings: u, xAxis: f, yAxis: p, frame: m, titlePosition: h, fillColor: g, opacity: _ }) {
183
+ this.updateChartSizes(n, r), this.updateGrid({
184
+ faceted: e,
185
+ facetLabels: t,
186
+ facetBy: l,
187
+ facetSettings: u
188
+ }), this.updateGroupingMaps(o, g), this.createAxisLabels(f), this.updateCaptionsSize(f, p), this.updateChartDimensions(), this.updateLegendSize(c, o), this.createMainTitle(i, a), this.updateMargins();
189
+ let v = /* @__PURE__ */ d(s, {
190
+ facetData: {
191
+ faceted: this.orderedFaceted,
192
+ facetLabels: this.facetLabels,
193
+ facetTitles: this.facetTitles
194
+ },
195
+ gridLayout: {
196
+ nRows: this.nRows,
197
+ nCols: this.nCols,
198
+ totalWidth: this.totalWidth,
199
+ totalHeight: this.totalHeight,
200
+ margins: this.margins,
201
+ cellPlotWidth: this.cellPlotWidth,
202
+ cellPlotHeight: this.cellPlotHeight,
203
+ cellLabelHeight: this.cellLabelHeight,
204
+ topPad: this.topPad,
205
+ rightPad: this.rightPad,
206
+ colLeftPads: this.colLeftPads,
207
+ rowBottomPads: this.rowBottomPads,
208
+ colXOffsets: this.colXOffsets,
209
+ rowYOffsets: this.rowYOffsets,
210
+ sharedX: this.isFaceted,
211
+ sharedY: this.isFaceted
212
+ },
213
+ xAxis: {
214
+ labelsByFacet: this.xLabelsByFacet,
215
+ countsByFacet: this.xCountsByFacet,
216
+ countsFontSize: 14,
217
+ labelsPosition: this.xLabelsPosition,
218
+ showGrid: f.showGrid,
219
+ showTicks: f.showTicks,
220
+ hiddenLabels: f.hiddenLabels,
221
+ title: f.title
222
+ },
223
+ yAxis: {
224
+ showGrid: p.showGrid,
225
+ showTicks: p.showTicks,
226
+ hiddenLabels: p.hiddenLabels,
227
+ title: p.title
228
+ },
229
+ style: {
230
+ frameType: this.isFaceted ? "full" : m,
231
+ barColor: this.solidColor,
232
+ opacity: _,
233
+ colorMap: this.colorMap,
234
+ nullValueLabel: o?.columnName.nullValueLabel
235
+ },
236
+ title: {
237
+ text: this.mainTitle,
238
+ show: this.mainTitle.length > 0,
239
+ position: h
240
+ },
241
+ legend: this.legend,
242
+ showFacetLabels: this.isFaceted,
243
+ grouped: this.grouped,
244
+ orderedGroupNames: this.groupNames
245
+ });
246
+ this.component = v, this.reactRoot?.render(v);
247
+ }
248
+ renderError(t) {
249
+ this.reactRoot?.render(/* @__PURE__ */ d(e, { message: t }));
250
+ }
251
+ };
252
+ export { f as default };
253
+
254
+ //# sourceMappingURL=ChartRenderer.js.map
@@ -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