@milaboratories/miplots4 1.0.168 → 1.0.170

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ChartRenderer.js","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 lastItem = items[items.length - 1];\n const legendWidth = lastItem.left + lastItem.width + 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 groupsCount = groupedCells.meta.xGroupKeys.length;\n this.chartSizes.chartWidth = keysCount * cellWidth + groupGap * (groupsCount - 1);\n } else {\n this.chartSizes.chartWidth = width;\n }\n\n if (cellHeight && firstFacet) {\n const keysCount = groupedCells.facets[firstFacet].yKeys.length;\n const groupsCount = groupedCells.meta.yGroupKeys.length;\n this.chartSizes.chartHeight = keysCount * cellHeight + groupGap * (groupsCount - 1);\n } else {\n this.chartSizes.chartHeight = height;\n }\n }\n\n // update scales for cell positions, x and y for each facet\n updateScales(\n facetKeys: string[],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n size: HeatmapSettingsImpl['chartSettings']['size'],\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY'],\n customOrder: {x: boolean, y: boolean, xGroup: boolean, yGroup: boolean},\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const { meta, facets } = groupedCells;\n const { sharedX, sharedY } = facetSettings;\n const sortX = (arr: string[], labels: Record<string, string> = {}) => {\n return arr.sort((a, b) => xAxis.sorting === 'asc'\n ? (labels[a] ?? a).localeCompare((labels[b] ?? b), 'en', { numeric: true })\n : (labels[b] ?? b).localeCompare((labels[a] ?? a), 'en', { numeric: true })\n );\n };\n const sortY = (arr: string[], labels: Record<string, string> = {}) => {\n return arr.sort((a, b) => yAxis.sorting === 'asc'\n ? (labels[a] ?? a).localeCompare((labels[b] ?? b), 'en', { numeric: true })\n : (labels[b] ?? b).localeCompare((labels[a] ?? a), 'en', { numeric: true })\n );\n };\n facetKeys.forEach(facetKey => {\n const facetGroup = facets[facetKey];\n const xGroupKeys = customOrder.xGroup ? meta.xGroupKeys : sortX(meta.xGroupKeys);\n const yGroupKeys = customOrder.yGroup ? meta.yGroupKeys : sortY(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 xGroupKeys.forEach(xKey => {\n const axisKeys = dendrogramX || customOrder.x ? xKeysByGroups[xKey] : sortX(xKeysByGroups[xKey], meta.xLabels);\n xKeys = xKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n xPositions.push(currentX);\n currentX += xStep;\n });\n // do not add offset for empty group\n if (axisKeys.length > 0) {\n currentX += groupGap;\n }\n });\n\n const yPositions: number[] = [];\n let yKeys: string[] = [];\n let currentY = 0;\n yGroupKeys.forEach(yKey => {\n const axisKeys = dendrogramY || customOrder.y ? yKeysByGroups[yKey] : sortY(yKeysByGroups[yKey], meta.yLabels);\n yKeys = yKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n yPositions.push(currentY);\n currentY += yStep;\n });\n // do not add offset for empty group\n if (axisKeys.length > 0) {\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);\n this.dendrograms[facetKey].x.treesByGroupKey = xGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupX[groupKey];\n const xKeys = xKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([xKeys.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);\n this.dendrograms[facetKey].y.treesByGroupKey = yGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupY[groupKey];\n const yKeys = yKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([yKeys.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 customOrder: {x: boolean, y: boolean, xGroup: boolean, yGroup: boolean},\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, chartSettings.xAxis, chartSettings.yAxis, dendrogramX, dendrogramY, customOrder);\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"],"names":["COS_PI_4","INCLINE_OFFSET","updateLinksHeight","root","scale","coord","setHeight","d","addShiftToLinkCoord","shift","coordFrom","coordTo","setX","getSteps","count","valueExtent","min","max","steps","i","step","getContinuousColorRange","normalization","colorsCount","extent","getMaxTextLength","keys","labels","textMeasurer","maxLabelSize","key","l","getCaptionHeight","size","angle","TITLE_LINE","ChartRenderer","__publicField","jsx","Fragment","DEFAULT_WIDTH","DEFAULT_HEIGHT","MIN_MARGIN","scaleOrdinal","scaleLinear","_a","node","createRoot","title","TITLE_LINE_HEIGHT","TITLE_MARGIN","valueType","legend","annotations","columnValue","continuousHeight","MIN_LEGEND_GRADIENT_HEIGHT","MAX_LEGEND_GRADIENT_HEIGHT","legendHeight","legendItems","emptySizes","getDefaultLabels","values","res","v","getContinuousLegendTicks","tickPositionScale","item","items","arrangeLegendParts","lastItem","legendWidth","LEGEND_OFFSET","groupedCells","xAxis","yAxis","facetSettings","TextMeasurer","xGroupKeys","yGroupKeys","xGroupLabels","yGroupLabels","xKeysByGroups","yKeysByGroups","xLabels","yLabels","maxXLabelSize","maxYLabelSize","maxXGroupLabelSize","maxYGroupLabelSize","xCaptionTail","yCaptionTail","calculateCaptionTails","facetKeys","dendrogramX","dendrogramY","facetCount","maxNRows","maxNCols","sharedX","sharedY","currentLeft","currentTop","index","currentColumn","chartSides","getChartEdgeSides","stepX","stepY","sideElementSizes","calculateChartSideElementSizes","annotationsTitleSizes","calculateAnnotationTitleSizes","getPadding","side","CHART_SIDE_ELEMENTS","el","padding","sideElementBBoxes","calculateSideElementsBBoxes","outerWidth","outerHeight","chartsWidth","sum","chartsHeight","_key","groupGap","width","height","cellWidth","cellHeight","firstFacet","keysCount","groupsCount","customOrder","meta","facets","sortX","arr","a","sortY","facetKey","facetGroup","xCounts","xGroupKey","yCounts","yGroupKey","xCellsCount","yCellsCount","xStep","yStep","xPositions","xKeys","currentX","xKey","axisKeys","yPositions","yKeys","currentY","yKey","aes","groupedCellsData","cellUniqValues","valueKeys","createDiscreteColorScale","xDataByKeys","yDataByKeys","colors","type","axis","valueColumn","data","discreteValues","lodash","createDiscreteRoundColorScale","createContinuousColorScale","groups","dendrogramsData","hierarchyByGroupX","maxHeightX","groupKey","hierarchy","cluster","heightScale","hierarchyByGroupY","maxHeightY","inheritedAes","usedColumns","columnName","aesMap","columnValues","value","DEFAULT_AES","dataFrame","settingsId","chartSettings","inheritedDendrogramAes","onTooltipHintSwitch","cellsRenderingMode","component","DataFrameProvider","ChartsGroup","message","Error"],"mappings":"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"}
1
+ {"version":3,"file":"ChartRenderer.js","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 groupsCount = groupedCells.meta.xGroupKeys.length;\n this.chartSizes.chartWidth = keysCount * cellWidth + groupGap * (groupsCount - 1);\n } else {\n this.chartSizes.chartWidth = width;\n }\n\n if (cellHeight && firstFacet) {\n const keysCount = groupedCells.facets[firstFacet].yKeys.length;\n const groupsCount = groupedCells.meta.yGroupKeys.length;\n this.chartSizes.chartHeight = keysCount * cellHeight + groupGap * (groupsCount - 1);\n } else {\n this.chartSizes.chartHeight = height;\n }\n }\n\n // update scales for cell positions, x and y for each facet\n updateScales(\n facetKeys: string[],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n size: HeatmapSettingsImpl['chartSettings']['size'],\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY'],\n customOrder: {x: boolean, y: boolean, xGroup: boolean, yGroup: boolean},\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const { meta, facets } = groupedCells;\n const { sharedX, sharedY } = facetSettings;\n const sortX = (arr: string[], labels: Record<string, string> = {}) => {\n return arr.sort((a, b) => xAxis.sorting === 'asc'\n ? (labels[a] ?? a).localeCompare((labels[b] ?? b), 'en', { numeric: true })\n : (labels[b] ?? b).localeCompare((labels[a] ?? a), 'en', { numeric: true })\n );\n };\n const sortY = (arr: string[], labels: Record<string, string> = {}) => {\n return arr.sort((a, b) => yAxis.sorting === 'asc'\n ? (labels[a] ?? a).localeCompare((labels[b] ?? b), 'en', { numeric: true })\n : (labels[b] ?? b).localeCompare((labels[a] ?? a), 'en', { numeric: true })\n );\n };\n facetKeys.forEach(facetKey => {\n const facetGroup = facets[facetKey];\n const xGroupKeys = customOrder.xGroup ? meta.xGroupKeys : sortX(meta.xGroupKeys);\n const yGroupKeys = customOrder.yGroup ? meta.yGroupKeys : sortY(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 xGroupKeys.forEach(xKey => {\n const axisKeys = dendrogramX || customOrder.x ? xKeysByGroups[xKey] : sortX(xKeysByGroups[xKey], meta.xLabels);\n xKeys = xKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n xPositions.push(currentX);\n currentX += xStep;\n });\n // do not add offset for empty group\n if (axisKeys.length > 0) {\n currentX += groupGap;\n }\n });\n\n const yPositions: number[] = [];\n let yKeys: string[] = [];\n let currentY = 0;\n yGroupKeys.forEach(yKey => {\n const axisKeys = dendrogramY || customOrder.y ? yKeysByGroups[yKey] : sortY(yKeysByGroups[yKey], meta.yLabels);\n yKeys = yKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n yPositions.push(currentY);\n currentY += yStep;\n });\n // do not add offset for empty group\n if (axisKeys.length > 0) {\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);\n this.dendrograms[facetKey].x.treesByGroupKey = xGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupX[groupKey];\n const xKeys = xKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([xKeys.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);\n this.dendrograms[facetKey].y.treesByGroupKey = yGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupY[groupKey];\n const yKeys = yKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([yKeys.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 customOrder: {x: boolean, y: boolean, xGroup: boolean, yGroup: boolean},\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, chartSettings.xAxis, chartSettings.yAxis, dendrogramX, dendrogramY, customOrder);\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"],"names":["COS_PI_4","INCLINE_OFFSET","updateLinksHeight","root","scale","coord","setHeight","d","addShiftToLinkCoord","shift","coordFrom","coordTo","setX","getSteps","count","valueExtent","min","max","steps","i","step","getContinuousColorRange","normalization","colorsCount","extent","getMaxTextLength","keys","labels","textMeasurer","maxLabelSize","key","l","getCaptionHeight","size","angle","TITLE_LINE","ChartRenderer","__publicField","jsx","Fragment","DEFAULT_WIDTH","DEFAULT_HEIGHT","MIN_MARGIN","scaleOrdinal","scaleLinear","_a","node","createRoot","title","TITLE_LINE_HEIGHT","TITLE_MARGIN","valueType","legend","annotations","columnValue","continuousHeight","MIN_LEGEND_GRADIENT_HEIGHT","MAX_LEGEND_GRADIENT_HEIGHT","legendHeight","legendItems","emptySizes","getDefaultLabels","values","res","v","getContinuousLegendTicks","tickPositionScale","item","items","arrangeLegendParts","legendWidth","LEGEND_OFFSET","groupedCells","xAxis","yAxis","facetSettings","TextMeasurer","xGroupKeys","yGroupKeys","xGroupLabels","yGroupLabels","xKeysByGroups","yKeysByGroups","xLabels","yLabels","maxXLabelSize","maxYLabelSize","maxXGroupLabelSize","maxYGroupLabelSize","xCaptionTail","yCaptionTail","calculateCaptionTails","facetKeys","dendrogramX","dendrogramY","facetCount","maxNRows","maxNCols","sharedX","sharedY","currentLeft","currentTop","index","currentColumn","chartSides","getChartEdgeSides","stepX","stepY","sideElementSizes","calculateChartSideElementSizes","annotationsTitleSizes","calculateAnnotationTitleSizes","getPadding","side","CHART_SIDE_ELEMENTS","el","padding","sideElementBBoxes","calculateSideElementsBBoxes","outerWidth","outerHeight","chartsWidth","sum","chartsHeight","_key","groupGap","width","height","cellWidth","cellHeight","firstFacet","keysCount","groupsCount","customOrder","meta","facets","sortX","arr","a","b","sortY","facetKey","facetGroup","xCounts","xGroupKey","yCounts","yGroupKey","xCellsCount","yCellsCount","xStep","yStep","xPositions","xKeys","currentX","xKey","axisKeys","yPositions","yKeys","currentY","yKey","aes","groupedCellsData","cellUniqValues","valueKeys","createDiscreteColorScale","xDataByKeys","yDataByKeys","colors","type","axis","valueColumn","data","discreteValues","lodash","createDiscreteRoundColorScale","createContinuousColorScale","groups","dendrogramsData","hierarchyByGroupX","maxHeightX","groupKey","hierarchy","cluster","heightScale","hierarchyByGroupY","maxHeightY","inheritedAes","usedColumns","columnName","aesMap","columnValues","value","DEFAULT_AES","dataFrame","settingsId","chartSettings","inheritedDendrogramAes","onTooltipHintSwitch","cellsRenderingMode","component","DataFrameProvider","ChartsGroup","message","Error"],"mappings":"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"}
@@ -1,31 +1,31 @@
1
1
  var j = Object.defineProperty;
