@milaboratories/graph-maker 1.1.174 → 1.1.175

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 (26) hide show
  1. package/dist/GraphMaker/components/LassoControls/index.vue.js +3 -2
  2. package/dist/GraphMaker/components/LassoControls/index.vue.js.map +1 -1
  3. package/dist/GraphMaker/index.vue.d.ts.map +1 -1
  4. package/dist/GraphMaker/index.vue.js +116 -110
  5. package/dist/GraphMaker/index.vue.js.map +1 -1
  6. package/dist/GraphMaker/store.d.ts +1 -0
  7. package/dist/GraphMaker/store.d.ts.map +1 -1
  8. package/dist/GraphMaker/store.js +30 -29
  9. package/dist/GraphMaker/store.js.map +1 -1
  10. package/dist/node_modules/@milaboratories/miplots4/dist/MiPlots.js +4 -4
  11. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/ChartRenderer.js +214 -214
  12. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/ChartRenderer.js.map +1 -1
  13. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/getClusters.js +20 -163
  14. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/getClusters.js.map +1 -1
  15. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/getDendrograms.js +47 -35
  16. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/getDendrograms.js.map +1 -1
  17. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/index.js +82 -79
  18. package/dist/node_modules/@milaboratories/miplots4/dist/heatmap/index.js.map +1 -1
  19. package/dist/node_modules/@milaboratories/miplots4/dist/node_modules/comlink/dist/esm/comlink.js +259 -0
  20. package/dist/node_modules/@milaboratories/miplots4/dist/node_modules/comlink/dist/esm/comlink.js.map +1 -0
  21. package/dist/node_modules/@milaboratories/miplots4/dist/scatterplot-umap/ChartRenderer.js +52 -50
  22. package/dist/node_modules/@milaboratories/miplots4/dist/scatterplot-umap/ChartRenderer.js.map +1 -1
  23. package/dist/node_modules/@milaboratories/miplots4/dist/types/common.js.map +1 -1
  24. package/dist/node_modules/@milaboratories/miplots4/dist/utils/WorkerFactory.js +14 -0
  25. package/dist/node_modules/@milaboratories/miplots4/dist/utils/WorkerFactory.js.map +1 -0
  26. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ChartRenderer.js","sources":["../../../../../../node_modules/@milaboratories/miplots4/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, 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 legendHeight = this.chartSizes.chartHeight;\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]], [legendHeight, 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]], [legendHeight, 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);\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 facetSettings: HeatmapSettingsImpl['facetSettings'],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const firstFacet = groupedCells.meta.facetKeys[0];\n if (cellWidth && facetSettings.sharedX && 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 && facetSettings.sharedY && 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 = sharedX && cellWidth ? cellWidth : (width - (xCounts.filter(count => count > 0).length - 1) * groupGap) / xCellsCount;\n const yStep = sharedY && cellHeight ? cellHeight : (height - (yCounts.filter(count => count > 0).length - 1) * groupGap) / yCellsCount;\n\n const xPositions: number[] = [];\n const 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.push(...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 const 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.push(...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 const { hierarchyByGroupX, hierarchyByGroupY } = dendrogramsData[facetKey];\n if (dendrogramX) {\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 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, facetSettings, 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","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","b","sortY","facetKey","facetGroup","xCounts","G","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","hierarchyByGroupY","maxHeightX","groupKey","hierarchy","cluster","heightScale","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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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"ChartRenderer.js","sources":["../../../../../../node_modules/@milaboratories/miplots4/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, 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 legendHeight = this.chartSizes.chartHeight;\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]], [legendHeight, 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]], [legendHeight, 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);\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 facetSettings: HeatmapSettingsImpl['facetSettings'],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const firstFacet = groupedCells.meta.facetKeys[0];\n if (cellWidth && facetSettings.sharedX && 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 && facetSettings.sharedY && 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 = sharedX && cellWidth ? cellWidth : (width - (xCounts.filter(count => count > 0).length - 1) * groupGap) / xCellsCount;\n const yStep = sharedY && 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, facetSettings, 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","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","b","sortY","facetKey","facetGroup","xCounts","xGroupKey","yCounts","G","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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","x_google_ignoreList":[0]}
@@ -1,169 +1,26 @@
1
- import E from "../node_modules/d3-random/src/lcg.js";
2
- function L(e, r) {
3
- let o = 0;
4
- for (let n = 0; n < e.length; n++)
5
- o += (e[n] - r[n]) * (e[n] - r[n]);
6
- return o;
7
- }
8
- function M(e, r) {
9
- return Math.sqrt(L(e, r));
10
- }
11
- const w = (e, r, o) => {
12
- let n = 0;
13
- for (const l of e)
14
- for (const s of r) n += o(l, s);
15
- return n / e.length / r.length;
16
- }, S = (e, r, o) => {
17
- let n = 0;
18
- for (const l of e)
19
- for (const s of r) n = Math.max(n, o(l, s));
20
- return n;
21
- }, y = (e, r, o) => {
22
- let n = 1 / 0;
23
- for (const l of e)
24
- for (const s of r) n = Math.min(n, o(l, s));
25
- return n;
26
- };
27
- function I(e) {
28
- switch (e) {
29
- case "average":
30
- return w;
31
- case "complete":
32
- return S;
33
- case "single":
34
- return y;
35
- default:
36
- return w;
37
- }
38
- }
39
- function q(e) {
40
- switch (e) {
41
- case "euclidean":
42
- return M;
43
- case "squaredEuclidean":
44
- return L;
45
- default:
46
- return M;
47
- }
48
- }
49
- function A(e) {
50
- const r = [], o = (n) => {
51
- if (n.children.length === 0)
52
- r.push(...n.indexes);
53
- else
54
- for (const l of n.children)
55
- o(l);
56
- };
57
- return o(e), r;
58
- }
59
- const v = 2e3;
60
- function O(e, r = "euclidean", o = "average") {
61
- if (e.length <= v)
62
- return k(e, r, o);
63
- const n = e.length, l = E(1), s = /* @__PURE__ */ new Set();
64
- for (; s.size < v; )
65
- s.add(Math.floor(l() * n));
66
- const f = Array.from(s), c = f.map((a) => e[a]), u = k(c, r, o);
67
- return b(u, e, f, r);
68
- }
69
- function b(e, r, o, n) {
70
- const l = q(n), s = new Set(o), f = /* @__PURE__ */ new Map();
71
- for (let c = 0; c < r.length; c++) {
72
- if (s.has(c)) continue;
73
- let u = 1 / 0, a = -1;
74
- for (const h of o) {
75
- const t = l(r[c], r[h]);
76
- t < u && (u = t, a = h);
77
- }
78
- f.set(c, a);
79
- }
80
- return z(e, f, o);
81
- }
82
- function z(e, r, o) {
83
- const n = /* @__PURE__ */ new Map(), l = (c) => {
84
- c.indexes.length === 1 && n.set(o[c.indexes[0]], c);
85
- for (const u of c.children)
86
- l(u);
87
- };
88
- l(e);
89
- const s = /* @__PURE__ */ new Map();
90
- for (const [c, u] of r) {
91
- const a = n.get(u);
92
- if (a) {
93
- s.has(a) || s.set(a, []);
94
- const h = s.get(a);
95
- h && h.push(c);
96
- }
97
- }
98
- const f = (c) => {
99
- c.indexes = c.indexes.map((u) => o[u]);
100
- for (const u of c.children)
101
- f(u);
102
- };
103
- f(e);
104
- for (const [c, u] of s)
105
- c.indexes = [...c.indexes, ...u];
106
- return {
107
- ...e,
108
- indexes: A(e)
109
- };
110
- }
111
- function k(e, r = "euclidean", o = "average") {
112
- const n = q(r), l = I(o), s = e.length, f = [], c = (t, i) => {
113
- if (t === i) return 0;
114
- t > i && ([t, i] = [i, t]);
115
- const d = t * s - t * (t + 1) / 2 + (i - t - 1);
116
- return f[d];
117
- }, u = (t, i, d) => {
118
- t > i && ([t, i] = [i, t]);
119
- const g = t * s - t * (t + 1) / 2 + (i - t - 1);
120
- f[g] = d;
121
- };
122
- for (let t = 0; t < s; t++)
123
- for (let i = t + 1; i < s; i++) {
124
- const d = n(e[t], e[i]);
125
- u(t, i, d);
126
- }
127
- const a = e.map((t, i) => ({
128
- height: 0,
129
- // Height 0 for leaf nodes
130
- indexes: [i],
131
- // Single index per cluster initially
132
- children: []
133
- // No children for leaf nodes
134
- }));
135
- for (let t = 0; t < s && !(t >= s - 1); t++) {
136
- let i = 1 / 0, d = 0, g = 0;
137
- for (let x = 0; x < a.length; x++)
138
- for (let p = x + 1; p < a.length; p++) {
139
- const m = l(a[x].indexes, a[p].indexes, c);
140
- m < i && (i = m, d = x, g = p);
1
+ const W = "KGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2NvbnN0IEE9MjMyODMwNjQzNjUzODY5NjNlLTI2O2Z1bmN0aW9uIEcoZT1NYXRoLnJhbmRvbSgpKXtsZXQgdD0oMDw9ZSYmZTwxP2UvQTpNYXRoLmFicyhlKSl8MDtyZXR1cm4oKT0+KHQ9MTY2NDUyNSp0KzEwMTM5MDQyMjN8MCxBKih0Pj4+MCkpfS8qKgogKiBAbGljZW5zZQogKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wCiAqL2NvbnN0IFI9U3ltYm9sKCJDb21saW5rLnByb3h5IiksWD1TeW1ib2woIkNvbWxpbmsuZW5kcG9pbnQiKSxZPVN5bWJvbCgiQ29tbGluay5yZWxlYXNlUHJveHkiKSxrPVN5bWJvbCgiQ29tbGluay5maW5hbGl6ZXIiKSx3PVN5bWJvbCgiQ29tbGluay50aHJvd24iKSxJPWU9PnR5cGVvZiBlPT0ib2JqZWN0IiYmZSE9PW51bGx8fHR5cGVvZiBlPT0iZnVuY3Rpb24iLFo9e2NhbkhhbmRsZTplPT5JKGUpJiZlW1JdLHNlcmlhbGl6ZShlKXtjb25zdHtwb3J0MTp0LHBvcnQyOm59PW5ldyBNZXNzYWdlQ2hhbm5lbDtyZXR1cm4gQyhlLHQpLFtuLFtuXV19LGRlc2VyaWFsaXplKGUpe3JldHVybiBlLnN0YXJ0KCksSyhlKX19LCQ9e2NhbkhhbmRsZTplPT5JKGUpJiZ3IGluIGUsc2VyaWFsaXplKHt2YWx1ZTplfSl7bGV0IHQ7cmV0dXJuIGUgaW5zdGFuY2VvZiBFcnJvcj90PXtpc0Vycm9yOiEwLHZhbHVlOnttZXNzYWdlOmUubWVzc2FnZSxuYW1lOmUubmFtZSxzdGFjazplLnN0YWNrfX06dD17aXNFcnJvcjohMSx2YWx1ZTplfSxbdCxbXV19LGRlc2VyaWFsaXplKGUpe3Rocm93IGUuaXNFcnJvcj9PYmplY3QuYXNzaWduKG5ldyBFcnJvcihlLnZhbHVlLm1lc3NhZ2UpLGUudmFsdWUpOmUudmFsdWV9fSxPPW5ldyBNYXAoW1sicHJveHkiLFpdLFsidGhyb3ciLCRdXSk7ZnVuY3Rpb24gQihlLHQpe2Zvcihjb25zdCBuIG9mIGUpaWYodD09PW58fG49PT0iKiJ8fG4gaW5zdGFuY2VvZiBSZWdFeHAmJm4udGVzdCh0KSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiBDKGUsdD1nbG9iYWxUaGlzLG49WyIqIl0pe3QuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZnVuY3Rpb24gaShhKXtpZighYXx8IWEuZGF0YSlyZXR1cm47aWYoIUIobixhLm9yaWdpbikpe2NvbnNvbGUud2FybihgSW52YWxpZCBvcmlnaW4gJyR7YS5vcmlnaW59JyBmb3IgY29tbGluayBwcm94eWApO3JldHVybn1jb25zdHtpZDpzLHR5cGU6ZyxwYXRoOmN9PU9iamVjdC5hc3NpZ24oe3BhdGg6W119LGEuZGF0YSksdT0oYS5kYXRhLmFyZ3VtZW50TGlzdHx8W10pLm1hcChoKTtsZXQgbzt0cnl7Y29uc3QgZj1jLnNsaWNlKDAsLTEpLnJlZHVjZSgobCxkKT0+bFtkXSxlKSxyPWMucmVkdWNlKChsLGQpPT5sW2RdLGUpO3N3aXRjaChnKXtjYXNlIkdFVCI6bz1yO2JyZWFrO2Nhc2UiU0VUIjpmW2Muc2xpY2UoLTEpWzBdXT1oKGEuZGF0YS52YWx1ZSksbz0hMDticmVhaztjYXNlIkFQUExZIjpvPXIuYXBwbHkoZix1KTticmVhaztjYXNlIkNPTlNUUlVDVCI6e2NvbnN0IGw9bmV3IHIoLi4udSk7bz10ZShsKX1icmVhaztjYXNlIkVORFBPSU5UIjp7Y29uc3R7cG9ydDE6bCxwb3J0MjpkfT1uZXcgTWVzc2FnZUNoYW5uZWw7QyhlLGQpLG89ZWUobCxbbF0pfWJyZWFrO2Nhc2UiUkVMRUFTRSI6bz12b2lkIDA7YnJlYWs7ZGVmYXVsdDpyZXR1cm59fWNhdGNoKGYpe289e3ZhbHVlOmYsW3ddOjB9fVByb21pc2UucmVzb2x2ZShvKS5jYXRjaChmPT4oe3ZhbHVlOmYsW3ddOjB9KSkudGhlbihmPT57Y29uc3RbcixsXT1NKGYpO3QucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LHIpLHtpZDpzfSksbCksZz09PSJSRUxFQVNFIiYmKHQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsaSksVCh0KSxrIGluIGUmJnR5cGVvZiBlW2tdPT0iZnVuY3Rpb24iJiZlW2tdKCkpfSkuY2F0Y2goZj0+e2NvbnN0W3IsbF09TSh7dmFsdWU6bmV3IFR5cGVFcnJvcigiVW5zZXJpYWxpemFibGUgcmV0dXJuIHZhbHVlIiksW3ddOjB9KTt0LnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxyKSx7aWQ6c30pLGwpfSl9KSx0LnN0YXJ0JiZ0LnN0YXJ0KCl9ZnVuY3Rpb24gSihlKXtyZXR1cm4gZS5jb25zdHJ1Y3Rvci5uYW1lPT09Ik1lc3NhZ2VQb3J0In1mdW5jdGlvbiBUKGUpe0ooZSkmJmUuY2xvc2UoKX1mdW5jdGlvbiBLKGUsdCl7Y29uc3Qgbj1uZXcgTWFwO3JldHVybiBlLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGZ1bmN0aW9uKGEpe2NvbnN0e2RhdGE6c309YTtpZighc3x8IXMuaWQpcmV0dXJuO2NvbnN0IGc9bi5nZXQocy5pZCk7aWYoZyl0cnl7ZyhzKX1maW5hbGx5e24uZGVsZXRlKHMuaWQpfX0pLFAoZSxuLFtdLHQpfWZ1bmN0aW9uIHAoZSl7aWYoZSl0aHJvdyBuZXcgRXJyb3IoIlByb3h5IGhhcyBiZWVuIHJlbGVhc2VkIGFuZCBpcyBub3QgdXNlYWJsZSIpfWZ1bmN0aW9uIEwoZSl7cmV0dXJuIHgoZSxuZXcgTWFwLHt0eXBlOiJSRUxFQVNFIn0pLnRoZW4oKCk9PntUKGUpfSl9Y29uc3QgRT1uZXcgV2Vha01hcCxiPSJGaW5hbGl6YXRpb25SZWdpc3RyeSJpbiBnbG9iYWxUaGlzJiZuZXcgRmluYWxpemF0aW9uUmVnaXN0cnkoZT0+e2NvbnN0IHQ9KEUuZ2V0KGUpfHwwKS0xO0Uuc2V0KGUsdCksdD09PTAmJkwoZSl9KTtmdW5jdGlvbiBRKGUsdCl7Y29uc3Qgbj0oRS5nZXQodCl8fDApKzE7RS5zZXQodCxuKSxiJiZiLnJlZ2lzdGVyKGUsdCxlKX1mdW5jdGlvbiBWKGUpe2ImJmIudW5yZWdpc3RlcihlKX1mdW5jdGlvbiBQKGUsdCxuPVtdLGk9ZnVuY3Rpb24oKXt9KXtsZXQgYT0hMTtjb25zdCBzPW5ldyBQcm94eShpLHtnZXQoZyxjKXtpZihwKGEpLGM9PT1ZKXJldHVybigpPT57VihzKSxMKGUpLHQuY2xlYXIoKSxhPSEwfTtpZihjPT09InRoZW4iKXtpZihuLmxlbmd0aD09PTApcmV0dXJue3RoZW46KCk9PnN9O2NvbnN0IHU9eChlLHQse3R5cGU6IkdFVCIscGF0aDpuLm1hcChvPT5vLnRvU3RyaW5nKCkpfSkudGhlbihoKTtyZXR1cm4gdS50aGVuLmJpbmQodSl9cmV0dXJuIFAoZSx0LFsuLi5uLGNdKX0sc2V0KGcsYyx1KXtwKGEpO2NvbnN0W28sZl09TSh1KTtyZXR1cm4geChlLHQse3R5cGU6IlNFVCIscGF0aDpbLi4ubixjXS5tYXAocj0+ci50b1N0cmluZygpKSx2YWx1ZTpvfSxmKS50aGVuKGgpfSxhcHBseShnLGMsdSl7cChhKTtjb25zdCBvPW5bbi5sZW5ndGgtMV07aWYobz09PVgpcmV0dXJuIHgoZSx0LHt0eXBlOiJFTkRQT0lOVCJ9KS50aGVuKGgpO2lmKG89PT0iYmluZCIpcmV0dXJuIFAoZSx0LG4uc2xpY2UoMCwtMSkpO2NvbnN0W2Yscl09eih1KTtyZXR1cm4geChlLHQse3R5cGU6IkFQUExZIixwYXRoOm4ubWFwKGw9PmwudG9TdHJpbmcoKSksYXJndW1lbnRMaXN0OmZ9LHIpLnRoZW4oaCl9LGNvbnN0cnVjdChnLGMpe3AoYSk7Y29uc3RbdSxvXT16KGMpO3JldHVybiB4KGUsdCx7dHlwZToiQ09OU1RSVUNUIixwYXRoOm4ubWFwKGY9PmYudG9TdHJpbmcoKSksYXJndW1lbnRMaXN0OnV9LG8pLnRoZW4oaCl9fSk7cmV0dXJuIFEocyxlKSxzfWZ1bmN0aW9uIGooZSl7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sZSl9ZnVuY3Rpb24geihlKXtjb25zdCB0PWUubWFwKE0pO3JldHVyblt0Lm1hcChuPT5uWzBdKSxqKHQubWFwKG49Pm5bMV0pKV19Y29uc3QgRj1uZXcgV2Vha01hcDtmdW5jdGlvbiBlZShlLHQpe3JldHVybiBGLnNldChlLHQpLGV9ZnVuY3Rpb24gdGUoZSl7cmV0dXJuIE9iamVjdC5hc3NpZ24oZSx7W1JdOiEwfSl9ZnVuY3Rpb24gTShlKXtmb3IoY29uc3RbdCxuXW9mIE8paWYobi5jYW5IYW5kbGUoZSkpe2NvbnN0W2ksYV09bi5zZXJpYWxpemUoZSk7cmV0dXJuW3t0eXBlOiJIQU5ETEVSIixuYW1lOnQsdmFsdWU6aX0sYV19cmV0dXJuW3t0eXBlOiJSQVciLHZhbHVlOmV9LEYuZ2V0KGUpfHxbXV19ZnVuY3Rpb24gaChlKXtzd2l0Y2goZS50eXBlKXtjYXNlIkhBTkRMRVIiOnJldHVybiBPLmdldChlLm5hbWUpLmRlc2VyaWFsaXplKGUudmFsdWUpO2Nhc2UiUkFXIjpyZXR1cm4gZS52YWx1ZX19ZnVuY3Rpb24geChlLHQsbixpKXtyZXR1cm4gbmV3IFByb21pc2UoYT0+e2NvbnN0IHM9bmUoKTt0LnNldChzLGEpLGUuc3RhcnQmJmUuc3RhcnQoKSxlLnBvc3RNZXNzYWdlKE9iamVjdC5hc3NpZ24oe2lkOnN9LG4pLGkpfSl9ZnVuY3Rpb24gbmUoKXtyZXR1cm4gbmV3IEFycmF5KDQpLmZpbGwoMCkubWFwKCgpPT5NYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLnRvU3RyaW5nKDE2KSkuam9pbigiLSIpfWZ1bmN0aW9uIE4oZSx0KXtsZXQgbj0wO2ZvcihsZXQgaT0wO2k8ZS5sZW5ndGg7aSsrKW4rPShlW2ldLXRbaV0pKihlW2ldLXRbaV0pO3JldHVybiBufWZ1bmN0aW9uIEQoZSx0KXtyZXR1cm4gTWF0aC5zcXJ0KE4oZSx0KSl9Y29uc3QgXz0oZSx0LG4pPT57bGV0IGk9MDtmb3IoY29uc3QgYSBvZiBlKWZvcihjb25zdCBzIG9mIHQpaSs9bihhLHMpO3JldHVybiBpL2UubGVuZ3RoL3QubGVuZ3RofSxyZT0oZSx0LG4pPT57bGV0IGk9MDtmb3IoY29uc3QgYSBvZiBlKWZvcihjb25zdCBzIG9mIHQpaT1NYXRoLm1heChpLG4oYSxzKSk7cmV0dXJuIGl9LHNlPShlLHQsbik9PntsZXQgaT0xLzA7Zm9yKGNvbnN0IGEgb2YgZSlmb3IoY29uc3QgcyBvZiB0KWk9TWF0aC5taW4oaSxuKGEscykpO3JldHVybiBpfTtmdW5jdGlvbiBvZShlKXtzd2l0Y2goZSl7Y2FzZSJhdmVyYWdlIjpyZXR1cm4gXztjYXNlImNvbXBsZXRlIjpyZXR1cm4gcmU7Y2FzZSJzaW5nbGUiOnJldHVybiBzZTtkZWZhdWx0OnJldHVybiBffX1mdW5jdGlvbiBIKGUpe3N3aXRjaChlKXtjYXNlImV1Y2xpZGVhbiI6cmV0dXJuIEQ7Y2FzZSJzcXVhcmVkRXVjbGlkZWFuIjpyZXR1cm4gTjtkZWZhdWx0OnJldHVybiBEfX1mdW5jdGlvbiBXKGUpe2NvbnN0IHQ9W10sbj1pPT57aWYoaS5jaGlsZHJlbi5sZW5ndGg9PT0wKXQucHVzaCguLi5pLmluZGV4ZXMpO2Vsc2UgZm9yKGNvbnN0IGEgb2YgaS5jaGlsZHJlbiluKGEpfTtyZXR1cm4gbihlKSx0fWNvbnN0IHY9MmUzO2Z1bmN0aW9uIGllKGUsdD0iZXVjbGlkZWFuIixuPSJhdmVyYWdlIil7aWYoZS5sZW5ndGg8PXYpcmV0dXJuIFUoZSx0LG4pO2NvbnN0IGk9ZS5sZW5ndGgsYT1HKDEpLHM9bmV3IFNldDtmb3IoO3Muc2l6ZTx2OylzLmFkZChNYXRoLmZsb29yKGEoKSppKSk7Y29uc3QgZz1BcnJheS5mcm9tKHMpLGM9Zy5tYXAobz0+ZVtvXSksdT1VKGMsdCxuKTtyZXR1cm4gYWUodSxlLGcsdCl9ZnVuY3Rpb24gYWUoZSx0LG4saSl7Y29uc3QgYT1IKGkpLHM9bmV3IFNldChuKSxnPW5ldyBNYXA7Zm9yKGxldCBjPTA7Yzx0Lmxlbmd0aDtjKyspe2lmKHMuaGFzKGMpKWNvbnRpbnVlO2xldCB1PTEvMCxvPS0xO2Zvcihjb25zdCBmIG9mIG4pe2NvbnN0IHI9YSh0W2NdLHRbZl0pO3I8dSYmKHU9cixvPWYpfWcuc2V0KGMsbyl9cmV0dXJuIGNlKGUsZyxuKX1mdW5jdGlvbiBjZShlLHQsbil7Y29uc3QgaT1uZXcgTWFwLGE9Yz0+e2MuaW5kZXhlcy5sZW5ndGg9PT0xJiZpLnNldChuW2MuaW5kZXhlc1swXV0sYyk7Zm9yKGNvbnN0IHUgb2YgYy5jaGlsZHJlbilhKHUpfTthKGUpO2NvbnN0IHM9bmV3IE1hcDtmb3IoY29uc3RbYyx1XW9mIHQpe2NvbnN0IG89aS5nZXQodSk7aWYobyl7cy5oYXMobyl8fHMuc2V0KG8sW10pO2NvbnN0IGY9cy5nZXQobyk7ZiYmZi5wdXNoKGMpfX1jb25zdCBnPWM9PntjLmluZGV4ZXM9Yy5pbmRleGVzLm1hcCh1PT5uW3VdKTtmb3IoY29uc3QgdSBvZiBjLmNoaWxkcmVuKWcodSl9O2coZSk7Zm9yKGNvbnN0W2MsdV1vZiBzKWMuaW5kZXhlcz1bLi4uYy5pbmRleGVzLC4uLnVdO3JldHVybnsuLi5lLGluZGV4ZXM6VyhlKX19ZnVuY3Rpb24gVShlLHQ9ImV1Y2xpZGVhbiIsbj0iYXZlcmFnZSIpe2NvbnN0IGk9SCh0KSxhPW9lKG4pLHM9ZS5sZW5ndGgsZz1bXSxjPShyLGwpPT57aWYocj09PWwpcmV0dXJuIDA7cj5sJiYoW3IsbF09W2wscl0pO2NvbnN0IGQ9cipzLXIqKHIrMSkvMisobC1yLTEpO3JldHVybiBnW2RdfSx1PShyLGwsZCk9PntyPmwmJihbcixsXT1bbCxyXSk7Y29uc3QgbT1yKnMtcioocisxKS8yKyhsLXItMSk7Z1ttXT1kfTtmb3IobGV0IHI9MDtyPHM7cisrKWZvcihsZXQgbD1yKzE7bDxzO2wrKyl7Y29uc3QgZD1pKGVbcl0sZVtsXSk7dShyLGwsZCl9Y29uc3Qgbz1lLm1hcCgocixsKT0+KHtoZWlnaHQ6MCxpbmRleGVzOltsXSxjaGlsZHJlbjpbXX0pKTtmb3IobGV0IHI9MDtyPHMmJiEocj49cy0xKTtyKyspe2xldCBsPTEvMCxkPTAsbT0wO2ZvcihsZXQgeT0wO3k8by5sZW5ndGg7eSsrKWZvcihsZXQgUz15KzE7UzxvLmxlbmd0aDtTKyspe2NvbnN0IHE9YShvW3ldLmluZGV4ZXMsb1tTXS5pbmRleGVzLGMpO3E8bCYmKGw9cSxkPXksbT1TKX1jb25zdCBsZT17aW5kZXhlczpbLi4ub1tkXS5pbmRleGVzLC4uLm9bbV0uaW5kZXhlc10saGVpZ2h0OmwsY2hpbGRyZW46W29bZF0sb1ttXV19O28uc3BsaWNlKE1hdGgubWF4KGQsbSksMSksby5zcGxpY2UoTWF0aC5taW4oZCxtKSwxKSxvLnB1c2gobGUpfWNvbnN0IGY9b1swXTtyZXR1cm57Li4uZixpbmRleGVzOlcoZil9fUMoe2dldENsdXN0ZXJzQXBwcm94aW1hdGU6aWV9KX0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldENsdXN0ZXJzLUJTY0p2ZWpmLmpzLm1hcAo=", G = (b) => Uint8Array.from(atob(b), (Z) => Z.charCodeAt(0)), c = typeof self < "u" && self.Blob && new Blob([G(W)], { type: "text/javascript;charset=utf-8" });
2
+ function m(b) {
3
+ let Z;
4
+ try {
5
+ if (Z = c && (self.URL || self.webkitURL).createObjectURL(c), !Z) throw "";
6
+ const l = new Worker(Z, {
7
+ name: b == null ? void 0 : b.name
8
+ });
9
+ return l.addEventListener("error", () => {
10
+ (self.URL || self.webkitURL).revokeObjectURL(Z);
11
+ }), l;
12
+ } catch {
13
+ return new Worker(
14
+ "data:text/javascript;base64," + W,
15
+ {
16
+ name: b == null ? void 0 : b.name
141
17
  }
142
- const C = {
143
- indexes: [...a[d].indexes, ...a[g].indexes],
144
- // Combine all indexes
145
- height: i,
146
- // Height is the distance at which clusters were merged
147
- children: [a[d], a[g]]
148
- // Store the two merged clusters as children
149
- };
150
- a.splice(Math.max(d, g), 1), a.splice(Math.min(d, g), 1), a.push(C);
18
+ );
19
+ } finally {
20
+ Z && (self.URL || self.webkitURL).revokeObjectURL(Z);
151
21
  }
152
- const h = a[0];
153
- return {
154
- ...h,
155
- indexes: A(h)
156
- // Ensure indexes are in hierarchical order
157
- };
158
22
  }
159
23
  export {
160
- w as averageLinkage,
161
- S as completeLinkage,
162
- M as euclidean,
163
- A as extractOrderedIndexes,
164
- k as getClusters,
165
- O as getClustersApproximate,
166
- y as singleLinkage,
167
- L as squaredEuclidean
24
+ m as default
168
25
  };
169
26
  //# sourceMappingURL=getClusters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getClusters.js","sources":["../../../../../../node_modules/@milaboratories/miplots4/src/heatmap/getClusters.ts"],"sourcesContent":["import type { Cluster } from './components/types';\nimport type { DendrogramDistance, DendrogramLinkage } from '../types';\nimport { randomLcg } from 'd3-random';\n\n/* DISTANCE FUNCTIONS - Calculate similarity between two data points */\n\n/**\n * Calculate squared Euclidean distance between two vectors\n * This is faster than regular Euclidean distance since it avoids the square root\n * Formula: Σ(p[i] - q[i])²\n * @param p First vector\n * @param q Second vector\n * @returns Squared distance (always positive)\n */\nexport function squaredEuclidean(p: number[], q: number[]) {\n let d = 0;\n // Sum the squared differences for each dimension\n for (let i = 0; i < p.length; i++) {\n d += (p[i] - q[i]) * (p[i] - q[i]);\n }\n return d;\n}\n\n/**\n * Calculate Euclidean distance between two vectors\n * This is the standard geometric distance in n-dimensional space\n * Formula: √(Σ(p[i] - q[i])²)\n * @param p First vector\n * @param q Second vector\n * @returns Euclidean distance\n */\nexport function euclidean(p: number[], q: number[]) {\n return Math.sqrt(squaredEuclidean(p, q));\n}\n\n/* LINKAGE FUNCTIONS - Define how to measure distance between two clusters */\n\n/**\n * Average Linkage\n * Calculates the average distance between all pairs of points in the two clusters\n * This is the most commonly used linkage method as it balances between single and complete linkage\n * @param setA Indexes of points in first cluster\n * @param setB Indexes of points in second cluster \n * @param getDistance Function to get distance between two point indexes\n * @returns Average distance between clusters\n */\nexport const averageLinkage = (setA: number[], setB: number[], getDistance: (i: number, j: number) => number) => {\n let distance = 0;\n // Sum all pairwise distances between clusters\n for (const a of setA) {\n for (const b of setB) distance += getDistance(a, b);\n }\n\n // Return average distance\n return distance / setA.length / setB.length;\n};\n\n/**\n * Complete Linkage (Maximum Linkage)\n * Uses the maximum distance between any pair of points in the two clusters\n * Tends to create compact, well-separated clusters\n * Formula: max{d(a,b)} for all a in A, b in B\n * @param setA Indexes of points in first cluster\n * @param setB Indexes of points in second cluster\n * @param getDistance Function to get distance between two point indexes\n * @returns Maximum distance between clusters\n */\nexport const completeLinkage = (setA: number[], setB: number[], getDistance: (i: number, j: number) => number) => {\n let distance = 0;\n // Find maximum distance between any pair of points\n for (const a of setA) {\n for (const b of setB) distance = Math.max(distance, getDistance(a, b));\n }\n\n return distance;\n};\n\n/**\n * Single Linkage (Minimum Linkage)\n * Uses the minimum distance between any pair of points in the two clusters\n * Tends to create elongated, chain-like clusters\n * Formula: min{d(a,b)} for all a in A, b in B\n * @param setA Indexes of points in first cluster\n * @param setB Indexes of points in second cluster\n * @param getDistance Function to get distance between two point indexes\n * @returns Minimum distance between clusters\n */\nexport const singleLinkage = (setA: number[], setB: number[], getDistance: (i: number, j: number) => number) => {\n let distance = Infinity;\n // Find minimum distance between any pair of points\n for (const a of setA) {\n for (const b of setB) distance = Math.min(distance, getDistance(a, b));\n }\n\n return distance;\n};\n\n/* HELPER FUNCTIONS - Factory functions for distance and linkage methods */\n\n/**\n * Get the appropriate linkage function based on the linkage type\n * @param linkage Type of linkage method to use\n * @returns Function that calculates distance between two clusters\n */\nfunction getLinkageFn(linkage: DendrogramLinkage) {\n switch (linkage) {\n case 'average': return averageLinkage;\n case 'complete': return completeLinkage;\n case 'single': return singleLinkage;\n default: return averageLinkage; // Default to average linkage\n }\n}\n\n/**\n * Get the appropriate distance function based on the distance type\n * @param distance Type of distance metric to use\n * @returns Function that calculates distance between two points\n */\nfunction getDistanceFn(distance: DendrogramDistance) {\n switch (distance) {\n case 'euclidean': return euclidean;\n case 'squaredEuclidean': return squaredEuclidean;\n default: return euclidean; // Default to euclidean distance\n }\n}\n\n/* UTILITY FUNCTIONS - Helper functions for cluster manipulation and sorting */\n\n/**\n * Extract indexes from a cluster hierarchy in the correct hierarchical order\n * This function traverses the cluster tree and collects all indexes in the order\n * they appear in the dendrogram (left-to-right traversal)\n * @param cluster The root cluster to extract indexes from\n * @returns Array of indexes in hierarchical order\n */\nexport function extractOrderedIndexes(cluster: Cluster): number[] {\n const orderedIndexes: number[] = [];\n \n const traverse = (c: Cluster) => {\n if (c.children.length === 0) {\n // Leaf node - add all indexes from this cluster\n orderedIndexes.push(...c.indexes);\n } else {\n // Internal node - traverse children in order (left to right)\n for (const child of c.children) {\n traverse(child);\n }\n }\n };\n \n traverse(cluster);\n return orderedIndexes;\n}\n\nconst MAX_CLUSTER_SIZE = 2000;\n\n// Approximate clustering using sampling for very large datasets\nexport function getClustersApproximate(\n dataValues: number[][], \n distanceType: DendrogramDistance = 'euclidean', \n linkageType: DendrogramLinkage = 'average',\n): Cluster { \n if (dataValues.length <= MAX_CLUSTER_SIZE) {\n return getClusters(dataValues, distanceType, linkageType);\n }\n \n const N = dataValues.length;\n const getRandom = randomLcg(1);\n // Step 1: Random sampling\n const sampleIndices = new Set<number>();\n while (sampleIndices.size < MAX_CLUSTER_SIZE) {\n sampleIndices.add(Math.floor(getRandom() * N));\n }\n \n const sampleIndicesArray = Array.from(sampleIndices);\n const sampleValues = sampleIndicesArray.map(i => dataValues[i]);\n \n // Step 2: Cluster the sample\n const sampleCluster = getClusters(sampleValues, distanceType, linkageType);\n \n // Step 3: Assign remaining points to nearest cluster\n return assignRemainingPoints(sampleCluster, dataValues, sampleIndicesArray, distanceType);\n}\n\n// Assign remaining points to the nearest cluster from the sample\nfunction assignRemainingPoints(\n sampleCluster: Cluster, \n dataValues: number[][], \n sampleIndices: number[],\n distanceType: DendrogramDistance\n): Cluster {\n // console.log('assignRemainingPoints');\n\n const distanceFn = getDistanceFn(distanceType);\n const sampleSet = new Set(sampleIndices);\n \n // Assign each non-sample point to nearest sample point\n const assignments = new Map<number, number>(); // point -> sample point\n for (let i = 0; i < dataValues.length; i++) {\n if (sampleSet.has(i)) continue;\n \n let minDistance = Infinity;\n let nearestSample = -1;\n \n for (const sampleIdx of sampleIndices) {\n const distance = distanceFn(dataValues[i], dataValues[sampleIdx]);\n if (distance < minDistance) {\n minDistance = distance;\n nearestSample = sampleIdx;\n }\n }\n \n assignments.set(i, nearestSample);\n }\n // Reconstruct cluster with all points\n return reconstructWithAssignments(sampleCluster, assignments, sampleIndices);\n}\n\n// Reconstruct cluster hierarchy with assigned points\nfunction reconstructWithAssignments(\n sampleCluster: Cluster, \n assignments: Map<number, number>, \n sampleIndices: number[]\n): Cluster {\n // Create a map of sample indices to their clusters\n const sampleToCluster = new Map<number, Cluster>();\n const findSampleClusters = (cluster: Cluster) => {\n if (cluster.indexes.length === 1) {\n sampleToCluster.set(sampleIndices[cluster.indexes[0]], cluster);\n }\n for (const child of cluster.children) {\n findSampleClusters(child);\n }\n };\n findSampleClusters(sampleCluster);\n \n // Group assigned points by their sample cluster\n const assignedPointsByCluster = new Map<Cluster, number[]>();\n for (const [pointIdx, sampleIdx] of assignments) {\n const sampleCluster = sampleToCluster.get(sampleIdx);\n if (sampleCluster) {\n if (!assignedPointsByCluster.has(sampleCluster)) {\n assignedPointsByCluster.set(sampleCluster, []);\n }\n const cluster = assignedPointsByCluster.get(sampleCluster);\n if (cluster) {\n cluster.push(pointIdx);\n }\n }\n }\n\n const fillCorrectIndexes = (c: Cluster) => {\n c.indexes = c.indexes.map(i => sampleIndices[i]);\n for (const child of c.children) {\n fillCorrectIndexes(child);\n }\n };\n fillCorrectIndexes(sampleCluster);\n for (const [cluster, assignedPoints] of assignedPointsByCluster) {\n cluster.indexes = [...cluster.indexes, ...assignedPoints];\n }\n \n return {\n ...sampleCluster,\n indexes: extractOrderedIndexes(sampleCluster)\n };\n}\n\n/* MAIN HIERARCHICAL CLUSTERING FUNCTION - Standard agglomerative clustering */\n\n/**\n * Main hierarchical clustering function using agglomerative approach\n * \n * This implements the standard agglomerative hierarchical clustering algorithm:\n * 1. Start with each point as its own cluster\n * 2. Compute pairwise distances between all points\n * 3. Iteratively merge the two closest clusters\n * 4. Continue until only one cluster remains\n * \n * Algorithm complexity:\n * - Time: O(n³) - for each of n-1 iterations, scan all n² cluster pairs\n * - Space: O(n²) - store upper triangular distance matrix\n * \n * Memory optimization:\n * - Uses upper triangular matrix storage (50% memory reduction)\n * - Only stores distances where i < j since distance matrix is symmetric\n * \n * @param dataKeys Labels for each data point\n * @param dataValues Feature vectors for each data point (n×d matrix)\n * @param distanceType Distance metric to use between points\n * @param linkageType Linkage method to use between clusters\n * @returns Root cluster containing the complete hierarchy\n */\nexport function getClusters(dataValues: number[][], distanceType: DendrogramDistance = 'euclidean', linkageType: DendrogramLinkage = 'average'): Cluster {\n const distanceFn = getDistanceFn(distanceType);\n const linkageFn = getLinkageFn(linkageType);\n \n const N = dataValues.length;\n \n // STEP 1: Precompute pairwise distances using upper triangular matrix\n // This reduces memory usage from O(n²) to O(n²/2) by only storing upper triangle\n // Since distance matrix is symmetric: d(i,j) = d(j,i)\n const distances: number[] = [];\n \n // Helper function to access distances in upper triangular matrix\n // Maps 2D coordinates (i,j) to 1D array index\n const getDistance = (i: number, j: number): number => {\n if (i === j) return 0; // Distance to self is always 0\n if (i > j) [i, j] = [j, i]; // Swap to ensure i < j (upper triangular)\n const index = i * N - (i * (i + 1)) / 2 + (j - i - 1);\n return distances[index];\n };\n \n // Helper function to set distances in upper triangular matrix\n const setDistance = (i: number, j: number, value: number): void => {\n if (i > j) [i, j] = [j, i]; // Swap to ensure i < j (upper triangular)\n const index = i * N - (i * (i + 1)) / 2 + (j - i - 1);\n distances[index] = value;\n };\n \n // Calculate all pairwise distances (only upper triangular)\n // This is the most expensive step: O(n²) distance calculations\n for (let i1 = 0; i1 < N; i1++) {\n for (let i2 = i1 + 1; i2 < N; i2++) {\n const v = distanceFn(dataValues[i1], dataValues[i2]);\n setDistance(i1, i2, v);\n } \n }\n\n // STEP 2: Initialize clusters - each point starts as its own cluster\n // This creates the leaf nodes of the dendrogram\n const clusters: Cluster[] = dataValues.map((_, index) => ({\n height: 0, // Height 0 for leaf nodes\n indexes: [index], // Single index per cluster initially\n children: [] // No children for leaf nodes\n }));\n\n // STEP 3: Agglomerative clustering - merge clusters iteratively\n // This is the main clustering loop that builds the hierarchy\n for (let iteration = 0; iteration < N; iteration++) {\n // Stop when only one cluster remains (root of dendrogram)\n if (iteration >= N - 1) break;\n\n // Find the two closest clusters using the selected linkage method\n let nearestDistance = Infinity;\n let nearest1 = 0;\n let nearest2 = 0;\n\n // Check all pairs of clusters (upper triangular to avoid duplicates)\n for (let clusterIdx1 = 0; clusterIdx1 < clusters.length; clusterIdx1++) {\n for (let clusterIdx2 = clusterIdx1 + 1; clusterIdx2 < clusters.length; clusterIdx2++) {\n // Calculate distance between clusters using linkage method\n const distance = linkageFn(clusters[clusterIdx1].indexes, clusters[clusterIdx2].indexes, getDistance);\n \n // Keep track of the closest pair\n if (distance < nearestDistance) {\n nearestDistance = distance;\n nearest1 = clusterIdx1;\n nearest2 = clusterIdx2;\n }\n }\n }\n\n // STEP 4: Merge the two closest clusters\n // Create a new cluster that combines the two closest clusters\n const newCluster = {\n indexes: [...clusters[nearest1].indexes, ...clusters[nearest2].indexes], // Combine all indexes\n height: nearestDistance, // Height is the distance at which clusters were merged\n children: [clusters[nearest1], clusters[nearest2]], // Store the two merged clusters as children\n };\n\n // STEP 5: Update cluster list\n // Remove the two merged clusters and add the new merged cluster\n // Remove higher index first to avoid index shifting issues\n clusters.splice(Math.max(nearest1, nearest2), 1);\n clusters.splice(Math.min(nearest1, nearest2), 1);\n clusters.push(newCluster);\n }\n\n // STEP 6: Return the root cluster with properly ordered keys and indexes\n // The root cluster contains the complete hierarchy\n const rootCluster = clusters[0];\n return {\n ...rootCluster,\n indexes: extractOrderedIndexes(rootCluster) // Ensure indexes are in hierarchical order\n };\n}\n"],"names":["squaredEuclidean","p","q","d","i","euclidean","averageLinkage","setA","setB","getDistance","distance","a","b","completeLinkage","singleLinkage","getLinkageFn","linkage","getDistanceFn","extractOrderedIndexes","cluster","orderedIndexes","traverse","c","child","MAX_CLUSTER_SIZE","getClustersApproximate","dataValues","distanceType","linkageType","getClusters","N","getRandom","randomLcg","sampleIndices","sampleIndicesArray","sampleValues","sampleCluster","assignRemainingPoints","distanceFn","sampleSet","assignments","minDistance","nearestSample","sampleIdx","reconstructWithAssignments","sampleToCluster","findSampleClusters","assignedPointsByCluster","pointIdx","fillCorrectIndexes","assignedPoints","linkageFn","distances","j","index","setDistance","value","i1","i2","v","clusters","_","iteration","nearestDistance","nearest1","nearest2","clusterIdx1","clusterIdx2","newCluster","rootCluster"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"getClusters.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,46 +1,58 @@
1
- import { getClustersApproximate as d } from "./getClusters.js";
2
- import x from "../node_modules/d3-hierarchy/src/hierarchy/index.js";
3
- function X(r, y, l, G) {
4
- const { facetKeys: K, xGroupKeys: B, yGroupKeys: g } = r.meta, m = {};
5
- if (y && G.sharedX)
1
+ import { WorkerFactory as B } from "../utils/WorkerFactory.js";
2
+ import g from "./getClusters.js";
3
+ import G from "../node_modules/d3-hierarchy/src/hierarchy/index.js";
4
+ const h = new B(() => new g());
5
+ async function b(i, p, n, d) {
6
+ const { facetKeys: w, xGroupKeys: x, yGroupKeys: K } = i.meta, c = {};
7
+ if (!p && !n)
8
+ return c;
9
+ if (p && d.sharedX)
6
10
  throw Error("Dendrogram on X axis is not available with shared by facets X axis");
7
- return K.forEach((s) => {
8
- const f = {
11
+ if (n && d.sharedY)
12
+ throw Error("Dendrogram on Y axis is not available with shared by facets Y axis");
13
+ return h.reset(), await Promise.all(w.map(async (y) => {
14
+ const m = {
9
15
  hierarchyByGroupX: {},
10
16
  hierarchyByGroupY: {}
11
- }, o = r.facets[s];
12
- if (y) {
13
- const i = [];
14
- B.forEach((e) => {
15
- const n = o.xKeysByGroups[e], p = o.yKeys, t = d(
16
- n.map((a) => p.map((h) => {
17
- var c;
18
- return ((c = o.cells[a][h]) == null ? void 0 : c.normalizedValue.dataSource) ?? y.fillNA;
17
+ }, s = i.facets[y];
18
+ if (p) {
19
+ const l = [], f = await Promise.all(x.map(async (r) => {
20
+ const o = s.xKeysByGroups[r], e = s.yKeys;
21
+ return h.wrapper.getClustersApproximate(
22
+ o.map((a) => e.map((t) => {
23
+ var u;
24
+ return ((u = s.cells[a][t]) == null ? void 0 : u.normalizedValue.dataSource) ?? p.fillNA;
19
25
  })),
20
- y.distance,
21
- y.linkage
22
- ), u = t.indexes.map((a) => n[a]);
23
- r.facets[s].xKeysByGroups[e] = u, i.push(...u), f.hierarchyByGroupX[e] = x(t);
24
- }), r.facets[s].xKeys = i;
26
+ p.distance,
27
+ p.linkage
28
+ );
29
+ }));
30
+ x.forEach((r, o) => {
31
+ const e = f[o], a = e.indexes.map((t) => s.xKeysByGroups[r][t]);
32
+ i.facets[y].xKeysByGroups[r] = a, l.push(...a), m.hierarchyByGroupX[r] = G(e);
33
+ }), i.facets[y].xKeys = l;
25
34
  }
26
- if (l) {
27
- const i = [];
28
- g.forEach((e) => {
29
- const n = o.yKeysByGroups[e], p = o.xKeys, t = d(
30
- n.map((a) => p.map((h) => {
31
- var c;
32
- return ((c = o.cells[h][a]) == null ? void 0 : c.normalizedValue.dataSource) ?? l.fillNA;
35
+ if (n) {
36
+ const l = [], f = await Promise.all(K.map(async (r) => {
37
+ const o = s.yKeysByGroups[r], e = s.xKeys;
38
+ return h.wrapper.getClustersApproximate(
39
+ o.map((a) => e.map((t) => {
40
+ var u;
41
+ return ((u = s.cells[t][a]) == null ? void 0 : u.normalizedValue.dataSource) ?? n.fillNA;
33
42
  })),
34
- l.distance,
35
- l.linkage
36
- ), u = t.indexes.map((a) => n[a]);
37
- r.facets[s].yKeysByGroups[e] = u, i.push(...u), f.hierarchyByGroupY[e] = x(t);
38
- }), r.facets[s].yKeys = i;
43
+ n.distance,
44
+ n.linkage
45
+ );
46
+ }));
47
+ K.forEach((r, o) => {
48
+ const e = f[o], a = e.indexes.map((t) => s.yKeysByGroups[r][t]);
49
+ i.facets[y].yKeysByGroups[r] = a, l.push(...a), m.hierarchyByGroupY[r] = G(e);
50
+ }), i.facets[y].yKeys = l;
39
51
  }
40
- m[s] = f;
41
- }), m;
52
+ c[y] = m;
53
+ })), c;
42
54
  }
43
55
  export {
44
- X as getDendrograms
56
+ b as getDendrograms
45
57
  };
46
58
  //# sourceMappingURL=getDendrograms.js.map