@milaboratories/miplots4 1.2.2 → 1.2.4

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 (65) hide show
  1. package/dist/DataFrame.d.ts.map +1 -1
  2. package/dist/DataFrame.js +2 -1
  3. package/dist/DataFrame.js.map +1 -1
  4. package/dist/heatmap/ChartRenderer.d.ts.map +1 -1
  5. package/dist/heatmap/ChartRenderer.js +72 -78
  6. package/dist/heatmap/ChartRenderer.js.map +1 -1
  7. package/dist/selection/ChartRenderer.d.ts.map +1 -1
  8. package/dist/selection/ChartRenderer.js +9 -11
  9. package/dist/selection/ChartRenderer.js.map +1 -1
  10. package/dist/selection/SelectionSettingsImpl.d.ts +0 -1
  11. package/dist/selection/SelectionSettingsImpl.d.ts.map +1 -1
  12. package/dist/selection/SelectionSettingsImpl.js +0 -1
  13. package/dist/selection/SelectionSettingsImpl.js.map +1 -1
  14. package/dist/selection/components/Chart/Bars/GroupSelectedBars.js +1 -1
  15. package/dist/selection/components/Chart/Bars/GroupSelectedBars.js.map +1 -1
  16. package/dist/selection/components/Chart/Bars/StackedBars.d.ts.map +1 -1
  17. package/dist/selection/components/Chart/Bars/StackedBars.js +11 -11
  18. package/dist/selection/components/Chart/Bars/StackedBars.js.map +1 -1
  19. package/dist/selection/components/Chart/ChartAxes.d.ts.map +1 -1
  20. package/dist/selection/components/Chart/ChartAxes.js +7 -8
  21. package/dist/selection/components/Chart/ChartAxes.js.map +1 -1
  22. package/dist/selection/components/Chart/ChartFrame.d.ts +1 -2
  23. package/dist/selection/components/Chart/ChartFrame.d.ts.map +1 -1
  24. package/dist/selection/components/Chart/ChartFrame.js +8 -8
  25. package/dist/selection/components/Chart/ChartFrame.js.map +1 -1
  26. package/dist/selection/components/Chart/Gridlines.d.ts +2 -6
  27. package/dist/selection/components/Chart/Gridlines.d.ts.map +1 -1
  28. package/dist/selection/components/Chart/Gridlines.js +14 -26
  29. package/dist/selection/components/Chart/Gridlines.js.map +1 -1
  30. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.js +1 -1
  31. package/dist/selection/components/Chart/Ribbons/GroupFlowRibbon.js.map +1 -1
  32. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.d.ts.map +1 -1
  33. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.js +27 -27
  34. package/dist/selection/components/Chart/Ribbons/StackedGroupFlowRibbon.js.map +1 -1
  35. package/dist/selection/components/Chart/SelectionXAxis.d.ts +18 -0
  36. package/dist/selection/components/Chart/SelectionXAxis.d.ts.map +1 -0
  37. package/dist/selection/components/Chart/SelectionXAxis.js +47 -0
  38. package/dist/selection/components/Chart/SelectionXAxis.js.map +1 -0
  39. package/dist/selection/components/Chart/types.d.ts +0 -1
  40. package/dist/selection/components/Chart/types.d.ts.map +1 -1
  41. package/dist/selection/components/Chart.d.ts.map +1 -1
  42. package/dist/selection/components/Chart.js +7 -12
  43. package/dist/selection/components/Chart.js.map +1 -1
  44. package/dist/selection/components/ChartsGroup.d.ts.map +1 -1
  45. package/dist/selection/components/ChartsGroup.js +73 -72
  46. package/dist/selection/components/ChartsGroup.js.map +1 -1
  47. package/dist/selection/components/types.d.ts +0 -1
  48. package/dist/selection/components/types.d.ts.map +1 -1
  49. package/dist/selection/constants.d.ts +1 -2
  50. package/dist/selection/constants.d.ts.map +1 -1
  51. package/dist/selection/constants.js +2 -2
  52. package/dist/selection/constants.js.map +1 -1
  53. package/dist/selection/createSelectionData.d.ts +2 -6
  54. package/dist/selection/createSelectionData.d.ts.map +1 -1
  55. package/dist/selection/createSelectionData.js +45 -59
  56. package/dist/selection/createSelectionData.js.map +1 -1
  57. package/dist/types/selection.d.ts +0 -5
  58. package/dist/types/selection.d.ts.map +1 -1
  59. package/dist/types/selection.js +0 -1
  60. package/dist/types/selection.js.map +1 -1
  61. package/dist/utils/computeChartInnerSize.d.ts +18 -0
  62. package/dist/utils/computeChartInnerSize.d.ts.map +1 -0
  63. package/dist/utils/computeChartInnerSize.js +22 -0
  64. package/dist/utils/computeChartInnerSize.js.map +1 -0
  65. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/heatmap/ChartRenderer.tsx"],"sourcesContent":["import { extent } from 'd3-array';\nimport type { HierarchyNode, HierarchyPointNode } from 'd3-hierarchy';\nimport { cluster } from 'd3-hierarchy';\nimport type { ScaleLinear, ScaleOrdinal } from 'd3-scale';\nimport { scaleLinear, scaleOrdinal } from 'd3-scale';\nimport lodash from 'lodash';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\nimport { Error } from '../common/Error';\nimport type { LegendData, LegendItem } from '../common/types';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport { DEFAULT_HEIGHT, DEFAULT_WIDTH, MAX_LEGEND_GRADIENT_HEIGHT, MIN_LEGEND_GRADIENT_HEIGHT, TITLE_LINE_HEIGHT, TITLE_MARGIN } from '../constants';\nimport type { DataFrame } from '../DataFrame';\nimport type { AesItem, ColumnName, DataValue } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { getChartEdgeSides } from '../utils/getChartEdgeSides';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type {\n AnnotationColorScales,\n CaptionsSizes,\n ChartDendrograms,\n ChartDimensionsData,\n ChartSizes,\n ChartsScales,\n Cluster,\n DendrogramAesScales,\n LabelAngles,\n Margins,\n} from './components/types';\nimport { CHART_SIDE_ELEMENTS, DEFAULT_AES, LEGEND_OFFSET, MIN_MARGIN, TITLE_LINE } from './constants';\nimport type { GroupedCellsHeatmap } from './getCells';\nimport type { DendrogramsData } from './getDendrograms';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport {\n calculateAnnotationTitleSizes,\n calculateChartSideElementSizes,\n calculateSideElementsBBoxes,\n createContinuousColorScale,\n createDiscreteColorScale,\n createDiscreteRoundColorScale,\n} from './utils';\nimport { calculateCaptionTails } from './utils/calculateCaptionTails';\n\nconst COS_PI_4 = Math.cos(Math.PI / 4);\nconst INCLINE_OFFSET = 5; // height of little triangle of text for captions inclined 45deg\nfunction updateLinksHeight(root: HierarchyPointNode<Cluster>, scale: (v: number) => number, coord: 'x' | 'y') {\n function setHeight(d: HierarchyPointNode<Cluster>) {\n d[coord] = scale(d.data.height);\n if (d.children) d.children.forEach(setHeight);\n }\n setHeight(root);\n}\n\n// add shift to move nodes positions with group gaps\nfunction addShiftToLinkCoord(\n root: HierarchyPointNode<Cluster>,\n shift: number,\n coordFrom: 'x' | 'y',\n coordTo = coordFrom\n) {\n function setX(d: HierarchyPointNode<Cluster>) {\n d[coordTo] = d[coordFrom] + shift;\n if (d.children) d.children.forEach(setX);\n }\n setX(root);\n}\n\nconst getSteps = (count: number, valueExtent: number[]) => {\n const min = Math.min(...valueExtent);\n const max = Math.max(...valueExtent);\n if (min === max) {\n const steps = count % 2 === 0 ? [] : [min];\n for (let i = 1; i < count / 2 + 1; i++) {\n steps.push(min + i);\n steps.unshift(min - i);\n }\n return steps;\n }\n if (count < 2) {\n return [min, max];\n }\n const step = (max - min) / (count - 1);\n const steps = [];\n for (let i = 0; i < count - 1; i++) {\n steps.push(min + step * i);\n }\n steps.push(max);\n return steps;\n};\n\nfunction getContinuousColorRange(normalization: HeatmapSettingsImpl['normalization'], colorsCount: number, valueExtent: number[]) {\n let extent = valueExtent;\n if (normalization) {\n if (normalization.colorRange) {\n extent = normalization.colorRange;\n }\n if (normalization.method === 'standardScaling') {\n extent = [-2, 2];\n }\n if (normalization.method === 'meanNormalization') {\n extent = [-0.75, 0.75];\n }\n }\n return getSteps(colorsCount, extent);\n}\n\nfunction getMaxTextLength(keys: string[], labels: Record<string, string>, textMeasurer: TextMeasurer) {\n let maxLabelSize = 0;\n for (const key of keys) {\n if (labels[key] === undefined) continue;\n const l = textMeasurer.getTextWidth(labels[key]);\n if (l > maxLabelSize) maxLabelSize = l;\n }\n return maxLabelSize;\n}\n\nfunction getCaptionHeight(size: number, angle: number) {\n if (angle === 90) {\n return size;\n }\n if (angle === 45) {\n return size * COS_PI_4 + (size > 0 ? 2 * INCLINE_OFFSET : 0);\n }\n return TITLE_LINE;\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = (<></>);\n chartsDimensions: Record<string, ChartDimensionsData> = {};\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\n chartsWidth: DEFAULT_WIDTH, // width of all charts in charts row\n chartsHeight: DEFAULT_HEIGHT, // width of all charts in charts column, without axes\n totalWidth: DEFAULT_WIDTH, // width of all charts in charts row, plus left axis, plus legend\n totalHeight: DEFAULT_HEIGHT, // width of all charts in charts height, plus bottom axis, plus top title\n };\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n captionsSizes: CaptionsSizes = {\n xAxisCaptions: 100,\n yAxisCaptions: 100,\n xGroupCaptions: TITLE_LINE,\n yGroupCaptions: TITLE_LINE,\n xCaptionTail: 0,\n yCaptionTail: 0,\n };\n labelAngles: LabelAngles = {\n xAxisLabels: 0,\n yAxisLabels: 0,\n xGroupLabels: 0,\n yGroupLabels: 0,\n };\n columnsCount = 1;\n rowsCount = 1;\n scales: ChartsScales = {\n // scales grouped by facet\n x: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n y: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n };\n step: {\n x: Record<string, number>;\n y: Record<string, number>;\n } = { x: {}, y: {} };\n colorScale: ScaleLinear<string, string> | ScaleOrdinal<string, string, string> = scaleLinear<string, string>()\n .domain([0, 1])\n .range(['white', 'black']);\n annotationColorScales: AnnotationColorScales = {};\n dendrogramAesScales: DendrogramAesScales = {};\n legend: LegendData = {\n width: 0,\n height: 0,\n items: [],\n };\n dendrograms: Record<string, ChartDendrograms> = {};\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 // timeout to avoid trying to unmount during rendering\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 updateMargins(title: HeatmapSettingsImpl['chartSettings']['title'], size: HeatmapSettingsImpl['chartSettings']['size']) {\n this.margins = {\n top: title.show ? TITLE_LINE_HEIGHT + TITLE_MARGIN * 2 : size.outerOffset,\n bottom: size.outerOffset,\n left: size.outerOffset,\n right: this.legend.width + size.outerOffset,\n };\n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartsHeight + this.margins.bottom, this.legend.height);\n }\n\n updateLegendSize(\n valueType: HeatmapSettingsImpl['chartSettings']['valueType'],\n legend: HeatmapSettingsImpl['chartSettings']['legend'],\n annotations: HeatmapSettingsImpl['annotations'],\n columnValue: ColumnName,\n valueExtent: [number, number]\n ) {\n if (!legend.show) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n const continuousHeight = Math.min(\n Math.max(this.chartSizes.chartHeight, MIN_LEGEND_GRADIENT_HEIGHT),\n MAX_LEGEND_GRADIENT_HEIGHT\n );\n const legendHeight = Math.max(this.chartSizes.chartHeight, continuousHeight);\n const legendItems: LegendItem[] = [];\n const emptySizes = { width: 0, height: 0, left: 0, top: 0 };\n\n const getDefaultLabels = (values: (string | number)[]) => values.reduce((res: Record<string, string>, v: string | number) => { res[v] = String(v); return res; }, {});\n if (valueType === 'continuous') {\n const scale = this.colorScale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n const title = columnValue.label ?? columnValue.value;\n legendItems.push({\n ...emptySizes,\n type: 'continuous',\n id: 'heatmapValue',\n scale,\n values,\n title,\n tickPositionScale\n });\n } else if (valueType === 'discrete') {\n const scale = this.colorScale as ScaleOrdinal<string, string>;\n const title = columnValue.label ?? columnValue.value;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: 'heatmapValue', title, scale, values, labels });\n }\n annotations.forEach(item => {\n const title = item.valueColumn.label ?? item.valueColumn.value;\n if (item.type === 'continuous') {\n const scale = this.annotationColorScales[item.id].scale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n\n legendItems.push({ ...emptySizes, type: 'continuous', id: item.id, tickPositionScale, title, scale, values });\n }\n if (item.type === 'discrete') {\n const scale = this.annotationColorScales[item.id].scale as ScaleOrdinal<string, string>;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: item.id, title, scale, values, labels });\n }\n });\n\n if (!legendItems.length) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n\n const items = arrangeLegendParts(legendItems, this.chartSizes.chartHeight,continuousHeight);\n const maxRightEdge = items.reduce((max, item) => Math.max(max, item.left + item.width), 0);\n\n const legendWidth = maxRightEdge + LEGEND_OFFSET;\n\n this.legend = {\n width: legendWidth,\n height: legendHeight,\n items\n };\n }\n\n updateCaptionsSize(\n groupedCells: GroupedCellsHeatmap,\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n facetSettings: HeatmapSettingsImpl['facetSettings']\n ) {\n const textMeasurer = new TextMeasurer('bold 16px Manrope');\n const { xGroupKeys, yGroupKeys, xGroupLabels, yGroupLabels, xKeysByGroups, yKeysByGroups, xLabels, yLabels } = groupedCells.meta;\n this.labelAngles = {\n xAxisLabels: xAxis.axisLabelsAngle,\n yAxisLabels: yAxis.axisLabelsAngle,\n xGroupLabels: xAxis.groupLabelsAngle,\n yGroupLabels: yAxis.groupLabelsAngle,\n };\n\n const maxXLabelSize = xGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(xKeysByGroups[key], xLabels, textMeasurer)), 0);\n const maxYLabelSize = yGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(yKeysByGroups[key], yLabels, textMeasurer)), 0);\n const maxXGroupLabelSize = getMaxTextLength(xGroupKeys, xGroupLabels, textMeasurer);\n const maxYGroupLabelSize = getMaxTextLength(yGroupKeys, yGroupLabels, textMeasurer);\n const { xCaptionTail, yCaptionTail } = calculateCaptionTails(\n this.labelAngles,\n facetSettings,\n this.scales,\n this.step,\n groupedCells,\n textMeasurer\n );\n this.captionsSizes = {\n xCaptionTail,\n yCaptionTail,\n xGroupCaptions: getCaptionHeight(maxXGroupLabelSize, this.labelAngles.xGroupLabels),\n yGroupCaptions: getCaptionHeight(maxYGroupLabelSize, this.labelAngles.yGroupLabels),\n xAxisCaptions: getCaptionHeight(maxXLabelSize, this.labelAngles.xAxisLabels),\n yAxisCaptions: getCaptionHeight(maxYLabelSize, this.labelAngles.yAxisLabels),\n };\n }\n\n updateChartDimensions(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n annotations: HeatmapSettingsImpl['annotations'],\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n const facetCount = facetKeys.length;\n const maxNRows = Math.min(facetSettings.nRows ?? facetCount, facetCount);\n const maxNCols = Math.min(facetSettings.nCols ?? facetCount, facetCount);\n // Use columns/rows count from settings if some of them defined, else make 1 column\n this.columnsCount = facetSettings.nRows ? Math.ceil(facetCount / maxNRows) : maxNCols;\n this.rowsCount = Math.ceil(facetCount / this.columnsCount);\n const { sharedX, sharedY } = facetSettings;\n\n this.chartsDimensions = {};\n\n let currentLeft = 0;\n let currentTop = 0;\n facetKeys.forEach((key, index) => {\n const currentColumn = (index % this.columnsCount) + 1;\n const chartSides = getChartEdgeSides(index, facetKeys.length, this.columnsCount, this.rowsCount);\n const stepX = this.step.x[key];\n const stepY = this.step.y[key];\n const sideElementSizes = calculateChartSideElementSizes(\n xAxis,\n yAxis,\n this.captionsSizes,\n annotations,\n dendrogramX,\n dendrogramY,\n chartSides,\n sharedX,\n sharedY,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n stepX,\n stepY\n );\n const annotationsTitleSizes = calculateAnnotationTitleSizes(annotations, chartSides, sharedX, sharedY);\n function getPadding(side: 'left' | 'right' | 'top' | 'bottom') {\n return Math.max(\n CHART_SIDE_ELEMENTS[side].reduce((res, el) => res + sideElementSizes[side][el], 0),\n annotationsTitleSizes[side],\n size.innerOffset\n );\n }\n const padding = {\n left: getPadding('left'),\n right: getPadding('right'),\n top: getPadding('top'),\n bottom: getPadding('bottom'),\n };\n if (padding.left < this.captionsSizes.xCaptionTail) {\n padding.left = this.captionsSizes.xCaptionTail;\n }\n if (padding.bottom < this.captionsSizes.yCaptionTail) {\n padding.bottom = this.captionsSizes.yCaptionTail;\n }\n const sideElementBBoxes = calculateSideElementsBBoxes(sideElementSizes, this.chartSizes.chartWidth, this.chartSizes.chartHeight);\n const outerWidth = this.chartSizes.chartWidth + padding.left + padding.right;\n const outerHeight = this.chartSizes.chartHeight + padding.top + padding.bottom;\n this.chartsDimensions[key] = {\n left: currentLeft,\n top: currentTop,\n inner: { width: this.chartSizes.chartWidth, height: this.chartSizes.chartHeight },\n outer: { width: outerWidth, height: outerHeight },\n padding,\n sideElementBBoxes,\n chartEdgeSides: chartSides,\n };\n currentLeft += outerWidth;\n if (currentColumn === this.columnsCount) {\n currentLeft = 0;\n currentTop += outerHeight;\n }\n });\n\n // sum of widths of first row\n const chartsWidth = facetKeys\n .slice(0, this.columnsCount)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.width, 0);\n // sum of heights of first column\n const chartsHeight = facetKeys\n .filter((_key, index) => index % this.columnsCount === 0)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.height, 0);\n this.chartSizes.chartsWidth = chartsWidth;\n this.chartSizes.chartsHeight = chartsHeight;\n }\n\n updateChartsSizes(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const firstFacet = groupedCells.meta.facetKeys[0];\n if (cellWidth && firstFacet) {\n const keysCount = groupedCells.facets[firstFacet].xKeys.length;\n const nonEmptyXGroupsCount = groupedCells.meta.xGroupKeys.filter(\n k => (groupedCells.facets[firstFacet]?.xKeysByGroups[k]?.length ?? 0) > 0\n ).length;\n this.chartSizes.chartWidth = keysCount * cellWidth + groupGap * (nonEmptyXGroupsCount - 1);\n } else {\n this.chartSizes.chartWidth = width;\n }\n\n if (cellHeight && firstFacet) {\n const keysCount = groupedCells.facets[firstFacet].yKeys.length;\n const nonEmptyYGroupsCount = groupedCells.meta.yGroupKeys.filter(\n k => (groupedCells.facets[firstFacet]?.yKeysByGroups[k]?.length ?? 0) > 0\n ).length;\n this.chartSizes.chartHeight = keysCount * cellHeight + groupGap * (nonEmptyYGroupsCount - 1);\n } else {\n this.chartSizes.chartHeight = height;\n }\n }\n\n // update scales for cell positions, x and y for each facet.\n // Keys arrive pre-sorted from fillCellsData (and re-ordered by getDendrograms for clustered axes).\n updateScales(\n facetKeys: string[],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n size: HeatmapSettingsImpl['chartSettings']['size'],\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const { meta, facets } = groupedCells;\n const { sharedX, sharedY } = facetSettings;\n // All sorting is done upstream in fillCellsData; keys arrive already ordered.\n facetKeys.forEach(facetKey => {\n const facetGroup = facets[facetKey];\n const xGroupKeys = meta.xGroupKeys;\n const yGroupKeys = meta.yGroupKeys;\n const { xKeysByGroups } = sharedX ? meta : facetGroup;\n const { yKeysByGroups } = sharedY ? meta : facetGroup;\n // for shared facets max cells counts in group should be used\n const xCounts = xGroupKeys.map(xGroupKey => xKeysByGroups[xGroupKey].length);\n const yCounts = yGroupKeys.map(yGroupKey => yKeysByGroups[yGroupKey].length);\n const xCellsCount = xCounts.reduce((sum, count) => sum + count, 0);\n const yCellsCount = yCounts.reduce((sum, count) => sum + count, 0);\n const xStep = cellWidth ? cellWidth : (width - (xCounts.filter(count => count > 0).length - 1) * groupGap) / xCellsCount;\n const yStep = cellHeight ? cellHeight : (height - (yCounts.filter(count => count > 0).length - 1) * groupGap) / yCellsCount;\n\n const xPositions: number[] = [];\n let xKeys: string[] = [];\n let currentX = 0;\n const resolvedXGroups = xGroupKeys.map(xKey => xKeysByGroups[xKey]);\n resolvedXGroups.forEach((axisKeys, idx) => {\n xKeys = xKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n xPositions.push(currentX);\n currentX += xStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedXGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentX += groupGap;\n }\n });\n\n const yPositions: number[] = [];\n let yKeys: string[] = [];\n let currentY = 0;\n const resolvedYGroups = yGroupKeys.map(yKey => yKeysByGroups[yKey]);\n resolvedYGroups.forEach((axisKeys, idx) => {\n yKeys = yKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n yPositions.push(currentY);\n currentY += yStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedYGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentY += groupGap;\n }\n });\n\n this.scales.x[facetKey] = scaleOrdinal<string, number>().domain(xKeys).range(xPositions);\n this.scales.y[facetKey] = scaleOrdinal<string, number>().domain(yKeys).range(yPositions);\n this.step.x[facetKey] = xStep;\n this.step.y[facetKey] = yStep;\n });\n }\n\n updateAesScale(\n valueType: 'discrete' | 'continuous',\n valueExtent: [number, number],\n aes: HeatmapSettingsImpl['aes'],\n annotations: HeatmapSettingsImpl['annotations'],\n groupedCellsData: GroupedCellsHeatmap,\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization']\n ) {\n if (valueType === 'continuous') {\n if (aes.valueColors) {\n this.colorScale = scaleLinear<string, string>()\n .domain(aes.valuesByColors ?? getContinuousColorRange(normalization, aes.valueColors.length, valueExtent))\n .range(aes.valueColors);\n } else if (aes.colorsList) {\n this.colorScale = scaleLinear<string, string>()\n .domain(getContinuousColorRange(normalization, aes.colorsList.length, valueExtent))\n .range(aes.colorsList);\n }\n } else {\n if (aes.colorsMap) {\n const valueKeys = Object.entries(aes.colorsMap);\n this.colorScale = scaleOrdinal<string, string>()\n .domain(valueKeys.map(v => v[0]))\n .range(valueKeys.map(v => v[1]))\n .unknown('#ccc');\n } else if (aes.colorsList) {\n this.colorScale = createDiscreteColorScale(aes.colorsList, cellUniqValues.map(String));\n }\n }\n\n const { xDataByKeys, yDataByKeys } = groupedCellsData.meta;\n annotations.forEach(item => {\n const { colors, type, axis, valueColumn } = item;\n const data = (axis === 'x' ? xDataByKeys : yDataByKeys)[valueColumn.valueLabels ?? valueColumn.value];\n if (type === 'discrete') {\n const discreteValues = lodash.uniq(Object.values(data).map(String)).sort();\n this.annotationColorScales[item.id] = {\n type: 'discrete',\n scale: createDiscreteRoundColorScale(colors, discreteValues),\n };\n } else {\n const values = Object.values(data).map(Number);\n if (!values.length) {\n return;\n }\n const [min = values[0], max = values[0]] = extent(values);\n this.annotationColorScales[item.id] = {\n type: 'continuous',\n scale: createContinuousColorScale(colors, min, max, 0, 0.5, 1),\n };\n }\n });\n }\n\n updateDendrogram(\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n groups: GroupedCellsHeatmap['facets'],\n dendrogramsData: DendrogramsData,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n facetKeys.forEach(facetKey => {\n this.dendrograms[facetKey] = { x: { treesByGroupKey: {}, data: dendrogramX }, y: { treesByGroupKey: {}, data: dendrogramY } };\n const { xKeysByGroups, yKeysByGroups } = groups[facetKey];\n if (dendrogramX) {\n const { hierarchyByGroupX } = dendrogramsData[facetKey];\n const maxHeightX = xGroupKeys.reduce((res, xKey) => Math.max(res, hierarchyByGroupX[xKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].x.treesByGroupKey = xGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupX[groupKey];\n if (!hierarchy) return res;\n const xKeys = xKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.x[facetKey], dendrogramX.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramX.position === 'top' ? [0, maxHeightX] : [maxHeightX, 0])\n .range([dendrogramX.size, 0]);\n updateLinksHeight(root, heightScale, 'y');\n addShiftToLinkCoord(root, this.scales.x[facetKey](xKeys[0]), 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].x.data = dendrogramX;\n }\n if (dendrogramY) {\n const { hierarchyByGroupY } = dendrogramsData[facetKey];\n const maxHeightY = yGroupKeys.reduce((res, yKey) => Math.max(res, hierarchyByGroupY[yKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].y.treesByGroupKey = yGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupY[groupKey];\n if (!hierarchy) return res;\n const yKeys = yKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.y[facetKey], dendrogramY.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramY.position === 'left' ? [0, maxHeightY] : [maxHeightY, 0])\n .range([dendrogramY.size, 0]);\n addShiftToLinkCoord(root, this.scales.y[facetKey](yKeys[0]), 'x', 'y');\n updateLinksHeight(root, heightScale, 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].y.data = dendrogramY;\n }\n });\n }\n\n updateDendrogramAesScales(inheritedAes: HeatmapSettingsImpl['inheritedDendrogramAes']) {\n if (!inheritedAes) {\n return;\n }\n const usedColumns = Object.keys(inheritedAes);\n this.dendrogramAesScales = usedColumns.reduce((res: DendrogramAesScales, columnName) => {\n const aesMap = inheritedAes[columnName];\n const columnValues: string[] = Object.keys(aesMap);\n res[columnName] = scaleOrdinal<string, AesItem, AesItem>()\n .domain(columnValues)\n .range(\n columnValues.map(value => ({\n ...DEFAULT_AES,\n ...aesMap[value],\n }))\n )\n .unknown(DEFAULT_AES);\n return res;\n }, {});\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: HeatmapSettingsImpl['chartSettings'],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n aes: HeatmapSettingsImpl['aes'],\n groupedCellsData: GroupedCellsHeatmap,\n annotations: HeatmapSettingsImpl['annotations'],\n valueColumn: ColumnName,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY'],\n dendrogramsData: DendrogramsData,\n inheritedDendrogramAes: HeatmapSettingsImpl['inheritedDendrogramAes'],\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization'],\n onTooltipHintSwitch: (v: boolean) => void,\n cellsRenderingMode: 'canvas' | 'svg'\n ) {\n const { meta, facets } = groupedCellsData;\n const { facetKeys, xGroupKeys, yGroupKeys, valueExtent } = meta;\n const { xAxis, yAxis, title, size, valueType } = chartSettings;\n this.updateChartsSizes(size, groupedCellsData, aes.groupGap);\n this.updateAesScale(valueType, valueExtent.dataSource, aes, annotations, groupedCellsData, cellUniqValues, normalization);\n this.updateScales(facetKeys, groupedCellsData, aes.groupGap, facetSettings, size);\n // caption sizes are needed for chart paddings in chart dimensions\n this.updateCaptionsSize(groupedCellsData, xAxis, yAxis, facetSettings);\n this.updateChartDimensions(\n size,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n facetSettings,\n xAxis,\n yAxis,\n annotations,\n dendrogramX,\n dendrogramY\n );\n this.updateLegendSize(valueType, chartSettings.legend, annotations, valueColumn, valueExtent.dataSource);\n this.updateMargins(title, size);\n this.updateDendrogram(facetKeys, xGroupKeys, yGroupKeys, facets, dendrogramsData, dendrogramX, dendrogramY);\n this.updateDendrogramAesScales(inheritedDendrogramAes);\n const component = (\n <DataFrameProvider dataFrame={dataFrame}>\n <ChartsGroup\n aes={aes}\n annotations={annotations}\n annotationColorScales={this.annotationColorScales}\n captionsSizes={this.captionsSizes}\n cellsMeta={meta}\n columnsCount={this.columnsCount}\n chartsDimensions={this.chartsDimensions}\n chartSettings={chartSettings}\n chartSizes={this.chartSizes}\n colorScale={this.colorScale as (v: unknown) => string}\n dendrogramAesScales={this.dendrogramAesScales}\n dendrograms={this.dendrograms}\n facetKeys={facetKeys}\n facetSettings={facetSettings}\n groupedCells={facets}\n labelAngles={this.labelAngles}\n legend={this.legend}\n margins={this.margins}\n scales={this.scales}\n settingsId={settingsId}\n step={this.step}\n xGroupKeys={xGroupKeys}\n yGroupKeys={yGroupKeys}\n onTooltipHintSwitch={onTooltipHintSwitch}\n cellsRenderingMode={cellsRenderingMode}\n />\n </DataFrameProvider>\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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"}