2
2
  var G = (e, t, i) => t in e ? j(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
3
- var g = (e, t, i) => G(e, typeof t != "symbol" ? t + "" : t, i);
3
+ var f = (e, t, i) => G(e, typeof t != "symbol" ? t + "" : t, i);
4
4
  import { j as A } from "../_virtual/jsx-runtime.js";
5
5
  import { c as Y } from "../_virtual/client.js";
6
6
  import { Error as O } from "../common/Error.js";
7
7
  import { DataFrameProvider as P } from "../common/useDataFrame.js";
8
8
  import { DEFAULT_HEIGHT as w, DEFAULT_WIDTH as N, TITLE_LINE_HEIGHT as U, TITLE_MARGIN as V } from "../constants.js";
9
- import { splitTextByWidth as _ } from "../utils/splitTextByWidth.js";
9
+ import { splitTextByWidth as R } from "../utils/splitTextByWidth.js";
10
10
  import { DEFAULT_COMMON_AES as X, LEGEND_OFFSET as B } from "../scatterplot/constants.js";
11
11
  import { getTicksAndFormat as Z } from "../scatterplot/utils/getTicksAndFormat.js";
12
12
  import { arrangeLegendParts as k } from "../utils/arrangeLegendParts.js";
13
13
  import { getContinuousColorScale as q } from "../utils/getContinuousColorScale.js";
14
14
  import { TextMeasurer as J } from "../utils/TextMeasurer/TextMeasurer.js";
15
15
  import { ChartsGroup as Q } from "./components/ChartsGroup.js";
16
- import { MIN_MARGIN as H, TICK_OFFSET as I, DEFAULT_TICKS_SIZE as R, MIN_PADDING as b, FACET_TITLE_OFFSET as $, FACET_TITLE_LINE as y, TITLE_LINE as K } from "./constants.js";
17
- import W from "../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/linear.js";
16
+ import { MIN_MARGIN as H, TICK_OFFSET as W, DEFAULT_TICKS_SIZE as _, MIN_PADDING as b, FACET_TITLE_OFFSET as $, FACET_TITLE_LINE as y, TITLE_LINE as K } from "./constants.js";
17
+ import I from "../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/linear.js";
18
18
  import F from "../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/symlog.js";
19
19
  import tt from "../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/ordinal.js";
20
20
  function it(e, t, i, o) {
21
21
  const s = [];
22
22
  return e % i === i - 1 && s.push("right"), e % i === 0 && s.push("left"), e < i && s.push("top"), (Math.ceil((e + 1) / i) === o || Math.ceil((e + 1) / i) === o - 1 && e % i > (t - 1) % i) && s.push("bottom"), s;
23
23
  }
24
- function st(e, t, i, o, s, h, d, n) {
25
- const r = h.includes("left") || !(n != null && n.sharedY), u = h.includes("bottom") || !(n != null && n.sharedX), C = h.includes("bottom") && e.title !== "", a = i.yAxisCaptionsWidth + 2 * I, x = (t.showTicks ? R : 0) + (t.hiddenLabels ? 0 : I), p = i.xAxisCaptionsWidth + 2 * I, E = (e.showTicks ? R : 0) + (e.hiddenLabels ? 0 : I), m = C ? K : 0, c = a + x, l = E + p + m, f = Math.max(...o.map((T) => s[T].length));
24
+ function st(e, t, i, o, s, n, d, h) {
25
+ const a = n.includes("left") || !(h != null && h.sharedY), u = n.includes("bottom") || !(h != null && h.sharedX), C = n.includes("bottom") && e.title !== "", r = i.yAxisCaptionsWidth + 2 * W, g = (t.showTicks ? _ : 0) + (t.hiddenLabels ? 0 : W), p = i.xAxisCaptionsWidth + 2 * W, E = (e.showTicks ? _ : 0) + (e.hiddenLabels ? 0 : W), m = C ? K : 0, c = r + g, l = E + p + m, x = Math.max(...o.map((T) => s[T].length));
26
26
  return {
27
- left: r ? c : b,
28
- top: f === 0 ? 0 : $ * 2 + f * y,
27
+ left: a ? c : b,
28
+ top: x === 0 ? 0 : $ * 2 + x * y,
29
29
  bottom: u ? l + 8 : b,
30
30
  right: d ? 0 : b
31
31
  };
@@ -47,33 +47,33 @@ function nt(e) {
47
47
  return typeof e == "object" && e !== null && "range" in e;
48
48
  }
49
49
  function ht(e, t, i, o) {
50
- return function(s, h, d) {
51
- var n;
50
+ return function(s, n, d) {
51
+ var h;
52
52
  if (nt(s)) {
53
- const { domain: r = o, range: u, type: C = "linear" } = s, a = q(u, r, C);
54
- return a.clamp(!0), a(d);
53
+ const { domain: a = o, range: u, type: C = "linear" } = s, r = q(u, a, C);
54
+ return r.clamp(!0), r(d);
55
55
  }
56
56
  if (v(s)) {
57
- const r = s.value, u = t[r];
58
- return (n = (u == null ? void 0 : u[String(e.getColumnValue(r, h))]) ?? X) == null ? void 0 : n[i];
57
+ const a = s.value, u = t[a];
58
+ return (h = (u == null ? void 0 : u[String(e.getColumnValue(a, n))]) ?? X) == null ? void 0 : h[i];
59
59
  }
60
60
  return s;
61
61
  };
62
62
  }
63
63
  class wt {
64
64
  constructor() {
65
- g(this, "reactRoot", null);
66
- g(this, "parentNode", null);
67
- g(this, "rootNode", null);
68
- g(this, "component", /* @__PURE__ */ A.jsx(A.Fragment, {}));
69
- g(this, "margins", {
65
+ f(this, "reactRoot", null);
66
+ f(this, "parentNode", null);
67
+ f(this, "rootNode", null);
68
+ f(this, "component", /* @__PURE__ */ A.jsx(A.Fragment, {}));
69
+ f(this, "margins", {
70
70
  top: H,
71
71
  bottom: H,
72
72
  left: H,
73
73
  right: H
74
74
  });
75
- g(this, "chartsDimensions", {});
76
- g(this, "chartSizes", {
75
+ f(this, "chartsDimensions", {});
76
+ f(this, "chartSizes", {
77
77
  chartWidth: N,
78
78
  // width of single chart
79
79
  chartHeight: w,
@@ -87,21 +87,21 @@ class wt {
87
87
  totalHeight: w
88
88
  // width of all charts in charts height, plus bottom axis, plus top title
89
89
  });
90
- g(this, "columnsCount", 1);
91
- g(this, "rowsCount", 1);
92
- g(this, "scales", {
93
- x: { null: W().domain([0, 10]).range([0, N]) },
94
- y: { null: W().domain([0, 10]).range([w, 0]) }
90
+ f(this, "columnsCount", 1);
91
+ f(this, "rowsCount", 1);
92
+ f(this, "scales", {
93
+ x: { null: I().domain([0, 10]).range([0, N]) },
94
+ y: { null: I().domain([0, 10]).range([w, 0]) }
95
95
  });
96
- g(this, "captionsSizes", {
96
+ f(this, "captionsSizes", {
97
97
  xAxisCaptionsWidth: 30,
98
98
  yAxisCaptionsWidth: 100
99
99
  });
100
- g(this, "facetTitles", {});
100
+ f(this, "facetTitles", {});
101
101
  // can be multiline
102
- g(this, "mainTitle", []);
102
+ f(this, "mainTitle", []);
103
103
  // can be multiline
104
- g(this, "legend", {
104
+ f(this, "legend", {
105
105
  width: 0,
106
106
  height: 0,
107
107
  items: []
@@ -121,9 +121,9 @@ class wt {
121
121
  this.chartSizes.chartWidth = t.width, this.chartSizes.chartHeight = t.height;
122
122
  }
123
123
  updateChartDimensions(t, i, o, s) {
124
- const { chartWidth: h, chartHeight: d } = this.chartSizes;
125
- let n = 0, r = 0;
126
- this.chartsDimensions = t.reduce((a, x, p) => {
124
+ const { chartWidth: n, chartHeight: d } = this.chartSizes;
125
+ let h = 0, a = 0;
126
+ this.chartsDimensions = t.reduce((r, g, p) => {
127
127
  const [E, m] = ot(p, this.columnsCount), c = it(p, t.length, this.columnsCount, this.rowsCount), l = st(
128
128
  o,
129
129
  s,
@@ -133,36 +133,36 @@ class wt {
133
133
  c,
134
134
  m === this.columnsCount - 1,
135
135
  i
136
- ), f = h + l.left + l.right, T = d + l.top + l.bottom;
137
- return a[x] = {
138
- left: n,
139
- top: r,
136
+ ), x = n + l.left + l.right, T = d + l.top + l.bottom;
137
+ return r[g] = {
138
+ left: h,
139
+ top: a,
140
140
  chartEdgeSides: c,
141
141
  padding: l,
142
- inner: { width: h, height: d },
143
- outer: { width: f, height: T }
144
- }, n += f, m === this.columnsCount - 1 && (n = 0, r += T), a;
142
+ inner: { width: n, height: d },
143
+ outer: { width: x, height: T }
144
+ }, h += x, m === this.columnsCount - 1 && (h = 0, a += T), r;
145
145
  }, {});
146
146
  const u = Math.max(
147
- ...t.map((a) => this.chartsDimensions[a].outer.width + this.chartsDimensions[a].left)
147
+ ...t.map((r) => this.chartsDimensions[r].outer.width + this.chartsDimensions[r].left)
148
148
  ), C = Math.max(
149
- ...t.map((a) => this.chartsDimensions[a].outer.height + this.chartsDimensions[a].top)
149
+ ...t.map((r) => this.chartsDimensions[r].outer.height + this.chartsDimensions[r].top)
150
150
  );
151
151
  this.chartSizes.chartsWidth = u, this.chartSizes.chartsHeight = C;
152
152
  }
153
- updateViewport(t, i, o, s, h, d, n) {
154
- const r = t.length, u = Math.min(i.nRows ?? r, r), C = Math.min(i.nCols ?? r, r);
155
- this.columnsCount = i.nRows ? Math.ceil(r / u) : C, this.rowsCount = Math.ceil(r / this.columnsCount);
156
- let [a, x] = [1 / 0, -1 / 0], p = -1 / 0;
153
+ updateViewport(t, i, o, s, n, d, h) {
154
+ const a = t.length, u = Math.min(i.nRows ?? a, a), C = Math.min(i.nCols ?? a, a);
155
+ this.columnsCount = i.nRows ? Math.ceil(a / u) : C, this.rowsCount = Math.ceil(a / this.columnsCount);
156
+ let [r, g] = [1 / 0, -1 / 0], p = -1 / 0;
157
157
  const E = t.reduce((m, c) => {
158
- const l = h[c], { minX: f, maxX: T, maxCount: z, maxCountFromGroups: M } = l;
159
- return a = Math.min(a, f), x = Math.max(x, T), p = Math.max(p, n === "vertical" ? z : M), m[c] = { minX: f, maxX: T, maxY: n === "vertical" ? z : M }, m;
158
+ const l = n[c], { minX: x, maxX: T, maxCount: z, maxCountFromGroups: M } = l;
159
+ return r = Math.min(r, x), g = Math.max(g, T), p = Math.max(p, h === "vertical" ? z : M), m[c] = { minX: x, maxX: T, maxY: h === "vertical" ? z : M }, m;
160
160
  }, {});
161
161
  t.forEach((m) => {
162
- const c = o.scale === "log" ? F() : W(), l = E[m], f = i.sharedX ? a : l.minX, T = i.sharedX ? x : l.maxX;
163
- c.domain([f, T]).range([0, this.chartSizes.chartWidth]), this.scales.x[m] = c;
162
+ const c = o.scale === "log" ? F() : I(), l = E[m], x = i.sharedX ? r : l.minX, T = i.sharedX ? g : l.maxX;
163
+ c.domain([x, T]).range([0, this.chartSizes.chartWidth]), this.scales.x[m] = c;
164
164
  }), t.forEach((m) => {
165
- const c = s.scale === "log" ? F() : W(), l = E[m], f = 0, T = i.sharedY ? p : l.maxY, z = [this.chartSizes.chartHeight, 0], M = c.copy().domain([f, T]).range([
165
+ const c = s.scale === "log" ? F() : I(), l = E[m], x = 0, T = i.sharedY ? p : l.maxY, z = [this.chartSizes.chartHeight, 0], M = c.copy().domain([x, T]).range([
166
166
  this.chartSizes.chartHeight,
167
167
  d.innerOffset
168
168
  ]);
@@ -174,12 +174,12 @@ class wt {
174
174
  updateCaptionsSize(t, i) {
175
175
  const o = new J("600 14px Arial");
176
176
  let s = 0;
177
- function h(d) {
178
- return Math.max(...d.map((n) => o.getTextWidth(n)));
177
+ function n(d) {
178
+ return Math.max(...d.map((h) => o.getTextWidth(h)));
179
179
  }
180
180
  i.hiddenLabels || Object.values(this.scales.y).forEach((d) => {
181
- const { ticks: n, format: r } = Z(d, !1);
182
- s = Math.max(s, h(n.map(r)));
181
+ const { ticks: h, format: a } = Z(d, !1);
182
+ s = Math.max(s, n(h.map(a)));
183
183
  }), this.captionsSizes = {
184
184
  xAxisCaptionsWidth: t.hiddenLabels ? 0 : 20,
185
185
  yAxisCaptionsWidth: s
@@ -187,38 +187,38 @@ class wt {
187
187
  }
188
188
  createMainTitle(t, i) {
189
189
  const o = this.chartsDimensions[t[0]], s = this.chartsDimensions[t[t.length - 1]];
190
- this.mainTitle = _(
190
+ this.mainTitle = R(
191
191
  i.name,
192
192
  this.chartSizes.chartsWidth - o.padding.left - s.padding.right,
193
193
  20
194
194
  );
195
195
  }
196
196
  createFacetTitles(t, i) {
197
- this.facetTitles = t.reduce((o, s, h) => (i[h].length === 1 && i[h][0] === "null" ? o[s] = [] : o[s] = _(i[h].join(", "), this.chartSizes.chartWidth, 14), o), {});
197
+ this.facetTitles = t.reduce((o, s, n) => (i[n].length === 1 && i[n][0] === "null" ? o[s] = [] : o[s] = R(i[n].join(", "), this.chartSizes.chartWidth, 14), o), {});
198
198
  }
199
199
  updateLegendSize(t, i, o, s) {
200
200
  if (!t.show) {
201
201
  this.legend = { width: 0, height: 0, items: [] };
202
202
  return;
203
203
  }
204
- const h = [], d = { width: 0, height: 0, left: 0, top: 0 };
205
- if (s.forEach((a) => {
206
- if (v(a.aes.fillColor) && o) {
207
- const x = a.aes.fillColor.value, p = i[o.value], E = o.label ?? o.value, m = tt().domain(p.values).range(p.values.map((c) => {
204
+ const n = [], d = { width: 0, height: 0, left: 0, top: 0 };
205
+ if (s.forEach((r) => {
206
+ if (v(r.aes.fillColor) && o) {
207
+ const g = r.aes.fillColor.value, p = i[o.value], E = o.label ?? o.value, m = tt().domain(p.values).range(p.values.map((c) => {
208
208
  var l;
209
209
  return ((l = p.aesMap[c]) == null ? void 0 : l.fillColor) ?? X.fillColor;
210
210
  }));
211
- h.push({ ...d, id: x, type: "discreteColor", title: E, scale: m, values: p.values, labels: p.labels });
211
+ n.push({ ...d, id: g, type: "discreteColor", title: E, scale: m, values: p.values, labels: p.labels });
212
212
  }
213
- }), !h.length) {
213
+ }), !n.length) {
214
214
  this.legend = { width: 0, height: 0, items: [] };
215
215
  return;
216
216
  }
217
- const n = k(h, this.chartSizes.chartHeight), r = n[n.length - 1], u = r.left + r.width + B, C = this.chartSizes.chartHeight;
217
+ const h = k(n, this.chartSizes.chartHeight), u = h.reduce((r, g) => Math.max(r, g.left + g.width), 0) + B, C = this.chartSizes.chartHeight;
218
218
  this.legend = {
219
219
  width: u,
220
220
  height: C,
221
- items: n
221
+ items: h
222
222
  };
223
223
  }
224
224
  updateMargins(t) {
@@ -230,16 +230,16 @@ class wt {
230
230
  right: this.legend.width + s
231
231
  }, this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right, this.chartSizes.totalHeight = this.margins.top + this.chartSizes.chartsHeight + this.margins.bottom;
232
232
  }
233
- render(t, i, o, s, h, d, n, r, u, C, a, x, p, E) {
233
+ render(t, i, o, s, n, d, h, a, u, C, r, g, p, E) {
234
234
  var D;
235
- const { xAxis: m, yAxis: c, size: l, title: f } = o;
236
- this.updateChartSizes(l), this.updateViewport(h, s, m, c, n, l, x), this.updateCaptionsSize(m, c), this.createFacetTitles(h, d), this.updateChartDimensions(h, s, m, c), this.createMainTitle(h, f), this.updateLegendSize(o.legend, r, a, u), this.updateMargins(l);
237
- const T = h.reduce((L, S) => Math.min(L, n[S].minX), 1 / 0), z = h.reduce((L, S) => Math.max(L, n[S].maxX), -1 / 0), M = /* @__PURE__ */ A.jsx(P, { dataFrame: t, children: /* @__PURE__ */ A.jsx(
235
+ const { xAxis: m, yAxis: c, size: l, title: x } = o;
236
+ this.updateChartSizes(l), this.updateViewport(n, s, m, c, h, l, g), this.updateCaptionsSize(m, c), this.createFacetTitles(n, d), this.updateChartDimensions(n, s, m, c), this.createMainTitle(n, x), this.updateLegendSize(o.legend, a, r, u), this.updateMargins(l);
237
+ const T = n.reduce((L, S) => Math.min(L, h[S].minX), 1 / 0), z = n.reduce((L, S) => Math.max(L, h[S].maxX), -1 / 0), M = /* @__PURE__ */ A.jsx(P, { dataFrame: t, children: /* @__PURE__ */ A.jsx(
238
238
  Q,
239
239
  {
240
240
  settingsId: i,
241
241
  chartSettings: o,
242
- facetKeys: h,
242
+ facetKeys: n,
243
243
  facetSettings: s,
244
244
  chartSizes: this.chartSizes,
245
245
  chartsDimensions: this.chartsDimensions,
@@ -249,12 +249,12 @@ class wt {
249
249
  mainTitle: this.mainTitle,
250
250
  facetTitles: this.facetTitles,
251
251
  captionsSizes: this.captionsSizes,
252
- histogramDataByFacets: n,
252
+ histogramDataByFacets: h,
253
253
  layers: u,
254
254
  aesColorGetter: ht(t, C, "fillColor", [T, z]),
255
255
  groupingDirection: p,
256
- groupingStack: x,
257
- groupingLabels: a ? r[a.value].labels : {},
256
+ groupingStack: g,
257
+ groupingLabels: r ? a[r.value].labels : {},
258
258
  legend: this.legend,
259
259
  onTooltipHintSwitch: E
260
260
  }