1
+ {"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/heatmap/ChartRenderer.tsx"],"sourcesContent":["import { extent } from 'd3-array';\nimport type { HierarchyNode, HierarchyPointNode } from 'd3-hierarchy';\nimport { cluster } from 'd3-hierarchy';\nimport type { ScaleLinear, ScaleOrdinal } from 'd3-scale';\nimport { scaleLinear, scaleOrdinal } from 'd3-scale';\nimport lodash from 'lodash';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\nimport { Error } from '../common/Error';\nimport type { LegendData, LegendItem } from '../common/types';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport { DEFAULT_HEIGHT, DEFAULT_WIDTH, MAX_LEGEND_GRADIENT_HEIGHT, MIN_LEGEND_GRADIENT_HEIGHT, TITLE_LINE_HEIGHT, TITLE_MARGIN } from '../constants';\nimport type { DataFrame } from '../DataFrame';\nimport type { AesItem, ColumnName, DataValue } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { computeChartInnerSize } from '../utils/computeChartInnerSize';\nimport { getChartEdgeSides } from '../utils/getChartEdgeSides';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type {\n AnnotationColorScales,\n CaptionsSizes,\n ChartDendrograms,\n ChartDimensionsData,\n ChartSizes,\n ChartsScales,\n Cluster,\n DendrogramAesScales,\n LabelAngles,\n Margins,\n} from './components/types';\nimport { CHART_SIDE_ELEMENTS, DEFAULT_AES, LEGEND_OFFSET, MIN_MARGIN, TITLE_LINE } from './constants';\nimport type { GroupedCellsHeatmap } from './getCells';\nimport type { DendrogramsData } from './getDendrograms';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport {\n calculateAnnotationTitleSizes,\n calculateChartSideElementSizes,\n calculateSideElementsBBoxes,\n createContinuousColorScale,\n createDiscreteColorScale,\n createDiscreteRoundColorScale,\n} from './utils';\nimport { calculateCaptionTails } from './utils/calculateCaptionTails';\n\nconst COS_PI_4 = Math.cos(Math.PI / 4);\nconst INCLINE_OFFSET = 5; // height of little triangle of text for captions inclined 45deg\nfunction updateLinksHeight(root: HierarchyPointNode<Cluster>, scale: (v: number) => number, coord: 'x' | 'y') {\n function setHeight(d: HierarchyPointNode<Cluster>) {\n d[coord] = scale(d.data.height);\n if (d.children) d.children.forEach(setHeight);\n }\n setHeight(root);\n}\n\n// add shift to move nodes positions with group gaps\nfunction addShiftToLinkCoord(\n root: HierarchyPointNode<Cluster>,\n shift: number,\n coordFrom: 'x' | 'y',\n coordTo = coordFrom\n) {\n function setX(d: HierarchyPointNode<Cluster>) {\n d[coordTo] = d[coordFrom] + shift;\n if (d.children) d.children.forEach(setX);\n }\n setX(root);\n}\n\nconst getSteps = (count: number, valueExtent: number[]) => {\n const min = Math.min(...valueExtent);\n const max = Math.max(...valueExtent);\n if (min === max) {\n const steps = count % 2 === 0 ? [] : [min];\n for (let i = 1; i < count / 2 + 1; i++) {\n steps.push(min + i);\n steps.unshift(min - i);\n }\n return steps;\n }\n if (count < 2) {\n return [min, max];\n }\n const step = (max - min) / (count - 1);\n const steps = [];\n for (let i = 0; i < count - 1; i++) {\n steps.push(min + step * i);\n }\n steps.push(max);\n return steps;\n};\n\nfunction getContinuousColorRange(normalization: HeatmapSettingsImpl['normalization'], colorsCount: number, valueExtent: number[]) {\n let extent = valueExtent;\n if (normalization) {\n if (normalization.colorRange) {\n extent = normalization.colorRange;\n }\n if (normalization.method === 'standardScaling') {\n extent = [-2, 2];\n }\n if (normalization.method === 'meanNormalization') {\n extent = [-0.75, 0.75];\n }\n }\n return getSteps(colorsCount, extent);\n}\n\nfunction getMaxTextLength(keys: string[], labels: Record<string, string>, textMeasurer: TextMeasurer) {\n let maxLabelSize = 0;\n for (const key of keys) {\n if (labels[key] === undefined) continue;\n const l = textMeasurer.getTextWidth(labels[key]);\n if (l > maxLabelSize) maxLabelSize = l;\n }\n return maxLabelSize;\n}\n\nfunction getCaptionHeight(size: number, angle: number) {\n if (angle === 90) {\n return size;\n }\n if (angle === 45) {\n return size * COS_PI_4 + (size > 0 ? 2 * INCLINE_OFFSET : 0);\n }\n return TITLE_LINE;\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = (<></>);\n chartsDimensions: Record<string, ChartDimensionsData> = {};\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\n chartsWidth: DEFAULT_WIDTH, // width of all charts in charts row\n chartsHeight: DEFAULT_HEIGHT, // width of all charts in charts column, without axes\n totalWidth: DEFAULT_WIDTH, // width of all charts in charts row, plus left axis, plus legend\n totalHeight: DEFAULT_HEIGHT, // width of all charts in charts height, plus bottom axis, plus top title\n };\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n captionsSizes: CaptionsSizes = {\n xAxisCaptions: 100,\n yAxisCaptions: 100,\n xGroupCaptions: TITLE_LINE,\n yGroupCaptions: TITLE_LINE,\n xCaptionTail: 0,\n yCaptionTail: 0,\n };\n labelAngles: LabelAngles = {\n xAxisLabels: 0,\n yAxisLabels: 0,\n xGroupLabels: 0,\n yGroupLabels: 0,\n };\n columnsCount = 1;\n rowsCount = 1;\n scales: ChartsScales = {\n // scales grouped by facet\n x: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n y: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n };\n step: {\n x: Record<string, number>;\n y: Record<string, number>;\n } = { x: {}, y: {} };\n colorScale: ScaleLinear<string, string> | ScaleOrdinal<string, string, string> = scaleLinear<string, string>()\n .domain([0, 1])\n .range(['white', 'black']);\n annotationColorScales: AnnotationColorScales = {};\n dendrogramAesScales: DendrogramAesScales = {};\n legend: LegendData = {\n width: 0,\n height: 0,\n items: [],\n };\n dendrograms: Record<string, ChartDendrograms> = {};\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 // timeout to avoid trying to unmount during rendering\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 updateMargins(title: HeatmapSettingsImpl['chartSettings']['title'], size: HeatmapSettingsImpl['chartSettings']['size']) {\n this.margins = {\n top: title.show ? TITLE_LINE_HEIGHT + TITLE_MARGIN * 2 : size.outerOffset,\n bottom: size.outerOffset,\n left: size.outerOffset,\n right: this.legend.width + size.outerOffset,\n };\n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartsHeight + this.margins.bottom, this.legend.height);\n }\n\n updateLegendSize(\n valueType: HeatmapSettingsImpl['chartSettings']['valueType'],\n legend: HeatmapSettingsImpl['chartSettings']['legend'],\n annotations: HeatmapSettingsImpl['annotations'],\n columnValue: ColumnName,\n valueExtent: [number, number]\n ) {\n if (!legend.show) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n const continuousHeight = Math.min(\n Math.max(this.chartSizes.chartHeight, MIN_LEGEND_GRADIENT_HEIGHT),\n MAX_LEGEND_GRADIENT_HEIGHT\n );\n const legendHeight = Math.max(this.chartSizes.chartHeight, continuousHeight);\n const legendItems: LegendItem[] = [];\n const emptySizes = { width: 0, height: 0, left: 0, top: 0 };\n\n const getDefaultLabels = (values: (string | number)[]) => values.reduce((res: Record<string, string>, v: string | number) => { res[v] = String(v); return res; }, {});\n if (valueType === 'continuous') {\n const scale = this.colorScale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n const title = columnValue.label ?? columnValue.value;\n legendItems.push({\n ...emptySizes,\n type: 'continuous',\n id: 'heatmapValue',\n scale,\n values,\n title,\n tickPositionScale\n });\n } else if (valueType === 'discrete') {\n const scale = this.colorScale as ScaleOrdinal<string, string>;\n const title = columnValue.label ?? columnValue.value;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: 'heatmapValue', title, scale, values, labels });\n }\n annotations.forEach(item => {\n const title = item.valueColumn.label ?? item.valueColumn.value;\n if (item.type === 'continuous') {\n const scale = this.annotationColorScales[item.id].scale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n\n legendItems.push({ ...emptySizes, type: 'continuous', id: item.id, tickPositionScale, title, scale, values });\n }\n if (item.type === 'discrete') {\n const scale = this.annotationColorScales[item.id].scale as ScaleOrdinal<string, string>;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: item.id, title, scale, values, labels });\n }\n });\n\n if (!legendItems.length) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n\n const items = arrangeLegendParts(legendItems, this.chartSizes.chartHeight,continuousHeight);\n const maxRightEdge = items.reduce((max, item) => Math.max(max, item.left + item.width), 0);\n\n const legendWidth = maxRightEdge + LEGEND_OFFSET;\n\n this.legend = {\n width: legendWidth,\n height: legendHeight,\n items\n };\n }\n\n updateCaptionsSize(\n groupedCells: GroupedCellsHeatmap,\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n facetSettings: HeatmapSettingsImpl['facetSettings']\n ) {\n const textMeasurer = new TextMeasurer('bold 16px Manrope');\n const { xGroupKeys, yGroupKeys, xGroupLabels, yGroupLabels, xKeysByGroups, yKeysByGroups, xLabels, yLabels } = groupedCells.meta;\n this.labelAngles = {\n xAxisLabels: xAxis.axisLabelsAngle,\n yAxisLabels: yAxis.axisLabelsAngle,\n xGroupLabels: xAxis.groupLabelsAngle,\n yGroupLabels: yAxis.groupLabelsAngle,\n };\n\n const maxXLabelSize = xGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(xKeysByGroups[key], xLabels, textMeasurer)), 0);\n const maxYLabelSize = yGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(yKeysByGroups[key], yLabels, textMeasurer)), 0);\n const maxXGroupLabelSize = getMaxTextLength(xGroupKeys, xGroupLabels, textMeasurer);\n const maxYGroupLabelSize = getMaxTextLength(yGroupKeys, yGroupLabels, textMeasurer);\n const { xCaptionTail, yCaptionTail } = calculateCaptionTails(\n this.labelAngles,\n facetSettings,\n this.scales,\n this.step,\n groupedCells,\n textMeasurer\n );\n this.captionsSizes = {\n xCaptionTail,\n yCaptionTail,\n xGroupCaptions: getCaptionHeight(maxXGroupLabelSize, this.labelAngles.xGroupLabels),\n yGroupCaptions: getCaptionHeight(maxYGroupLabelSize, this.labelAngles.yGroupLabels),\n xAxisCaptions: getCaptionHeight(maxXLabelSize, this.labelAngles.xAxisLabels),\n yAxisCaptions: getCaptionHeight(maxYLabelSize, this.labelAngles.yAxisLabels),\n };\n }\n\n updateChartDimensions(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n annotations: HeatmapSettingsImpl['annotations'],\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n const facetCount = facetKeys.length;\n const maxNRows = Math.min(facetSettings.nRows ?? facetCount, facetCount);\n const maxNCols = Math.min(facetSettings.nCols ?? facetCount, facetCount);\n // Use columns/rows count from settings if some of them defined, else make 1 column\n this.columnsCount = facetSettings.nRows ? Math.ceil(facetCount / maxNRows) : maxNCols;\n this.rowsCount = Math.ceil(facetCount / this.columnsCount);\n const { sharedX, sharedY } = facetSettings;\n\n this.chartsDimensions = {};\n\n let currentLeft = 0;\n let currentTop = 0;\n facetKeys.forEach((key, index) => {\n const currentColumn = (index % this.columnsCount) + 1;\n const chartSides = getChartEdgeSides(index, facetKeys.length, this.columnsCount, this.rowsCount);\n const stepX = this.step.x[key];\n const stepY = this.step.y[key];\n const sideElementSizes = calculateChartSideElementSizes(\n xAxis,\n yAxis,\n this.captionsSizes,\n annotations,\n dendrogramX,\n dendrogramY,\n chartSides,\n sharedX,\n sharedY,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n stepX,\n stepY\n );\n const annotationsTitleSizes = calculateAnnotationTitleSizes(annotations, chartSides, sharedX, sharedY);\n function getPadding(side: 'left' | 'right' | 'top' | 'bottom') {\n return Math.max(\n CHART_SIDE_ELEMENTS[side].reduce((res, el) => res + sideElementSizes[side][el], 0),\n annotationsTitleSizes[side],\n size.innerOffset\n );\n }\n const padding = {\n left: getPadding('left'),\n right: getPadding('right'),\n top: getPadding('top'),\n bottom: getPadding('bottom'),\n };\n if (padding.left < this.captionsSizes.xCaptionTail) {\n padding.left = this.captionsSizes.xCaptionTail;\n }\n if (padding.bottom < this.captionsSizes.yCaptionTail) {\n padding.bottom = this.captionsSizes.yCaptionTail;\n }\n const sideElementBBoxes = calculateSideElementsBBoxes(sideElementSizes, this.chartSizes.chartWidth, this.chartSizes.chartHeight);\n const outerWidth = this.chartSizes.chartWidth + padding.left + padding.right;\n const outerHeight = this.chartSizes.chartHeight + padding.top + padding.bottom;\n this.chartsDimensions[key] = {\n left: currentLeft,\n top: currentTop,\n inner: { width: this.chartSizes.chartWidth, height: this.chartSizes.chartHeight },\n outer: { width: outerWidth, height: outerHeight },\n padding,\n sideElementBBoxes,\n chartEdgeSides: chartSides,\n };\n currentLeft += outerWidth;\n if (currentColumn === this.columnsCount) {\n currentLeft = 0;\n currentTop += outerHeight;\n }\n });\n\n // sum of widths of first row\n const chartsWidth = facetKeys\n .slice(0, this.columnsCount)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.width, 0);\n // sum of heights of first column\n const chartsHeight = facetKeys\n .filter((_key, index) => index % this.columnsCount === 0)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.height, 0);\n this.chartSizes.chartsWidth = chartsWidth;\n this.chartSizes.chartsHeight = chartsHeight;\n }\n\n updateChartsSizes(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n ) {\n const { chartWidth, chartHeight } = computeChartInnerSize(size, groupedCells.meta, groupGap);\n this.chartSizes.chartWidth = chartWidth;\n this.chartSizes.chartHeight = chartHeight;\n }\n\n // update scales for cell positions, x and y for each facet.\n // Keys arrive pre-sorted from fillCellsData (and re-ordered by getDendrograms for clustered axes).\n updateScales(\n facetKeys: string[],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n size: HeatmapSettingsImpl['chartSettings']['size'],\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const { meta, facets } = groupedCells;\n const { sharedX, sharedY } = facetSettings;\n // All sorting is done upstream in fillCellsData; keys arrive already ordered.\n facetKeys.forEach(facetKey => {\n const facetGroup = facets[facetKey];\n const xGroupKeys = meta.xGroupKeys;\n const yGroupKeys = meta.yGroupKeys;\n const { xKeysByGroups } = sharedX ? meta : facetGroup;\n const { yKeysByGroups } = sharedY ? meta : facetGroup;\n // for shared facets max cells counts in group should be used\n const xCounts = xGroupKeys.map(xGroupKey => xKeysByGroups[xGroupKey].length);\n const yCounts = yGroupKeys.map(yGroupKey => yKeysByGroups[yGroupKey].length);\n const xCellsCount = xCounts.reduce((sum, count) => sum + count, 0);\n const yCellsCount = yCounts.reduce((sum, count) => sum + count, 0);\n const xStep = cellWidth ? cellWidth : (width - (xCounts.filter(count => count > 0).length - 1) * groupGap) / xCellsCount;\n const yStep = cellHeight ? cellHeight : (height - (yCounts.filter(count => count > 0).length - 1) * groupGap) / yCellsCount;\n\n const xPositions: number[] = [];\n let xKeys: string[] = [];\n let currentX = 0;\n const resolvedXGroups = xGroupKeys.map(xKey => xKeysByGroups[xKey]);\n resolvedXGroups.forEach((axisKeys, idx) => {\n xKeys = xKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n xPositions.push(currentX);\n currentX += xStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedXGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentX += groupGap;\n }\n });\n\n const yPositions: number[] = [];\n let yKeys: string[] = [];\n let currentY = 0;\n const resolvedYGroups = yGroupKeys.map(yKey => yKeysByGroups[yKey]);\n resolvedYGroups.forEach((axisKeys, idx) => {\n yKeys = yKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n yPositions.push(currentY);\n currentY += yStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedYGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentY += groupGap;\n }\n });\n\n this.scales.x[facetKey] = scaleOrdinal<string, number>().domain(xKeys).range(xPositions);\n this.scales.y[facetKey] = scaleOrdinal<string, number>().domain(yKeys).range(yPositions);\n this.step.x[facetKey] = xStep;\n this.step.y[facetKey] = yStep;\n });\n }\n\n updateAesScale(\n valueType: 'discrete' | 'continuous',\n valueExtent: [number, number],\n aes: HeatmapSettingsImpl['aes'],\n annotations: HeatmapSettingsImpl['annotations'],\n groupedCellsData: GroupedCellsHeatmap,\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization']\n ) {\n if (valueType === 'continuous') {\n if (aes.valueColors) {\n this.colorScale = scaleLinear<string, string>()\n .domain(aes.valuesByColors ?? getContinuousColorRange(normalization, aes.valueColors.length, valueExtent))\n .range(aes.valueColors);\n } else if (aes.colorsList) {\n this.colorScale = scaleLinear<string, string>()\n .domain(getContinuousColorRange(normalization, aes.colorsList.length, valueExtent))\n .range(aes.colorsList);\n }\n } else {\n if (aes.colorsMap) {\n const valueKeys = Object.entries(aes.colorsMap);\n this.colorScale = scaleOrdinal<string, string>()\n .domain(valueKeys.map(v => v[0]))\n .range(valueKeys.map(v => v[1]))\n .unknown('#ccc');\n } else if (aes.colorsList) {\n this.colorScale = createDiscreteColorScale(aes.colorsList, cellUniqValues.map(String));\n }\n }\n\n const { xDataByKeys, yDataByKeys } = groupedCellsData.meta;\n annotations.forEach(item => {\n const { colors, type, axis, valueColumn } = item;\n const data = (axis === 'x' ? xDataByKeys : yDataByKeys)[valueColumn.valueLabels ?? valueColumn.value];\n if (type === 'discrete') {\n const discreteValues = lodash.uniq(Object.values(data).map(String)).sort();\n this.annotationColorScales[item.id] = {\n type: 'discrete',\n scale: createDiscreteRoundColorScale(colors, discreteValues),\n };\n } else {\n const values = Object.values(data).map(Number);\n if (!values.length) {\n return;\n }\n const [min = values[0], max = values[0]] = extent(values);\n this.annotationColorScales[item.id] = {\n type: 'continuous',\n scale: createContinuousColorScale(colors, min, max, 0, 0.5, 1),\n };\n }\n });\n }\n\n updateDendrogram(\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n groups: GroupedCellsHeatmap['facets'],\n dendrogramsData: DendrogramsData,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n facetKeys.forEach(facetKey => {\n this.dendrograms[facetKey] = { x: { treesByGroupKey: {}, data: dendrogramX }, y: { treesByGroupKey: {}, data: dendrogramY } };\n const { xKeysByGroups, yKeysByGroups } = groups[facetKey];\n if (dendrogramX) {\n const { hierarchyByGroupX } = dendrogramsData[facetKey];\n const maxHeightX = xGroupKeys.reduce((res, xKey) => Math.max(res, hierarchyByGroupX[xKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].x.treesByGroupKey = xGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupX[groupKey];\n if (!hierarchy) return res;\n const xKeys = xKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.x[facetKey], dendrogramX.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramX.position === 'top' ? [0, maxHeightX] : [maxHeightX, 0])\n .range([dendrogramX.size, 0]);\n updateLinksHeight(root, heightScale, 'y');\n addShiftToLinkCoord(root, this.scales.x[facetKey](xKeys[0]), 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].x.data = dendrogramX;\n }\n if (dendrogramY) {\n const { hierarchyByGroupY } = dendrogramsData[facetKey];\n const maxHeightY = yGroupKeys.reduce((res, yKey) => Math.max(res, hierarchyByGroupY[yKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].y.treesByGroupKey = yGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupY[groupKey];\n if (!hierarchy) return res;\n const yKeys = yKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.y[facetKey], dendrogramY.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramY.position === 'left' ? [0, maxHeightY] : [maxHeightY, 0])\n .range([dendrogramY.size, 0]);\n addShiftToLinkCoord(root, this.scales.y[facetKey](yKeys[0]), 'x', 'y');\n updateLinksHeight(root, heightScale, 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].y.data = dendrogramY;\n }\n });\n }\n\n updateDendrogramAesScales(inheritedAes: HeatmapSettingsImpl['inheritedDendrogramAes']) {\n if (!inheritedAes) {\n return;\n }\n const usedColumns = Object.keys(inheritedAes);\n this.dendrogramAesScales = usedColumns.reduce((res: DendrogramAesScales, columnName) => {\n const aesMap = inheritedAes[columnName];\n const columnValues: string[] = Object.keys(aesMap);\n res[columnName] = scaleOrdinal<string, AesItem, AesItem>()\n .domain(columnValues)\n .range(\n columnValues.map(value => ({\n ...DEFAULT_AES,\n ...aesMap[value],\n }))\n )\n .unknown(DEFAULT_AES);\n return res;\n }, {});\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: HeatmapSettingsImpl['chartSettings'],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n aes: HeatmapSettingsImpl['aes'],\n groupedCellsData: GroupedCellsHeatmap,\n annotations: HeatmapSettingsImpl['annotations'],\n valueColumn: ColumnName,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY'],\n dendrogramsData: DendrogramsData,\n inheritedDendrogramAes: HeatmapSettingsImpl['inheritedDendrogramAes'],\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization'],\n onTooltipHintSwitch: (v: boolean) => void,\n cellsRenderingMode: 'canvas' | 'svg'\n ) {\n const { meta, facets } = groupedCellsData;\n const { facetKeys, xGroupKeys, yGroupKeys, valueExtent } = meta;\n const { xAxis, yAxis, title, size, valueType } = chartSettings;\n this.updateChartsSizes(size, groupedCellsData, aes.groupGap);\n this.updateAesScale(valueType, valueExtent.dataSource, aes, annotations, groupedCellsData, cellUniqValues, normalization);\n this.updateScales(facetKeys, groupedCellsData, aes.groupGap, facetSettings, size);\n // caption sizes are needed for chart paddings in chart dimensions\n this.updateCaptionsSize(groupedCellsData, xAxis, yAxis, facetSettings);\n this.updateChartDimensions(\n size,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n facetSettings,\n xAxis,\n yAxis,\n annotations,\n dendrogramX,\n dendrogramY\n );\n this.updateLegendSize(valueType, chartSettings.legend, annotations, valueColumn, valueExtent.dataSource);\n this.updateMargins(title, size);\n this.updateDendrogram(facetKeys, xGroupKeys, yGroupKeys, facets, dendrogramsData, dendrogramX, dendrogramY);\n this.updateDendrogramAesScales(inheritedDendrogramAes);\n const component = (\n <DataFrameProvider dataFrame={dataFrame}>\n <ChartsGroup\n aes={aes}\n annotations={annotations}\n annotationColorScales={this.annotationColorScales}\n captionsSizes={this.captionsSizes}\n cellsMeta={meta}\n columnsCount={this.columnsCount}\n chartsDimensions={this.chartsDimensions}\n chartSettings={chartSettings}\n chartSizes={this.chartSizes}\n colorScale={this.colorScale as (v: unknown) => string}\n dendrogramAesScales={this.dendrogramAesScales}\n dendrograms={this.dendrograms}\n facetKeys={facetKeys}\n facetSettings={facetSettings}\n groupedCells={facets}\n labelAngles={this.labelAngles}\n legend={this.legend}\n margins={this.margins}\n scales={this.scales}\n settingsId={settingsId}\n step={this.step}\n xGroupKeys={xGroupKeys}\n yGroupKeys={yGroupKeys}\n onTooltipHintSwitch={onTooltipHintSwitch}\n cellsRenderingMode={cellsRenderingMode}\n />\n </DataFrameProvider>\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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChartRenderer.d.ts","sourceRoot":"","sources":["../../src/selection/ChartRenderer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChartRenderer.d.ts","sourceRoot":"","sources":["../../src/selection/ChartRenderer.tsx"],"names":[],"mappings":"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"}
@@ -108,19 +108,18 @@ var f = class {
108
108
  this.solidColor = n ? i : t;
109
109
  }
110
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";
111
+ let n = new t("500 14px Manrope"), i = this.orderedFaceted.facetKeys, o = 0;
112
+ for (let e of i) for (let t of this.orderedFaceted.byFacet[e]?.filterNames ?? []) o = Math.max(o, n.getTextWidth(t));
113
+ this.maxLabelPx = o, this.xLabelsPosition = e.labelsPosition ?? "45deg";
114
+ let s = this.xLabelsPosition !== "center";
117
115
  this.xLabelsByFacet = {}, this.xCountsByFacet = {}, this.maxLabelLines = 1;
118
116
  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);
117
+ let t = this.orderedFaceted.byFacet[e], n = {}, i = {};
118
+ for (let [e, i] of (t?.filterNames ?? []).entries()) {
119
+ let t = s ? [i] : r(i, 120, 14);
120
+ n[String(e)] = t, this.maxLabelLines = Math.max(this.maxLabelLines, t.length);
123
121
  }
122
+ for (let [e, n] of (t?.stages ?? []).entries()) i[String(e)] = a(n.total);
124
123
  this.xLabelsByFacet[e] = n, this.xCountsByFacet[e] = i;
125
124
  }
126
125
  }
@@ -215,7 +214,6 @@ var f = class {
215
214
  countsByFacet: this.xCountsByFacet,
216
215
  countsFontSize: 14,
217
216
  labelsPosition: this.xLabelsPosition,
218
- showGrid: f.showGrid,
219
217
  showTicks: f.showTicks,
220
218
  hiddenLabels: f.hiddenLabels,
221
219
  title: f.title
@@ -1 +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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"}
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_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 let maxLabelPx = 0;\n for (const fk of facetKeys) {\n for (const name of this.orderedFaceted.byFacet[fk]?.filterNames ?? []) {\n maxLabelPx = Math.max(maxLabelPx, tm.getTextWidth(name));\n }\n }\n this.maxLabelPx = maxLabelPx;\n this.xLabelsPosition = xAxis.labelsPosition ?? '45deg';\n const rotateLabels = this.xLabelsPosition !== 'center';\n\n // labels = filter name per gap (N); counts = population total per bar (N+1).\n // Centered labels wrap to two lines; rotated stay on one.\n this.xLabelsByFacet = {};\n this.xCountsByFacet = {};\n this.maxLabelLines = 1;\n for (const fk of facetKeys) {\n const facetData = this.orderedFaceted.byFacet[fk];\n const labels: Record<string, string[]> = {};\n const counts: Record<string, string> = {};\n for (const [gapIndex, name] of (facetData?.filterNames ?? []).entries()) {\n const lines = rotateLabels\n ? [name]\n : splitTextByWidth(name, LABEL_WRAP_WIDTH_PX, LABEL_LINE_HEIGHT_PX);\n labels[String(gapIndex)] = lines;\n this.maxLabelLines = Math.max(this.maxLabelLines, lines.length);\n }\n for (const [barIndex, stage] of (facetData?.stages ?? []).entries()) {\n counts[String(barIndex)] = formatCount(stage.total);\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 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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"}
@@ -6,7 +6,6 @@ export type SelectionFillColor = string | {
6
6
  };
7
7
  export type SelectionXAxisSettings = {
8
8
  title: string;
9
- showGrid: boolean;
10
9
  showTicks: boolean;
11
10
  hiddenLabels: boolean;
12
11
  labelsPosition: 'center' | '45deg' | '90deg' | null;
@@ -1 +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"}
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,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;CA2CxC"}
@@ -27,7 +27,6 @@ var n = class {
27
27
  position: n.title.position ?? "center"
28
28
  }, this.xAxis = {
29
29
  title: n.xAxis?.title ?? "",
30
- showGrid: n.xAxis?.showGrid ?? !1,
31
30
  showTicks: n.xAxis?.showTicks ?? !0,
32
31
  hiddenLabels: n.xAxis?.hiddenLabels ?? !1,
33
32
  labelsPosition: n.xAxis?.labelsPosition ?? null
@@ -1 +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"}
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 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 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":";;AA6BA,IAAa,IAAb,MAAgE;CAC9D;CACA,OAAgB;CAEhB;CACA;CAEA;CAOA;CAEA;CACA;CAMA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA,YAAY,GAA6B;AAsCvC,EArCA,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,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"}
@@ -4,7 +4,7 @@ import { toPercent as t } from "../../../utils.js";
4
4
  import { memo as n } from "react";
5
5
  import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
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);
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.get(o), b = y?.surviving ?? 0, x = b + (y?.discarded ?? 0);
8
8
  if (x <= 0) return null;
9
9
  let S = v(t(x / u.total)), C = v(t(b / u.total)), w = C - S, T = _ - C, E = e((e, t) => {
10
10
  p.onEnter({
@@ -1 +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"}
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.get(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,IAAI,EAAiB,EAC9C,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"}
@@ -1 +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"}
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;EA8EpC,CAAC"}
@@ -15,16 +15,16 @@ const c = i(function({ common: i, stackOrder: c, colorMap: l, fallbackColor: u,
15
15
  });
16
16
  }), T = e(() => {
17
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;
18
+ }), E = e((e) => p(e)), D = h.total > 0 ? C(r(h.surviving / h.total)) : S, O = [], k = [], A = D, j = 0;
19
19
  for (let e of c) {
20
- let r = D.get(e);
20
+ let r = h.groups.get(e);
21
21
  if (!r) continue;
22
22
  let i = r.surviving / h.total * S, a = r.discarded / h.total * S, s = d && d !== e;
23
23
  if (i > 0) {
24
- let t = j + i / 2;
25
- k.push(/* @__PURE__ */ o("rect", {
24
+ let t = A + i / 2;
25
+ O.push(/* @__PURE__ */ o("rect", {
26
26
  x: y,
27
- y: j,
27
+ y: A,
28
28
  width: b,
29
29
  height: i,
30
30
  fill: l.get(e) ?? u,
@@ -33,13 +33,13 @@ const c = i(function({ common: i, stackOrder: c, colorMap: l, fallbackColor: u,
33
33
  onMouseLeave: T,
34
34
  onClick: () => E(e),
35
35
  style: { cursor: "pointer" }
36
- }, `bar-p-${m}-${e}`)), j += i;
36
+ }, `bar-p-${m}-${e}`)), A += i;
37
37
  }
38
38
  if (a > 0) {
39
- let r = M + a / 2;
40
- A.push(/* @__PURE__ */ o("rect", {
39
+ let r = j + a / 2;
40
+ k.push(/* @__PURE__ */ o("rect", {
41
41
  x: y,
42
- y: M,
42
+ y: j,
43
43
  width: b,
44
44
  height: a,
45
45
  fill: l.get(e) ?? u,
@@ -48,10 +48,10 @@ const c = i(function({ common: i, stackOrder: c, colorMap: l, fallbackColor: u,
48
48
  onMouseLeave: T,
49
49
  onClick: () => E(e),
50
50
  style: { cursor: "pointer" }
51
- }, `bar-d-${m}-${e}`)), M += a;
51
+ }, `bar-d-${m}-${e}`)), j += a;
52
52
  }
53
53
  }
54
- return /* @__PURE__ */ s(a, { children: [k, A] });
54
+ return /* @__PURE__ */ s(a, { children: [O, k] });
55
55
  });
56
56
  export { c as StackedBars };
57
57
 
@@ -1 +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"}
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 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 = stage.groups.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,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,EAAM,OAAO,IAAI,EAAU;AAC7C,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"}
@@ -1 +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"}
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;EAiEjB,CAAC"}