@milaboratories/miplots4 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/bubble/BubbleSettingsImpl.d.ts +4 -2
  2. package/dist/bubble/BubbleSettingsImpl.d.ts.map +1 -1
  3. package/dist/bubble/BubbleSettingsImpl.js +32 -29
  4. package/dist/bubble/BubbleSettingsImpl.js.map +1 -1
  5. package/dist/bubble/getGroupedCellsData.d.ts +1 -1
  6. package/dist/bubble/getGroupedCellsData.d.ts.map +1 -1
  7. package/dist/bubble/getGroupedCellsData.js +2 -2
  8. package/dist/bubble/getGroupedCellsData.js.map +1 -1
  9. package/dist/bubble/index.d.ts.map +1 -1
  10. package/dist/bubble/index.js +16 -15
  11. package/dist/bubble/index.js.map +1 -1
  12. package/dist/heatmap/HeatmapSettingsImpl.d.ts +4 -2
  13. package/dist/heatmap/HeatmapSettingsImpl.d.ts.map +1 -1
  14. package/dist/heatmap/HeatmapSettingsImpl.js +20 -17
  15. package/dist/heatmap/HeatmapSettingsImpl.js.map +1 -1
  16. package/dist/heatmap/fillCellsData.d.ts +3 -3
  17. package/dist/heatmap/fillCellsData.d.ts.map +1 -1
  18. package/dist/heatmap/fillCellsData.js +89 -94
  19. package/dist/heatmap/fillCellsData.js.map +1 -1
  20. package/dist/heatmap/getCells.d.ts +3 -3
  21. package/dist/heatmap/getCells.d.ts.map +1 -1
  22. package/dist/heatmap/getCells.js +3 -3
  23. package/dist/heatmap/getCells.js.map +1 -1
  24. package/dist/heatmap/index.d.ts.map +1 -1
  25. package/dist/heatmap/index.js +21 -22
  26. package/dist/heatmap/index.js.map +1 -1
  27. package/dist/heatmap/labelParts.d.ts +21 -0
  28. package/dist/heatmap/labelParts.d.ts.map +1 -0
  29. package/dist/heatmap/labelParts.js +55 -0
  30. package/dist/heatmap/labelParts.js.map +1 -0
  31. package/dist/types/bubble.d.ts +26 -16
  32. package/dist/types/bubble.d.ts.map +1 -1
  33. package/dist/types/bubble.js +4 -3
  34. package/dist/types/bubble.js.map +1 -1
  35. package/dist/types/heatmap.d.ts +22 -12
  36. package/dist/types/heatmap.d.ts.map +1 -1
  37. package/dist/types/heatmap.js +4 -3
  38. package/dist/types/heatmap.js.map +1 -1
  39. package/dist/utils/compareColumnGroups.d.ts +4 -0
  40. package/dist/utils/compareColumnGroups.d.ts.map +1 -0
  41. package/dist/utils/compareColumnGroups.js +7 -0
  42. package/dist/utils/compareColumnGroups.js.map +1 -0
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"fillCellsData.js","names":[],"sources":["../../src/heatmap/fillCellsData.ts"],"sourcesContent":["import { deviation, extent, mean, quantileSorted, sum } from 'd3-array';\nimport type { DataFrame } from '../DataFrame';\nimport type { AggregationMethod, ColumnName, DataValue, NormalizationMethod } from '../types';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport { exhaustive } from '../utils';\nimport { getFacetOrGroupKey } from '../utils/getFacetOrGroupKey';\nimport { intersect } from '../utils/intersect';\nimport type { BubbleSettingsImpl } from '../bubble/BubbleSettingsImpl';\nimport { getFacetLabels } from '../discrete/utils/getFacetLabels';\nimport { getFacetStringKey } from '../discrete/utils/getFacetStringKey';\n\nexport type Cell<T extends string> = {\n isCell: true;\n idx: number;\n id: string;\n value: Record<T, DataValue>;\n normalizedValue: Record<T, DataValue>;\n x: DataValue;\n y: DataValue;\n};\n\nexport type GroupedCellsData<T extends string> = {\n meta: {\n valueSources: T[]; // dataSource for heatmap, color and size for bubble - main data for every cell\n\n facetKeys: string[];\n xGroupKeys: string[];\n yGroupKeys: string[];\n\n xKeys: string[];\n yKeys: string[];\n xKeysByGroups: Record<string, string[]>;\n yKeysByGroups: Record<string, string[]>;\n\n // for titles, if facet by more 1 columns title has several values separated by commas\n facetKeyValues: Record<string, string[]>;\n xGroupKeyValues: Record<string, string[]>;\n yGroupKeyValues: Record<string, string[]>;\n\n xLabels: Record<string, string>;\n yLabels: Record<string, string>;\n xGroupLabels: Record<string, string>;\n yGroupLabels: Record<string, string>;\n\n valueExtent: Record<T, [number, number]>; // for color/size scales\n // data for labels, annotations and dendrograms\n xDataByKeys: Record<string, Record<string, DataValue>>;\n yDataByKeys: Record<string, Record<string, DataValue>>;\n };\n //facet groups\n facets: Record<\n string,\n {\n // axis keys\n xKeys: string[];\n yKeys: string[];\n // axis keys grouped by group keys from meta\n xKeysByGroups: Record<string, string[]>;\n yKeysByGroups: Record<string, string[]>;\n // cells grouped by X, then by Y\n cells: Record<string, Record<string, Cell<T>>>;\n }\n >;\n};\n\nfunction normalizeByStd(values: number[]) {\n const stdValue = deviation(values);\n const meanValue = mean(values);\n\n if (stdValue === undefined || meanValue === undefined || stdValue === 0) {\n return (v: number) => v;\n }\n return (v: number) => (v - meanValue) / stdValue;\n}\nfunction normalizeByMinMax(values: number[]) {\n const meanValue = mean(values);\n const [min, max] = extent(values);\n if (meanValue === undefined || min === undefined || max === undefined || max === min) {\n return (v: number) => v;\n }\n return (v: number) => (v - meanValue) / (max - min);\n}\n\nfunction getNormalizationFn(method: NormalizationMethod, values: number[]) {\n if (method === 'standardScaling') {\n return normalizeByStd(values);\n }\n if (method === 'meanNormalization') {\n return normalizeByMinMax(values);\n }\n return (v: number) => v;\n}\n\nfunction aggregateNumeric(method: AggregationMethod, values: number[]) {\n switch (method) {\n case 'max': {\n let res = values[0];\n for (const v of values) {\n res = Math.max(res, v);\n }\n return res;\n }\n case 'min': {\n let res = values[0];\n for (const v of values) {\n res = Math.min(res, v);\n }\n return res;\n }\n case 'median': {\n const valuesSorted = values.sort((a, b) => a - b);\n return quantileSorted(valuesSorted, 0.5) as number;\n }\n case 'mean': {\n return mean(values) ?? values[0];\n }\n case 'sum': {\n return sum(values) as number;\n }\n default: exhaustive(method, `Unknown aggregation function ${method}`);\n }\n}\nfunction aggregateString(values: string[]) {\n const list = [...new Set(values)].sort();\n if (list.length > 3) {\n return [...list.slice(0, 3), '...'].join(', ');\n }\n return list.join(', ');\n}\n\n// all combinations with 1 key from each list\nfunction getKeysCombinations(keysLists: string[][]) {\n if (!keysLists.length) {\n return [];\n }\n let result: string[][] = [[]];\n for (const keys of keysLists) {\n const nextResult: string[][] = [];\n for (const key of keys) {\n nextResult.push(...result.map(resultItem => [...resultItem, key]));\n }\n result = nextResult;\n }\n return result;\n}\nconst sortByLabels = (arr: string[], direction: 'asc' | 'desc', labels: Record<string, string> = {}) => {\n const sign = direction === 'asc' ? 1 : -1;\n return arr.sort((a, b) => sign * (labels[a] ?? a).localeCompare((labels[b] ?? b), 'en', { numeric: true }));\n};\n\nfunction isMissing(v: DataValue | undefined): boolean {\n if (v === null || v === undefined) return true;\n if (typeof v === 'number' && Number.isNaN(v)) return true;\n return false;\n}\n\nfunction compareValues(a: DataValue | undefined, b: DataValue | undefined, direction: 'asc' | 'desc'): number {\n const aMissing = isMissing(a);\n const bMissing = isMissing(b);\n if (aMissing && bMissing) return 0;\n if (aMissing) return 1; // NA pushed to end regardless of direction\n if (bMissing) return -1;\n const sign = direction === 'asc' ? 1 : -1;\n if (typeof a === 'number' && typeof b === 'number') {\n return sign * (a < b ? -1 : a > b ? 1 : 0);\n }\n return sign * String(a).localeCompare(String(b), 'en', { numeric: true });\n}\n\nexport const sortByColumns = (\n arr: string[],\n direction: 'asc' | 'desc',\n sortColumns: ColumnName[],\n dataByKeys: Record<string, Record<string, DataValue>>\n) => {\n return arr.sort((a, b) => {\n for (const col of sortColumns) {\n const cmp = compareValues(dataByKeys[col.value]?.[a], dataByKeys[col.value]?.[b], direction);\n if (cmp !== 0) return cmp;\n }\n return 0;\n });\n};\nfunction applyAggregation<T extends string>(\n result: GroupedCellsData<T>,\n aggregation: HeatmapSettingsImpl['aggregation'],\n additionalDataColumnsX: string[],\n additionalDataColumnsY: string[],\n annotations: HeatmapSettingsImpl['annotations']\n) {\n if (aggregation.x || aggregation.y) {\n const valueExtent: GroupedCellsData<T>['meta']['valueExtent'] = result.meta.valueSources.reduce((r, key) => {\n r[key] = [Infinity, -Infinity] as [number, number];\n return r;\n }, {} as GroupedCellsData<T>['meta']['valueExtent']);\n for (const facetKey of result.meta.facetKeys) {\n const { xKeys, yKeys, cells, xKeysByGroups, yKeysByGroups } = result.facets[facetKey];\n const xGroups = aggregation.x ? xKeysByGroups : xKeys.reduce((res, xKey) => { res[xKey] = [xKey]; return res; }, {} as Record<string, string[]>);\n const yGroups = aggregation.y ? yKeysByGroups : yKeys.reduce((res, yKey) => { res[yKey] = [yKey]; return res; }, {} as Record<string, string[]>);\n const xNewKeys = Object.keys(xGroups);\n const yNewKeys = Object.keys(yGroups);\n\n for (const xGroupKey of xNewKeys) {\n for (const yGroupKey of yNewKeys) {\n // collect values for aggregation to arrays\n const valuesBySources: Record<T, number[]> = result.meta.valueSources.reduce((r, v) => {\n r[v] = [];\n return r;\n }, {} as Record<T, number[]>);\n for (const xKey of xGroups[xGroupKey]) {\n for (const yKey of yGroups[yGroupKey]) {\n for (const valueSource of result.meta.valueSources) {\n const cellValue = cells[xKey]?.[yKey]?.value?.[valueSource];\n if (cellValue !== undefined) {\n valuesBySources[valueSource].push(cellValue as number);\n }\n }\n delete cells[xKey]?.[yKey];\n }\n }\n // create new cells with aggregated values\n for (const valueSource of result.meta.valueSources) {\n const values = valuesBySources[valueSource];\n if (values.length > 0) {\n const value = aggregateNumeric(aggregation.method, values);\n if (!result.facets[facetKey].cells[xGroupKey]) {\n result.facets[facetKey].cells[xGroupKey] = {};\n }\n if (!result.facets[facetKey].cells[xGroupKey][yGroupKey]) {\n result.facets[facetKey].cells[xGroupKey][yGroupKey] = {\n isCell: true,\n idx: 0,\n id: `${xGroupKey}_${yGroupKey}`,\n x: xGroupKey,\n y: yGroupKey,\n value: result.meta.valueSources.reduce((r, v) => { r[v] = null; return r; }, {} as Record<T, DataValue>),\n normalizedValue: result.meta.valueSources.reduce((r, v) => { r[v] = null; return r; }, {} as Record<T, DataValue>),\n };\n }\n const cell = result.facets[facetKey].cells[xGroupKey][yGroupKey];\n cell.value[valueSource] = value;\n cell.normalizedValue[valueSource] = value;\n\n valueExtent[valueSource][0] = Math.min(cell.normalizedValue?.[valueSource], valueExtent[valueSource][0]);\n valueExtent[valueSource][1] = Math.max(cell.normalizedValue?.[valueSource], valueExtent[valueSource][1]);\n }\n }\n }\n }\n // add aggregated values for X annotations\n if (aggregation.x) {\n for (const xGroupKey of xNewKeys) {\n for (const columnKey of additionalDataColumnsX) {\n const annotation = annotations.find((v) => v.valueColumn.value === columnKey || v.valueColumn.valueLabels === columnKey);\n if (!annotation) {\n continue;\n }\n const values: DataValue[] = [];\n for (const xKey of xGroups[xGroupKey]) {\n values.push(result.meta.xDataByKeys[columnKey][xKey]);\n delete result.meta.xDataByKeys[columnKey][xKey];\n }\n const value = annotation.type === 'continuous' ? aggregateNumeric(aggregation.method, values as number[]) : aggregateString(values as string[]);\n result.meta.xDataByKeys[columnKey][xGroupKey] = value;\n }\n }\n }\n // add aggregated values for Y annotations\n if (aggregation.y) {\n for (const columnKey of additionalDataColumnsY) {\n result.meta.yDataByKeys[columnKey] = {};\n }\n for (const yGroupKey of yNewKeys) {\n for (const columnKey of additionalDataColumnsY) {\n const annotation = annotations.find((v) => v.valueColumn.value === columnKey || v.valueColumn.valueLabels === columnKey);\n if (!annotation) {\n continue;\n }\n const values: DataValue[] = [];\n for (const yKey of yGroups[yGroupKey]) {\n values.push(result.meta.yDataByKeys[columnKey][yKey]);\n delete result.meta.yDataByKeys[columnKey][yKey];\n }\n const value = annotation.type === 'continuous' ? aggregateNumeric(aggregation.method, values as number[]) : aggregateString(values as string[]);\n result.meta.yDataByKeys[columnKey][yGroupKey] = value;\n }\n }\n }\n // erase grouping - we aggregated by them and now there is no grouping in the chart;\n // replace axis keys with group keys - now group keys are new axis keys\n if (aggregation.x) {\n result.facets[facetKey].xKeys = Object.keys(xKeysByGroups);\n result.facets[facetKey].xKeysByGroups = { 'null': result.facets[facetKey].xKeys };\n result.meta.xLabels = result.meta.xGroupLabels;\n result.meta.xGroupKeys = ['null'];\n result.meta.xGroupKeyValues = { null: ['null'] };\n }\n if (aggregation.y) {\n result.facets[facetKey].yKeys = Object.keys(yKeysByGroups);\n result.facets[facetKey].yKeysByGroups = { 'null': result.facets[facetKey].yKeys };\n result.meta.yLabels = result.meta.yGroupLabels;\n result.meta.yGroupKeys = ['null'];\n result.meta.yGroupKeyValues = { null: ['null'] };\n }\n }\n result.meta.valueExtent = valueExtent;\n }\n}\n\nfunction updateValueExtent<T extends string>(result: GroupedCellsData<T>, cell: Cell<T>) {\n for (const valueSource of result.meta.valueSources) {\n result.meta.valueExtent[valueSource][0] = Math.min(cell.normalizedValue?.[valueSource] as number, result.meta.valueExtent[valueSource][0]);\n result.meta.valueExtent[valueSource][1] = Math.max(cell.normalizedValue?.[valueSource] as number, result.meta.valueExtent[valueSource][1]);\n }\n\n}\nfunction applyNormalization<T extends string>(\n result: GroupedCellsData<T>,\n normalizationBySources: Record<T, HeatmapSettingsImpl['normalization']>,\n) {\n if (Object.values(normalizationBySources).length) {\n const valueExtent: GroupedCellsData<T>['meta']['valueExtent'] = result.meta.valueSources.reduce((r, key) => {\n if (normalizationBySources[key]) {\n r[key] = [Infinity, -Infinity] as [number, number];\n }\n return r;\n }, {} as GroupedCellsData<T>['meta']['valueExtent']);\n for (const facetKey of result.meta.facetKeys) {\n const { xKeys, yKeys, cells } = result.facets[facetKey];\n\n for (const valueSource of result.meta.valueSources) {\n const normalization = normalizationBySources[valueSource];\n if (!normalization) {\n continue;\n }\n const cellKeys = normalization.direction === 'row' ? xKeys : yKeys;\n const groupKeys = normalization.direction === 'row' ? yKeys : xKeys;\n const cellGetter = normalization.direction === 'row'\n ? (cellKey: string, groupKey: string) => cells[cellKey]?.[groupKey]\n : (cellKey: string, groupKey: string) => cells[groupKey]?.[cellKey];\n for (const groupKey of groupKeys) {\n const values: number[] = [];\n for (const cellKey of cellKeys) {\n const v = cellGetter(cellKey, groupKey)?.value?.[valueSource];\n if (v !== undefined) {\n values.push(v as number);\n }\n }\n const normalize = getNormalizationFn(normalization.method, values);\n for (const cellKey of cellKeys) {\n const cell = cellGetter(cellKey, groupKey);\n if (cell !== undefined) {\n cell.normalizedValue[valueSource] = normalize(cell.value?.[valueSource] as number);\n valueExtent[valueSource][0] = Math.min(cell.normalizedValue?.[valueSource], valueExtent[valueSource][0]);\n valueExtent[valueSource][1] = Math.max(cell.normalizedValue?.[valueSource], valueExtent[valueSource][1]);\n }\n }\n }\n }\n\n }\n result.meta.valueExtent = {...result.meta.valueExtent, valueExtent};\n }\n}\n\nexport function fillCellsData<T extends string>(\n result: GroupedCellsData<T>,\n {\n data,\n xColumn,\n yColumn,\n valueColumns,\n facetBy,\n xGroupBy,\n yGroupBy,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalizationBySource, // separated for color and size for example\n NAValueAs,\n transformBySource, // same per-source pattern as normalization\n keysOrder,\n xAxis,\n yAxis,\n xSortBy,\n ySortBy,\n aggregation,\n showEmptyRows = false,\n showEmptyColumns = false,\n }: {\n data: DataFrame;\n xColumn: ColumnName;\n yColumn: ColumnName;\n valueColumns: Record<string, ColumnName>;\n facetBy: ColumnName[];\n xGroupBy: ColumnName[];\n yGroupBy: ColumnName[];\n facetSettings: HeatmapSettingsImpl['facetSettings'];\n annotations: HeatmapSettingsImpl['annotations'];\n dendrogramX: HeatmapSettingsImpl['dendrogramX'];\n dendrogramY: HeatmapSettingsImpl['dendrogramY'];\n normalizationBySource: Record<T, HeatmapSettingsImpl['normalization']>;\n NAValueAs: HeatmapSettingsImpl['NAValueAs'];\n transformBySource?: Record<T, HeatmapSettingsImpl['transform']>;\n keysOrder: HeatmapSettingsImpl['keysOrder'];\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'] | BubbleSettingsImpl['chartSettings']['xAxis'];\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'] | BubbleSettingsImpl['chartSettings']['yAxis'];\n xSortBy?: HeatmapSettingsImpl['xSortBy'];\n ySortBy?: HeatmapSettingsImpl['ySortBy'];\n aggregation: HeatmapSettingsImpl['aggregation'];\n showEmptyRows?: boolean;\n showEmptyColumns?: boolean;\n }\n) {\n const facetKeysLists = facetBy.length\n ? facetBy.map(column => keysOrder[column.value] ?? data.getColumnCategories(column.value))\n : [['null']];\n\n const xGroupKeysLists = xGroupBy.length\n ? xGroupBy.map(column => keysOrder[column.value] ?? data.getColumnCategories(column.value))\n : [['null']];\n const yGroupKeysLists = yGroupBy.length\n ? yGroupBy.map(column => keysOrder[column.value] ?? data.getColumnCategories(column.value))\n : [['null']];\n let facetKeysCombinations = getKeysCombinations(facetKeysLists);\n const xGroupKeysCombinations = getKeysCombinations(xGroupKeysLists);\n const yGroupKeysCombinations = getKeysCombinations(yGroupKeysLists);\n\n if (facetSettings?.order?.length) {\n facetKeysCombinations = facetKeysCombinations.filter(keys => facetSettings.order?.includes(getFacetStringKey(keys)));\n }\n const facetKeys = facetKeysCombinations.map(getFacetOrGroupKey);\n const facetKeysSet = new Set(facetKeys);\n const xGroupKeys = xGroupKeysCombinations.map(getFacetOrGroupKey);\n const yGroupKeys = yGroupKeysCombinations.map(getFacetOrGroupKey);\n\n result.meta.facetKeys = facetKeys;\n result.meta.xGroupKeys = xGroupKeys;\n result.meta.yGroupKeys = yGroupKeys;\n\n const facetLabels = getFacetLabels(data, facetBy, facetKeys, facetKeysCombinations);\n result.meta.facetKeyValues = facetKeys.reduce((res: Record<string, string[]>, key) => {\n res[key] = facetLabels[key];\n return res;\n }, {});\n\n result.meta.xGroupKeyValues = xGroupKeys.reduce((res: Record<string, string[]>, key, index) => {\n res[key] = xGroupKeysCombinations[index];\n return res;\n }, {});\n result.meta.yGroupKeyValues = yGroupKeys.reduce((res: Record<string, string[]>, key, index) => {\n res[key] = yGroupKeysCombinations[index];\n return res;\n }, {});\n\n const xLabelsSource = xColumn.valueLabels ?? xColumn.value;\n const yLabelsSource = yColumn.valueLabels ?? yColumn.value;\n const annotationColumnsX = annotations.filter(item => item.axis === 'x').map(item => item.valueColumn.valueLabels ?? item.valueColumn.value);\n const annotationColumnsY = annotations.filter(item => item.axis === 'y').map(item => item.valueColumn.valueLabels ?? item.valueColumn.value);\n const dendrogramXColumns = Object.values(dendrogramX ?? {}).map(column => column.value);\n const dendrogramYColumns = Object.values(dendrogramY ?? {}).map(column => column.value);\n const xSortByColumns = (xSortBy ?? []).map(c => c.value);\n const ySortByColumns = (ySortBy ?? []).map(c => c.value);\n const additionalDataColumnsX = [...new Set([...annotationColumnsX, ...dendrogramXColumns, ...xSortByColumns, xLabelsSource])];\n const additionalDataColumnsY = [...new Set([...annotationColumnsY, ...dendrogramYColumns, ...ySortByColumns, yLabelsSource])];\n\n for (let i = 0; i < data.rowsCount; i++) {\n const facetKey = getFacetOrGroupKey(facetBy.map(column => data.getColumnValue(column.value, i)));\n if (!facetKeysSet.has(facetKey)) {\n continue;\n }\n const xGroupKey = getFacetOrGroupKey(xGroupBy.map(column => data.getColumnValue(column.value, i)));\n const yGroupKey = getFacetOrGroupKey(yGroupBy.map(column => data.getColumnValue(column.value, i)));\n const xGroupLabel = xGroupBy.map(column => data.getColumnValue(column.valueLabels ?? column.value, i)).join(', ');\n const yGroupLabel = yGroupBy.map(column => data.getColumnValue(column.valueLabels ?? column.value, i)).join(', ');\n result.meta.xGroupLabels[xGroupKey] = xGroupLabel;\n result.meta.yGroupLabels[yGroupKey] = yGroupLabel;\n const x = String(data.getColumnValue(xColumn.value, i));\n const y = String(data.getColumnValue(yColumn.value, i));\n\n const values = result.meta.valueSources.reduce((r, key) => {\n let v = (data.getColumnValue(valueColumns[key].value, i) ?? NAValueAs) as number | null;\n if (transformBySource?.[key] === 'log' && typeof v === 'number') {\n const transformed = Math.log10(v);\n v = Number.isFinite(transformed) ? transformed : null;\n }\n r[key] = v;\n return r;\n }, {} as Record<string, DataValue>);\n\n if (x === 'null' || y === 'null') {\n continue;\n }\n\n const allValuesNull = Object.values(values).every(v => v === null);\n\n if (allValuesNull && !showEmptyRows && !showEmptyColumns) {\n continue;\n }\n\n if (!result.facets[facetKey]) {\n result.facets[facetKey] = {\n xKeys: [],\n yKeys: [],\n xKeysByGroups: {},\n yKeysByGroups: {},\n cells: {},\n };\n }\n if (!result.facets[facetKey].xKeysByGroups[xGroupKey]) {\n result.facets[facetKey].xKeysByGroups[xGroupKey] = [];\n }\n if (!result.facets[facetKey].yKeysByGroups[yGroupKey]) {\n result.facets[facetKey].yKeysByGroups[yGroupKey] = [];\n }\n\n if (!allValuesNull || showEmptyColumns) {\n result.facets[facetKey].xKeys.push(x);\n result.facets[facetKey].xKeysByGroups[xGroupKey].push(x);\n const xLabelsSourceValue = data.getColumnValue(xLabelsSource, i);\n if (result.meta.xLabels[x] && String(xLabelsSourceValue) !== result.meta.xLabels[x]) {\n throw Error(`More than 1 x-label value for x=${x}`);\n }\n result.meta.xLabels[x] = String(xLabelsSourceValue);\n for (const columnKey of additionalDataColumnsX) {\n const isAddedColumn = typeof result.meta.xDataByKeys[columnKey] !== 'undefined';\n const isAddedValue = isAddedColumn && typeof result.meta.xDataByKeys[columnKey][x] !== 'undefined';\n if (!isAddedColumn) {\n result.meta.xDataByKeys[columnKey] = {};\n }\n if (isAddedValue && result.meta.xDataByKeys[columnKey][x] !== data.getColumnValue(columnKey, i)) {\n throw Error(`More than 1 value for x = ${x} and column = ${columnKey}`);\n }\n if (!isAddedValue) {\n result.meta.xDataByKeys[columnKey][x] = data.getColumnValue(columnKey, i);\n }\n }\n }\n\n if (!allValuesNull || showEmptyRows) {\n result.facets[facetKey].yKeys.push(y);\n result.facets[facetKey].yKeysByGroups[yGroupKey].push(y);\n const yLabelsSourceValue = data.getColumnValue(yLabelsSource, i);\n if (result.meta.yLabels[y] && String(yLabelsSourceValue) !== result.meta.yLabels[y]) {\n throw Error(`More than 1 y-label value for y=${y}`);\n }\n result.meta.yLabels[y] = String(yLabelsSourceValue);\n for (const columnKey of additionalDataColumnsY) {\n const isAddedColumn = typeof result.meta.yDataByKeys[columnKey] !== 'undefined';\n const isAddedValue = isAddedColumn && typeof result.meta.yDataByKeys[columnKey][y] !== 'undefined';\n if (!isAddedColumn) {\n result.meta.yDataByKeys[columnKey] = {};\n }\n if (isAddedValue && result.meta.yDataByKeys[columnKey][y] !== data.getColumnValue(columnKey, i)) {\n throw Error(`More than 1 value for y = ${y} and column = ${columnKey}`);\n }\n if (!isAddedValue) {\n result.meta.yDataByKeys[columnKey][y] = data.getColumnValue(columnKey, i);\n }\n }\n }\n\n if (allValuesNull) {\n continue;\n }\n\n if (!result.facets[facetKey].cells[x]) {\n result.facets[facetKey].cells[x] = {};\n }\n\n for (const valueSource of result.meta.valueSources) {\n if (result.facets[facetKey].cells[x][y] && result.facets[facetKey].cells[x][y].value[valueSource] !== values[valueSource]) {\n throw Error(`More than 1 value for x=${x}, y=${y}`);\n }\n }\n\n result.facets[facetKey].cells[x][y] = {\n isCell: true,\n idx: i,\n id: `${x}_${y}`,\n x,\n y,\n value: values,\n normalizedValue: values,\n };\n\n updateValueExtent(result, result.facets[facetKey].cells[x][y]);\n }\n\n result.meta.facetKeys = result.meta.facetKeys.filter((key) => result.facets[key]); // filter only used;\n\n // make uniq x, y, x-group and y-group keys\n for (const facetKey of result.meta.facetKeys) {\n const facet = result.facets[facetKey];\n const uniqueXKeys = [...new Set(facet.xKeys)];\n const uniqueYKeys = [...new Set(facet.yKeys)];\n facet.xKeys = keysOrder[xColumn.value] ? intersect(keysOrder[xColumn.value], uniqueXKeys) : uniqueXKeys;\n facet.yKeys = keysOrder[yColumn.value] ? intersect(keysOrder[yColumn.value], uniqueYKeys) : uniqueYKeys;\n for (const xGroupKey of xGroupKeys) {\n result.facets[facetKey].xKeysByGroups[xGroupKey] = intersect(\n facet.xKeys,\n result.facets[facetKey].xKeysByGroups[xGroupKey]\n );\n }\n for (const yGroupKey of yGroupKeys) {\n result.facets[facetKey].yKeysByGroups[yGroupKey] = intersect(\n facet.yKeys,\n result.facets[facetKey].yKeysByGroups[yGroupKey]\n );\n }\n }\n\n applyAggregation(result, aggregation, additionalDataColumnsX, additionalDataColumnsY, annotations);\n applyNormalization(result, normalizationBySource);\n\n // All sorting is consolidated here. Dendrograms run later in getDendrograms and reorder\n // per-facet keys for axes where clustering is on — that's the only post-fillCellsData sort.\n\n // Sort group keys (by group labels). Skip when user supplied custom order via keysOrder.\n const xGroupCustomOrder = xGroupBy.some(c => keysOrder[c.value]?.length > 0);\n const yGroupCustomOrder = yGroupBy.some(c => keysOrder[c.value]?.length > 0);\n if (!xGroupCustomOrder) {\n result.meta.xGroupKeys = sortByLabels([...result.meta.xGroupKeys], xAxis.sorting, result.meta.xGroupLabels);\n }\n if (!yGroupCustomOrder) {\n result.meta.yGroupKeys = sortByLabels([...result.meta.yGroupKeys], yAxis.sorting, result.meta.yGroupLabels);\n }\n\n // every facet may contain not all of available keys, but for shared axes it is necessary to have all of them\n const effectiveXSortBy = (!dendrogramX && !aggregation.x && xSortBy?.length) ? xSortBy : null;\n result.meta.xKeysByGroups = result.meta.xGroupKeys.reduce((res: Record<string, string[]>, xGroupKey) => {\n const uniqueXKeys = [...new Set(\n result.meta.facetKeys.flatMap(facetKey => result.facets[facetKey].xKeysByGroups[xGroupKey])\n )];\n const existingXKeys = effectiveXSortBy\n ? sortByColumns(uniqueXKeys, xAxis.sorting, effectiveXSortBy, result.meta.xDataByKeys)\n : sortByLabels(uniqueXKeys, xAxis.sorting, result.meta.xLabels);\n res[xGroupKey] = keysOrder[xColumn.value] ? intersect(keysOrder[xColumn.value], existingXKeys) : existingXKeys;\n return res;\n }, {});\n result.meta.xKeys = result.meta.xGroupKeys.reduce((res: string[], xGroupKey: string) => {\n res = res.concat(result.meta.xKeysByGroups[xGroupKey]);\n return res;\n }, []);\n\n const effectiveYSortBy = (!dendrogramY && !aggregation.y && ySortBy?.length) ? ySortBy : null;\n result.meta.yKeysByGroups = result.meta.yGroupKeys.reduce((res: Record<string, string[]>, yGroupKey) => {\n const uniqueYKeys = [...new Set(\n result.meta.facetKeys.flatMap(facetKey => result.facets[facetKey].yKeysByGroups[yGroupKey])\n )];\n const existingYKeys = effectiveYSortBy\n ? sortByColumns(uniqueYKeys, yAxis.sorting, effectiveYSortBy, result.meta.yDataByKeys)\n : sortByLabels(uniqueYKeys, yAxis.sorting, result.meta.yLabels);\n res[yGroupKey] = keysOrder[yColumn.value] ? intersect(keysOrder[yColumn.value], existingYKeys) : existingYKeys;\n return res;\n }, {});\n result.meta.yKeys = result.meta.yGroupKeys.reduce((res: string[], yGroupKey: string) => {\n res = res.concat(result.meta.yKeysByGroups[yGroupKey]);\n return res;\n }, []);\n\n // Propagate the sorted meta order to per-facet keys. Used by the renderer when sharedX/Y is\n // false. Intersection preserves meta order while filtering down to keys present in each facet.\n // getDendrograms may re-order facet keys later for axes with clustering on.\n for (const facetKey of result.meta.facetKeys) {\n for (const xGroupKey of result.meta.xGroupKeys) {\n result.facets[facetKey].xKeysByGroups[xGroupKey] = intersect(\n result.meta.xKeysByGroups[xGroupKey],\n result.facets[facetKey].xKeysByGroups[xGroupKey] ?? []\n );\n }\n result.facets[facetKey].xKeys = result.meta.xGroupKeys.flatMap(\n g => result.facets[facetKey].xKeysByGroups[g] ?? []\n );\n for (const yGroupKey of result.meta.yGroupKeys) {\n result.facets[facetKey].yKeysByGroups[yGroupKey] = intersect(\n result.meta.yKeysByGroups[yGroupKey],\n result.facets[facetKey].yKeysByGroups[yGroupKey] ?? []\n );\n }\n result.facets[facetKey].yKeys = result.meta.yGroupKeys.flatMap(\n g => result.facets[facetKey].yKeysByGroups[g] ?? []\n );\n }\n\n for (const valueSource of result.meta.valueSources) {\n // avoid render errors on empty data\n if (result.meta.valueExtent[valueSource][0] === Infinity) {\n result.meta.valueExtent[valueSource][0] = 0;\n }\n if (result.meta.valueExtent[valueSource][1] === -Infinity) {\n result.meta.valueExtent[valueSource][1] = 0;\n }\n }\n\n result.meta.xLabels['null'] = xColumn.nullValueLabel ?? 'NA';\n result.meta.yLabels['null'] = yColumn.nullValueLabel ?? 'NA';\n result.meta.xGroupLabels['null'] = xGroupBy.map(column => column.nullValueLabel ?? 'NA').join(', ');\n result.meta.yGroupLabels['null'] = yGroupBy.map(column => column.nullValueLabel ?? 'NA').join(', ');\n return result;\n}"],"mappings":"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"}
1
+ {"version":3,"file":"fillCellsData.js","names":[],"sources":["../../src/heatmap/fillCellsData.ts"],"sourcesContent":["import { deviation, extent, mean, quantileSorted, sum } from 'd3-array';\nimport type { DataFrame } from '../DataFrame';\nimport type { AggregationMethod, ColumnName, DataValue, NormalizationMethod } from '../types';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport { exhaustive } from '../utils';\nimport { getFacetOrGroupKey } from '../utils/getFacetOrGroupKey';\nimport { intersect } from '../utils/intersect';\nimport type { BubbleSettingsImpl } from '../bubble/BubbleSettingsImpl';\nimport { getFacetLabels } from '../discrete/utils/getFacetLabels';\nimport { getFacetStringKey } from '../discrete/utils/getFacetStringKey';\nimport { joinLabel, resolveLabelParts } from './labelParts';\n\nexport type Cell<T extends string> = {\n isCell: true;\n idx: number;\n id: string;\n value: Record<T, DataValue>;\n normalizedValue: Record<T, DataValue>;\n x: DataValue;\n y: DataValue;\n};\n\nexport type GroupedCellsData<T extends string> = {\n meta: {\n valueSources: T[]; // dataSource for heatmap, color and size for bubble - main data for every cell\n\n facetKeys: string[];\n xGroupKeys: string[];\n yGroupKeys: string[];\n\n xKeys: string[];\n yKeys: string[];\n xKeysByGroups: Record<string, string[]>;\n yKeysByGroups: Record<string, string[]>;\n\n // for titles, if facet by more 1 columns title has several values separated by commas\n facetKeyValues: Record<string, string[]>;\n xGroupKeyValues: Record<string, string[]>;\n yGroupKeyValues: Record<string, string[]>;\n\n xLabels: Record<string, string>;\n yLabels: Record<string, string>;\n xGroupLabels: Record<string, string>;\n yGroupLabels: Record<string, string>;\n\n valueExtent: Record<T, [number, number]>; // for color/size scales\n // data for labels, annotations and dendrograms\n xDataByKeys: Record<string, Record<string, DataValue>>;\n yDataByKeys: Record<string, Record<string, DataValue>>;\n };\n //facet groups\n facets: Record<\n string,\n {\n // axis keys\n xKeys: string[];\n yKeys: string[];\n // axis keys grouped by group keys from meta\n xKeysByGroups: Record<string, string[]>;\n yKeysByGroups: Record<string, string[]>;\n // cells grouped by X, then by Y\n cells: Record<string, Record<string, Cell<T>>>;\n }\n >;\n};\n\nfunction normalizeByStd(values: number[]) {\n const stdValue = deviation(values);\n const meanValue = mean(values);\n\n if (stdValue === undefined || meanValue === undefined || stdValue === 0) {\n return (v: number) => v;\n }\n return (v: number) => (v - meanValue) / stdValue;\n}\nfunction normalizeByMinMax(values: number[]) {\n const meanValue = mean(values);\n const [min, max] = extent(values);\n if (meanValue === undefined || min === undefined || max === undefined || max === min) {\n return (v: number) => v;\n }\n return (v: number) => (v - meanValue) / (max - min);\n}\n\nfunction getNormalizationFn(method: NormalizationMethod, values: number[]) {\n if (method === 'standardScaling') {\n return normalizeByStd(values);\n }\n if (method === 'meanNormalization') {\n return normalizeByMinMax(values);\n }\n return (v: number) => v;\n}\n\nfunction aggregateNumeric(method: AggregationMethod, values: number[]) {\n switch (method) {\n case 'max': {\n let res = values[0];\n for (const v of values) {\n res = Math.max(res, v);\n }\n return res;\n }\n case 'min': {\n let res = values[0];\n for (const v of values) {\n res = Math.min(res, v);\n }\n return res;\n }\n case 'median': {\n const valuesSorted = values.sort((a, b) => a - b);\n return quantileSorted(valuesSorted, 0.5) as number;\n }\n case 'mean': {\n return mean(values) ?? values[0];\n }\n case 'sum': {\n return sum(values) as number;\n }\n default: exhaustive(method, `Unknown aggregation function ${method}`);\n }\n}\nfunction aggregateString(values: string[]) {\n const list = [...new Set(values)].sort();\n if (list.length > 3) {\n return [...list.slice(0, 3), '...'].join(', ');\n }\n return list.join(', ');\n}\n\n// all combinations with 1 key from each list\nfunction getKeysCombinations(keysLists: string[][]) {\n if (!keysLists.length) {\n return [];\n }\n let result: string[][] = [[]];\n for (const keys of keysLists) {\n const nextResult: string[][] = [];\n for (const key of keys) {\n nextResult.push(...result.map(resultItem => [...resultItem, key]));\n }\n result = nextResult;\n }\n return result;\n}\nconst sortByLabels = (arr: string[], direction: 'asc' | 'desc', labels: Record<string, string> = {}) => {\n const sign = direction === 'asc' ? 1 : -1;\n return arr.sort((a, b) => sign * (labels[a] ?? a).localeCompare((labels[b] ?? b), 'en', { numeric: true }));\n};\n\nfunction isMissing(v: DataValue | undefined): boolean {\n if (v === null || v === undefined) return true;\n if (typeof v === 'number' && Number.isNaN(v)) return true;\n return false;\n}\n\nfunction compareValues(a: DataValue | undefined, b: DataValue | undefined, direction: 'asc' | 'desc'): number {\n const aMissing = isMissing(a);\n const bMissing = isMissing(b);\n if (aMissing && bMissing) return 0;\n if (aMissing) return 1; // NA pushed to end regardless of direction\n if (bMissing) return -1;\n const sign = direction === 'asc' ? 1 : -1;\n if (typeof a === 'number' && typeof b === 'number') {\n return sign * (a < b ? -1 : a > b ? 1 : 0);\n }\n return sign * String(a).localeCompare(String(b), 'en', { numeric: true });\n}\n\nexport const sortByColumns = (\n arr: string[],\n direction: 'asc' | 'desc',\n sortColumns: ColumnName[],\n dataByKeys: Record<string, Record<string, DataValue>>\n) => {\n return arr.sort((a, b) => {\n for (const col of sortColumns) {\n const cmp = compareValues(dataByKeys[col.value]?.[a], dataByKeys[col.value]?.[b], direction);\n if (cmp !== 0) return cmp;\n }\n return 0;\n });\n};\nfunction applyAggregation<T extends string>(\n result: GroupedCellsData<T>,\n aggregation: HeatmapSettingsImpl['aggregation'],\n additionalDataColumnsX: string[],\n additionalDataColumnsY: string[],\n annotations: HeatmapSettingsImpl['annotations']\n) {\n if (aggregation.x || aggregation.y) {\n const valueExtent: GroupedCellsData<T>['meta']['valueExtent'] = result.meta.valueSources.reduce((r, key) => {\n r[key] = [Infinity, -Infinity] as [number, number];\n return r;\n }, {} as GroupedCellsData<T>['meta']['valueExtent']);\n for (const facetKey of result.meta.facetKeys) {\n const { xKeys, yKeys, cells, xKeysByGroups, yKeysByGroups } = result.facets[facetKey];\n const xGroups = aggregation.x ? xKeysByGroups : xKeys.reduce((res, xKey) => { res[xKey] = [xKey]; return res; }, {} as Record<string, string[]>);\n const yGroups = aggregation.y ? yKeysByGroups : yKeys.reduce((res, yKey) => { res[yKey] = [yKey]; return res; }, {} as Record<string, string[]>);\n const xNewKeys = Object.keys(xGroups);\n const yNewKeys = Object.keys(yGroups);\n\n for (const xGroupKey of xNewKeys) {\n for (const yGroupKey of yNewKeys) {\n // collect values for aggregation to arrays\n const valuesBySources: Record<T, number[]> = result.meta.valueSources.reduce((r, v) => {\n r[v] = [];\n return r;\n }, {} as Record<T, number[]>);\n for (const xKey of xGroups[xGroupKey]) {\n for (const yKey of yGroups[yGroupKey]) {\n for (const valueSource of result.meta.valueSources) {\n const cellValue = cells[xKey]?.[yKey]?.value?.[valueSource];\n if (cellValue !== undefined) {\n valuesBySources[valueSource].push(cellValue as number);\n }\n }\n delete cells[xKey]?.[yKey];\n }\n }\n // create new cells with aggregated values\n for (const valueSource of result.meta.valueSources) {\n const values = valuesBySources[valueSource];\n if (values.length > 0) {\n const value = aggregateNumeric(aggregation.method, values);\n if (!result.facets[facetKey].cells[xGroupKey]) {\n result.facets[facetKey].cells[xGroupKey] = {};\n }\n if (!result.facets[facetKey].cells[xGroupKey][yGroupKey]) {\n result.facets[facetKey].cells[xGroupKey][yGroupKey] = {\n isCell: true,\n idx: 0,\n id: `${xGroupKey}_${yGroupKey}`,\n x: xGroupKey,\n y: yGroupKey,\n value: result.meta.valueSources.reduce((r, v) => { r[v] = null; return r; }, {} as Record<T, DataValue>),\n normalizedValue: result.meta.valueSources.reduce((r, v) => { r[v] = null; return r; }, {} as Record<T, DataValue>),\n };\n }\n const cell = result.facets[facetKey].cells[xGroupKey][yGroupKey];\n cell.value[valueSource] = value;\n cell.normalizedValue[valueSource] = value;\n\n valueExtent[valueSource][0] = Math.min(cell.normalizedValue?.[valueSource], valueExtent[valueSource][0]);\n valueExtent[valueSource][1] = Math.max(cell.normalizedValue?.[valueSource], valueExtent[valueSource][1]);\n }\n }\n }\n }\n // add aggregated values for X annotations\n if (aggregation.x) {\n for (const xGroupKey of xNewKeys) {\n for (const columnKey of additionalDataColumnsX) {\n const annotation = annotations.find((v) => v.valueColumn.value === columnKey || v.valueColumn.valueLabels === columnKey);\n if (!annotation) {\n continue;\n }\n const values: DataValue[] = [];\n for (const xKey of xGroups[xGroupKey]) {\n values.push(result.meta.xDataByKeys[columnKey][xKey]);\n delete result.meta.xDataByKeys[columnKey][xKey];\n }\n const value = annotation.type === 'continuous' ? aggregateNumeric(aggregation.method, values as number[]) : aggregateString(values as string[]);\n result.meta.xDataByKeys[columnKey][xGroupKey] = value;\n }\n }\n }\n // add aggregated values for Y annotations\n if (aggregation.y) {\n for (const columnKey of additionalDataColumnsY) {\n result.meta.yDataByKeys[columnKey] = {};\n }\n for (const yGroupKey of yNewKeys) {\n for (const columnKey of additionalDataColumnsY) {\n const annotation = annotations.find((v) => v.valueColumn.value === columnKey || v.valueColumn.valueLabels === columnKey);\n if (!annotation) {\n continue;\n }\n const values: DataValue[] = [];\n for (const yKey of yGroups[yGroupKey]) {\n values.push(result.meta.yDataByKeys[columnKey][yKey]);\n delete result.meta.yDataByKeys[columnKey][yKey];\n }\n const value = annotation.type === 'continuous' ? aggregateNumeric(aggregation.method, values as number[]) : aggregateString(values as string[]);\n result.meta.yDataByKeys[columnKey][yGroupKey] = value;\n }\n }\n }\n // erase grouping - we aggregated by them and now there is no grouping in the chart;\n // replace axis keys with group keys - now group keys are new axis keys\n if (aggregation.x) {\n result.facets[facetKey].xKeys = Object.keys(xKeysByGroups);\n result.facets[facetKey].xKeysByGroups = { 'null': result.facets[facetKey].xKeys };\n result.meta.xLabels = result.meta.xGroupLabels;\n result.meta.xGroupKeys = ['null'];\n result.meta.xGroupKeyValues = { null: ['null'] };\n }\n if (aggregation.y) {\n result.facets[facetKey].yKeys = Object.keys(yKeysByGroups);\n result.facets[facetKey].yKeysByGroups = { 'null': result.facets[facetKey].yKeys };\n result.meta.yLabels = result.meta.yGroupLabels;\n result.meta.yGroupKeys = ['null'];\n result.meta.yGroupKeyValues = { null: ['null'] };\n }\n }\n result.meta.valueExtent = valueExtent;\n }\n}\n\nfunction updateValueExtent<T extends string>(result: GroupedCellsData<T>, cell: Cell<T>) {\n for (const valueSource of result.meta.valueSources) {\n result.meta.valueExtent[valueSource][0] = Math.min(cell.normalizedValue?.[valueSource] as number, result.meta.valueExtent[valueSource][0]);\n result.meta.valueExtent[valueSource][1] = Math.max(cell.normalizedValue?.[valueSource] as number, result.meta.valueExtent[valueSource][1]);\n }\n\n}\nfunction applyNormalization<T extends string>(\n result: GroupedCellsData<T>,\n normalizationBySources: Record<T, HeatmapSettingsImpl['normalization']>,\n) {\n if (Object.values(normalizationBySources).length) {\n const valueExtent: GroupedCellsData<T>['meta']['valueExtent'] = result.meta.valueSources.reduce((r, key) => {\n if (normalizationBySources[key]) {\n r[key] = [Infinity, -Infinity] as [number, number];\n }\n return r;\n }, {} as GroupedCellsData<T>['meta']['valueExtent']);\n for (const facetKey of result.meta.facetKeys) {\n const { xKeys, yKeys, cells } = result.facets[facetKey];\n\n for (const valueSource of result.meta.valueSources) {\n const normalization = normalizationBySources[valueSource];\n if (!normalization) {\n continue;\n }\n const cellKeys = normalization.direction === 'row' ? xKeys : yKeys;\n const groupKeys = normalization.direction === 'row' ? yKeys : xKeys;\n const cellGetter = normalization.direction === 'row'\n ? (cellKey: string, groupKey: string) => cells[cellKey]?.[groupKey]\n : (cellKey: string, groupKey: string) => cells[groupKey]?.[cellKey];\n for (const groupKey of groupKeys) {\n const values: number[] = [];\n for (const cellKey of cellKeys) {\n const v = cellGetter(cellKey, groupKey)?.value?.[valueSource];\n if (v !== undefined) {\n values.push(v as number);\n }\n }\n const normalize = getNormalizationFn(normalization.method, values);\n for (const cellKey of cellKeys) {\n const cell = cellGetter(cellKey, groupKey);\n if (cell !== undefined) {\n cell.normalizedValue[valueSource] = normalize(cell.value?.[valueSource] as number);\n valueExtent[valueSource][0] = Math.min(cell.normalizedValue?.[valueSource], valueExtent[valueSource][0]);\n valueExtent[valueSource][1] = Math.max(cell.normalizedValue?.[valueSource], valueExtent[valueSource][1]);\n }\n }\n }\n }\n\n }\n result.meta.valueExtent = {...result.meta.valueExtent, valueExtent};\n }\n}\n\nexport function fillCellsData<T extends string>(\n result: GroupedCellsData<T>,\n {\n data,\n x,\n y,\n valueColumns,\n facetBy,\n xGroupBy,\n yGroupBy,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalizationBySource, // separated for color and size for example\n NAValueAs,\n transformBySource, // same per-source pattern as normalization\n keysOrder,\n xAxis,\n yAxis,\n xSortBy,\n ySortBy,\n aggregation,\n showEmptyRows = false,\n showEmptyColumns = false,\n }: {\n data: DataFrame;\n x: ColumnName[];\n y: ColumnName[];\n valueColumns: Record<string, ColumnName>;\n facetBy: ColumnName[];\n xGroupBy: ColumnName[];\n yGroupBy: ColumnName[];\n facetSettings: HeatmapSettingsImpl['facetSettings'];\n annotations: HeatmapSettingsImpl['annotations'];\n dendrogramX: HeatmapSettingsImpl['dendrogramX'];\n dendrogramY: HeatmapSettingsImpl['dendrogramY'];\n normalizationBySource: Record<T, HeatmapSettingsImpl['normalization']>;\n NAValueAs: HeatmapSettingsImpl['NAValueAs'];\n transformBySource?: Record<T, HeatmapSettingsImpl['transform']>;\n keysOrder: HeatmapSettingsImpl['keysOrder'];\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'] | BubbleSettingsImpl['chartSettings']['xAxis'];\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'] | BubbleSettingsImpl['chartSettings']['yAxis'];\n xSortBy?: HeatmapSettingsImpl['xSortBy'];\n ySortBy?: HeatmapSettingsImpl['ySortBy'];\n aggregation: HeatmapSettingsImpl['aggregation'];\n showEmptyRows?: boolean;\n showEmptyColumns?: boolean;\n }\n) {\n // Resolved, visible-only label-part ids come pre-computed from graph-maker;\n // map them back to the full x / y parts here. Cell identity below still uses\n // the full x / y (labelParts must not merge cells) — this only drives the\n // rendered *label* text. undefined ids → use all parts.\n const xLabelParts = resolveLabelParts(x, 'labelParts' in xAxis ? xAxis.labelParts : null);\n const yLabelParts = resolveLabelParts(y, 'labelParts' in yAxis ? yAxis.labelParts : null);\n const facetKeysLists = facetBy.length\n ? facetBy.map(column => keysOrder[column.value] ?? data.getColumnCategories(column.value))\n : [['null']];\n\n const xGroupKeysLists = xGroupBy.length\n ? xGroupBy.map(column => keysOrder[column.value] ?? data.getColumnCategories(column.value))\n : [['null']];\n const yGroupKeysLists = yGroupBy.length\n ? yGroupBy.map(column => keysOrder[column.value] ?? data.getColumnCategories(column.value))\n : [['null']];\n let facetKeysCombinations = getKeysCombinations(facetKeysLists);\n const xGroupKeysCombinations = getKeysCombinations(xGroupKeysLists);\n const yGroupKeysCombinations = getKeysCombinations(yGroupKeysLists);\n\n if (facetSettings?.order?.length) {\n facetKeysCombinations = facetKeysCombinations.filter(keys => facetSettings.order?.includes(getFacetStringKey(keys)));\n }\n const facetKeys = facetKeysCombinations.map(getFacetOrGroupKey);\n const facetKeysSet = new Set(facetKeys);\n const xGroupKeys = xGroupKeysCombinations.map(getFacetOrGroupKey);\n const yGroupKeys = yGroupKeysCombinations.map(getFacetOrGroupKey);\n\n result.meta.facetKeys = facetKeys;\n result.meta.xGroupKeys = xGroupKeys;\n result.meta.yGroupKeys = yGroupKeys;\n\n const facetLabels = getFacetLabels(data, facetBy, facetKeys, facetKeysCombinations);\n result.meta.facetKeyValues = facetKeys.reduce((res: Record<string, string[]>, key) => {\n res[key] = facetLabels[key];\n return res;\n }, {});\n\n result.meta.xGroupKeyValues = xGroupKeys.reduce((res: Record<string, string[]>, key, index) => {\n res[key] = xGroupKeysCombinations[index];\n return res;\n }, {});\n result.meta.yGroupKeyValues = yGroupKeys.reduce((res: Record<string, string[]>, key, index) => {\n res[key] = yGroupKeysCombinations[index];\n return res;\n }, {});\n\n const annotationColumnsX = annotations.filter(item => item.axis === 'x').map(item => item.valueColumn.valueLabels ?? item.valueColumn.value);\n const annotationColumnsY = annotations.filter(item => item.axis === 'y').map(item => item.valueColumn.valueLabels ?? item.valueColumn.value);\n const dendrogramXColumns = Object.values(dendrogramX ?? {}).map(column => column.value);\n const dendrogramYColumns = Object.values(dendrogramY ?? {}).map(column => column.value);\n const xSortByColumns = (xSortBy ?? []).map(c => c.value);\n const ySortByColumns = (ySortBy ?? []).map(c => c.value);\n const additionalDataColumnsX = [...new Set([...annotationColumnsX, ...dendrogramXColumns, ...xSortByColumns])];\n const additionalDataColumnsY = [...new Set([...annotationColumnsY, ...dendrogramYColumns, ...ySortByColumns])];\n\n for (let i = 0; i < data.rowsCount; i++) {\n const facetKey = getFacetOrGroupKey(facetBy.map(column => data.getColumnValue(column.value, i)));\n if (!facetKeysSet.has(facetKey)) {\n continue;\n }\n const xGroupKey = getFacetOrGroupKey(xGroupBy.map(column => data.getColumnValue(column.value, i)));\n const yGroupKey = getFacetOrGroupKey(yGroupBy.map(column => data.getColumnValue(column.value, i)));\n const xGroupLabel = joinLabel(xGroupBy, data, i);\n const yGroupLabel = joinLabel(yGroupBy, data, i);\n result.meta.xGroupLabels[xGroupKey] = xGroupLabel;\n result.meta.yGroupLabels[yGroupKey] = yGroupLabel;\n // Cell identity uses all x/y parts plus their group parts so cells stay\n // unique within groups. labelParts (the visible-id subset) does NOT\n // affect identity.\n const xKey = getFacetOrGroupKey([\n ...x.map(c => data.getColumnValue(c.value, i)),\n ...xGroupBy.map(c => data.getColumnValue(c.value, i)),\n ]);\n const yKey = getFacetOrGroupKey([\n ...y.map(c => data.getColumnValue(c.value, i)),\n ...yGroupBy.map(c => data.getColumnValue(c.value, i)),\n ]);\n const xLabel = joinLabel(xLabelParts, data, i);\n const yLabel = joinLabel(yLabelParts, data, i);\n\n const values = result.meta.valueSources.reduce((r, key) => {\n let v = (data.getColumnValue(valueColumns[key].value, i) ?? NAValueAs) as number | null;\n if (transformBySource?.[key] === 'log' && typeof v === 'number') {\n const transformed = Math.log10(v);\n v = Number.isFinite(transformed) ? transformed : null;\n }\n r[key] = v;\n return r;\n }, {} as Record<string, DataValue>);\n\n if (xKey === 'null' || yKey === 'null') {\n continue;\n }\n\n const allValuesNull = Object.values(values).every(v => v === null);\n\n if (allValuesNull && !showEmptyRows && !showEmptyColumns) {\n continue;\n }\n\n if (!result.facets[facetKey]) {\n result.facets[facetKey] = {\n xKeys: [],\n yKeys: [],\n xKeysByGroups: {},\n yKeysByGroups: {},\n cells: {},\n };\n }\n if (!result.facets[facetKey].xKeysByGroups[xGroupKey]) {\n result.facets[facetKey].xKeysByGroups[xGroupKey] = [];\n }\n if (!result.facets[facetKey].yKeysByGroups[yGroupKey]) {\n result.facets[facetKey].yKeysByGroups[yGroupKey] = [];\n }\n\n if (!allValuesNull || showEmptyColumns) {\n result.facets[facetKey].xKeys.push(xKey);\n result.facets[facetKey].xKeysByGroups[xGroupKey].push(xKey);\n if (result.meta.xLabels[xKey] && xLabel !== result.meta.xLabels[xKey]) {\n throw Error(`More than 1 x-label value for x=${xKey}`);\n }\n result.meta.xLabels[xKey] = xLabel;\n for (const columnKey of additionalDataColumnsX) {\n const isAddedColumn = typeof result.meta.xDataByKeys[columnKey] !== 'undefined';\n const isAddedValue = isAddedColumn && typeof result.meta.xDataByKeys[columnKey][xKey] !== 'undefined';\n if (!isAddedColumn) {\n result.meta.xDataByKeys[columnKey] = {};\n }\n if (isAddedValue && result.meta.xDataByKeys[columnKey][xKey] !== data.getColumnValue(columnKey, i)) {\n throw Error(`More than 1 value for x = ${xKey} and column = ${columnKey}`);\n }\n if (!isAddedValue) {\n result.meta.xDataByKeys[columnKey][xKey] = data.getColumnValue(columnKey, i);\n }\n }\n }\n\n if (!allValuesNull || showEmptyRows) {\n result.facets[facetKey].yKeys.push(yKey);\n result.facets[facetKey].yKeysByGroups[yGroupKey].push(yKey);\n if (result.meta.yLabels[yKey] && yLabel !== result.meta.yLabels[yKey]) {\n throw Error(`More than 1 y-label value for y=${yKey}`);\n }\n result.meta.yLabels[yKey] = yLabel;\n for (const columnKey of additionalDataColumnsY) {\n const isAddedColumn = typeof result.meta.yDataByKeys[columnKey] !== 'undefined';\n const isAddedValue = isAddedColumn && typeof result.meta.yDataByKeys[columnKey][yKey] !== 'undefined';\n if (!isAddedColumn) {\n result.meta.yDataByKeys[columnKey] = {};\n }\n if (isAddedValue && result.meta.yDataByKeys[columnKey][yKey] !== data.getColumnValue(columnKey, i)) {\n throw Error(`More than 1 value for y = ${yKey} and column = ${columnKey}`);\n }\n if (!isAddedValue) {\n result.meta.yDataByKeys[columnKey][yKey] = data.getColumnValue(columnKey, i);\n }\n }\n }\n\n if (allValuesNull) {\n continue;\n }\n\n if (!result.facets[facetKey].cells[xKey]) {\n result.facets[facetKey].cells[xKey] = {};\n }\n\n for (const valueSource of result.meta.valueSources) {\n if (result.facets[facetKey].cells[xKey][yKey] && result.facets[facetKey].cells[xKey][yKey].value[valueSource] !== values[valueSource]) {\n throw Error(`More than 1 value for x=${xKey}, y=${yKey}`);\n }\n }\n\n result.facets[facetKey].cells[xKey][yKey] = {\n isCell: true,\n idx: i,\n id: `${xKey}_${yKey}`,\n x: xKey,\n y: yKey,\n value: values,\n normalizedValue: values,\n };\n\n updateValueExtent(result, result.facets[facetKey].cells[xKey][yKey]);\n }\n\n result.meta.facetKeys = result.meta.facetKeys.filter((key) => result.facets[key]); // filter only used;\n\n // make uniq x, y, x-group and y-group keys\n for (const facetKey of result.meta.facetKeys) {\n const facet = result.facets[facetKey];\n const uniqueXKeys = [...new Set(facet.xKeys)];\n const uniqueYKeys = [...new Set(facet.yKeys)];\n facet.xKeys = keysOrder['x'] ? intersect(keysOrder['x'], uniqueXKeys) : uniqueXKeys;\n facet.yKeys = keysOrder['y'] ? intersect(keysOrder['y'], uniqueYKeys) : uniqueYKeys;\n for (const xGroupKey of xGroupKeys) {\n result.facets[facetKey].xKeysByGroups[xGroupKey] = intersect(\n facet.xKeys,\n result.facets[facetKey].xKeysByGroups[xGroupKey]\n );\n }\n for (const yGroupKey of yGroupKeys) {\n result.facets[facetKey].yKeysByGroups[yGroupKey] = intersect(\n facet.yKeys,\n result.facets[facetKey].yKeysByGroups[yGroupKey]\n );\n }\n }\n\n applyAggregation(result, aggregation, additionalDataColumnsX, additionalDataColumnsY, annotations);\n applyNormalization(result, normalizationBySource);\n\n // All sorting is consolidated here. Dendrograms run later in getDendrograms and reorder\n // per-facet keys for axes where clustering is on — that's the only post-fillCellsData sort.\n\n // Sort group keys (by group labels). Skip when user supplied custom order via keysOrder.\n const xGroupCustomOrder = xGroupBy.some(c => keysOrder[c.value]?.length > 0);\n const yGroupCustomOrder = yGroupBy.some(c => keysOrder[c.value]?.length > 0);\n if (!xGroupCustomOrder) {\n result.meta.xGroupKeys = sortByLabels([...result.meta.xGroupKeys], xAxis.sorting, result.meta.xGroupLabels);\n }\n if (!yGroupCustomOrder) {\n result.meta.yGroupKeys = sortByLabels([...result.meta.yGroupKeys], yAxis.sorting, result.meta.yGroupLabels);\n }\n\n // every facet may contain not all of available keys, but for shared axes it is necessary to have all of them\n const effectiveXSortBy = (!dendrogramX && !aggregation.x && xSortBy?.length) ? xSortBy : null;\n result.meta.xKeysByGroups = result.meta.xGroupKeys.reduce((res: Record<string, string[]>, xGroupKey) => {\n const uniqueXKeys = [...new Set(\n result.meta.facetKeys.flatMap(facetKey => result.facets[facetKey].xKeysByGroups[xGroupKey])\n )];\n const existingXKeys = effectiveXSortBy\n ? sortByColumns(uniqueXKeys, xAxis.sorting, effectiveXSortBy, result.meta.xDataByKeys)\n : sortByLabels(uniqueXKeys, xAxis.sorting, result.meta.xLabels);\n res[xGroupKey] = keysOrder['x'] ? intersect(keysOrder['x'], existingXKeys) : existingXKeys;\n return res;\n }, {});\n result.meta.xKeys = result.meta.xGroupKeys.reduce((res: string[], xGroupKey: string) => {\n res = res.concat(result.meta.xKeysByGroups[xGroupKey]);\n return res;\n }, []);\n\n const effectiveYSortBy = (!dendrogramY && !aggregation.y && ySortBy?.length) ? ySortBy : null;\n result.meta.yKeysByGroups = result.meta.yGroupKeys.reduce((res: Record<string, string[]>, yGroupKey) => {\n const uniqueYKeys = [...new Set(\n result.meta.facetKeys.flatMap(facetKey => result.facets[facetKey].yKeysByGroups[yGroupKey])\n )];\n const existingYKeys = effectiveYSortBy\n ? sortByColumns(uniqueYKeys, yAxis.sorting, effectiveYSortBy, result.meta.yDataByKeys)\n : sortByLabels(uniqueYKeys, yAxis.sorting, result.meta.yLabels);\n res[yGroupKey] = keysOrder['y'] ? intersect(keysOrder['y'], existingYKeys) : existingYKeys;\n return res;\n }, {});\n result.meta.yKeys = result.meta.yGroupKeys.reduce((res: string[], yGroupKey: string) => {\n res = res.concat(result.meta.yKeysByGroups[yGroupKey]);\n return res;\n }, []);\n\n // Propagate the sorted meta order to per-facet keys. Used by the renderer when sharedX/Y is\n // false. Intersection preserves meta order while filtering down to keys present in each facet.\n // getDendrograms may re-order facet keys later for axes with clustering on.\n for (const facetKey of result.meta.facetKeys) {\n for (const xGroupKey of result.meta.xGroupKeys) {\n result.facets[facetKey].xKeysByGroups[xGroupKey] = intersect(\n result.meta.xKeysByGroups[xGroupKey],\n result.facets[facetKey].xKeysByGroups[xGroupKey] ?? []\n );\n }\n result.facets[facetKey].xKeys = result.meta.xGroupKeys.flatMap(\n g => result.facets[facetKey].xKeysByGroups[g] ?? []\n );\n for (const yGroupKey of result.meta.yGroupKeys) {\n result.facets[facetKey].yKeysByGroups[yGroupKey] = intersect(\n result.meta.yKeysByGroups[yGroupKey],\n result.facets[facetKey].yKeysByGroups[yGroupKey] ?? []\n );\n }\n result.facets[facetKey].yKeys = result.meta.yGroupKeys.flatMap(\n g => result.facets[facetKey].yKeysByGroups[g] ?? []\n );\n }\n\n for (const valueSource of result.meta.valueSources) {\n // avoid render errors on empty data\n if (result.meta.valueExtent[valueSource][0] === Infinity) {\n result.meta.valueExtent[valueSource][0] = 0;\n }\n if (result.meta.valueExtent[valueSource][1] === -Infinity) {\n result.meta.valueExtent[valueSource][1] = 0;\n }\n }\n\n result.meta.xLabels['null'] = xLabelParts.map(c => c.nullValueLabel ?? 'NA').join(', ');\n result.meta.yLabels['null'] = yLabelParts.map(c => c.nullValueLabel ?? 'NA').join(', ');\n result.meta.xGroupLabels['null'] = xGroupBy.map(c => c.nullValueLabel ?? 'NA').join(', ');\n result.meta.yGroupLabels['null'] = yGroupBy.map(c => c.nullValueLabel ?? 'NA').join(', ');\n return result;\n}"],"mappings":"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"}
@@ -5,10 +5,10 @@ import { Cell, GroupedCellsData } from './fillCellsData';
5
5
  export type CellHeatmap = Cell<'dataSource'>;
6
6
  export type GroupedCellsHeatmap = GroupedCellsData<'dataSource'>;
7
7
  export declare function createEmptyGroupedCells(): GroupedCellsHeatmap;
8
- export declare function getCells({ data, xColumn, yColumn, valueColumns, facetBy, xGroupBy, yGroupBy, xSortBy, ySortBy, facetSettings, annotations, dendrogramX, dendrogramY, normalization, NAValueAs, transform, keysOrder, xAxis, yAxis, aggregation, showEmptyRows, showEmptyColumns, }: {
8
+ export declare function getCells({ data, x, y, valueColumns, facetBy, xGroupBy, yGroupBy, xSortBy, ySortBy, facetSettings, annotations, dendrogramX, dendrogramY, normalization, NAValueAs, transform, keysOrder, xAxis, yAxis, aggregation, showEmptyRows, showEmptyColumns, }: {
9
9
  data: DataFrame;
10
- xColumn: ColumnName;
11
- yColumn: ColumnName;
10
+ x: ColumnName[];
11
+ y: ColumnName[];
12
12
  valueColumns: Record<string, ColumnName>;
13
13
  facetBy: ColumnName[];
14
14
  xGroupBy: ColumnName[];
@@ -1 +1 @@
1
- {"version":3,"file":"getCells.d.ts","sourceRoot":"","sources":["../../src/heatmap/getCells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG9D,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,CAAA;AAC5C,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAEjE,wBAAgB,uBAAuB,IAAI,mBAAmB,CAwB7D;AAED,wBAAgB,QAAQ,CAAC,EACrB,IAAI,EACJ,OAAO,EACP,OAAO,EACP,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,EACP,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,SAAS,EACT,SAAS,EACT,SAAS,EACT,KAAK,EACL,KAAK,EACL,WAAW,EACX,aAAqB,EACrB,gBAAwB,GAC3B,EAAE;IACC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACpD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACpD,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,KAAK,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC;IACrD,KAAK,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC;IACrD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG,mBAAmB,CAqBtB"}
1
+ {"version":3,"file":"getCells.d.ts","sourceRoot":"","sources":["../../src/heatmap/getCells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG9D,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,CAAA;AAC5C,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;AAEjE,wBAAgB,uBAAuB,IAAI,mBAAmB,CAwB7D;AAED,wBAAgB,QAAQ,CAAC,EACrB,IAAI,EACJ,CAAC,EACD,CAAC,EACD,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,EACP,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,SAAS,EACT,SAAS,EACT,SAAS,EACT,KAAK,EACL,KAAK,EACL,WAAW,EACX,aAAqB,EACrB,gBAAwB,GAC3B,EAAE;IACC,IAAI,EAAE,SAAS,CAAC;IAChB,CAAC,EAAE,UAAU,EAAE,CAAC;IAChB,CAAC,EAAE,UAAU,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACpD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACpD,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC5C,KAAK,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC;IACrD,KAAK,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC;IACrD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,GAAG,mBAAmB,CAqBtB"}
@@ -24,12 +24,12 @@ function t() {
24
24
  facets: {}
25
25
  };
26
26
  }
27
- function n({ data: n, xColumn: r, yColumn: i, valueColumns: a, facetBy: o, xGroupBy: s, yGroupBy: c, xSortBy: l, ySortBy: u, facetSettings: d, annotations: f, dendrogramX: p, dendrogramY: m, normalization: h, NAValueAs: g, transform: _, keysOrder: v, xAxis: y, yAxis: b, aggregation: x, showEmptyRows: S = !1, showEmptyColumns: C = !1 }) {
27
+ function n({ data: n, x: r, y: i, valueColumns: a, facetBy: o, xGroupBy: s, yGroupBy: c, xSortBy: l, ySortBy: u, facetSettings: d, annotations: f, dendrogramX: p, dendrogramY: m, normalization: h, NAValueAs: g, transform: _, keysOrder: v, xAxis: y, yAxis: b, aggregation: x, showEmptyRows: S = !1, showEmptyColumns: C = !1 }) {
28
28
  let w = t();
29
29
  return e(w, {
30
30
  data: n,
31
- xColumn: r,
32
- yColumn: i,
31
+ x: r,
32
+ y: i,
33
33
  valueColumns: a,
34
34
  facetBy: o,
35
35
  xGroupBy: s,
@@ -1 +1 @@
1
- {"version":3,"file":"getCells.js","names":[],"sources":["../../src/heatmap/getCells.ts"],"sourcesContent":["import type { DataFrame } from '../DataFrame';\nimport type { ColumnName } from '../types';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport type { Cell, GroupedCellsData } from './fillCellsData';\nimport { fillCellsData } from './fillCellsData';\n\nexport type CellHeatmap = Cell<'dataSource'>\nexport type GroupedCellsHeatmap = GroupedCellsData<'dataSource'>;\n\nexport function createEmptyGroupedCells(): GroupedCellsHeatmap {\n return {\n meta: {\n valueSources: ['dataSource'],\n facetKeys: [],\n xKeys: [],\n yKeys: [],\n xGroupKeys: [],\n yGroupKeys: [],\n xKeysByGroups: {},\n yKeysByGroups: {},\n xLabels: {},\n yLabels: {},\n xGroupLabels: {},\n yGroupLabels: {},\n xDataByKeys: {},\n yDataByKeys: {},\n facetKeyValues: {},\n xGroupKeyValues: {},\n yGroupKeyValues: {},\n valueExtent: { dataSource: [Infinity, -Infinity] },\n },\n facets: {},\n };\n}\n\nexport function getCells({\n data,\n xColumn,\n yColumn,\n valueColumns,\n facetBy,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalization,\n NAValueAs,\n transform,\n keysOrder,\n xAxis,\n yAxis,\n aggregation,\n showEmptyRows = false,\n showEmptyColumns = false,\n}: {\n data: DataFrame;\n xColumn: ColumnName;\n yColumn: ColumnName;\n valueColumns: Record<string, ColumnName>;\n facetBy: ColumnName[];\n xGroupBy: ColumnName[];\n yGroupBy: ColumnName[];\n xSortBy: ColumnName[];\n ySortBy: ColumnName[];\n facetSettings: HeatmapSettingsImpl['facetSettings'];\n annotations: HeatmapSettingsImpl['annotations'];\n dendrogramX: HeatmapSettingsImpl['dendrogramX'];\n dendrogramY: HeatmapSettingsImpl['dendrogramY'];\n normalization: HeatmapSettingsImpl['normalization'];\n NAValueAs: HeatmapSettingsImpl['NAValueAs'];\n transform: HeatmapSettingsImpl['transform'];\n keysOrder: HeatmapSettingsImpl['keysOrder'];\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'];\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'];\n aggregation: HeatmapSettingsImpl['aggregation'];\n showEmptyRows?: boolean;\n showEmptyColumns?: boolean;\n}): GroupedCellsHeatmap {\n const result: GroupedCellsHeatmap = createEmptyGroupedCells();\n fillCellsData(result, {\n data,\n xColumn, yColumn, valueColumns,\n facetBy, xGroupBy, yGroupBy,\n xSortBy, ySortBy,\n facetSettings,\n annotations,\n dendrogramX, dendrogramY,\n normalizationBySource: { dataSource: normalization },\n NAValueAs,\n transformBySource: { dataSource: transform },\n keysOrder,\n xAxis,\n yAxis,\n aggregation,\n showEmptyRows,\n showEmptyColumns,\n });\n return result;\n}\n"],"mappings":";AASA,SAAgB,IAA+C;AAC3D,QAAO;EACH,MAAM;GACF,cAAc,CAAC,aAAa;GAC5B,WAAW,EAAE;GACb,OAAO,EAAE;GACT,OAAO,EAAE;GACT,YAAY,EAAE;GACd,YAAY,EAAE;GACd,eAAe,EAAE;GACjB,eAAe,EAAE;GACjB,SAAS,EAAE;GACX,SAAS,EAAE;GACX,cAAc,EAAE;GAChB,cAAc,EAAE;GAChB,aAAa,EAAE;GACf,aAAa,EAAE;GACf,gBAAgB,EAAE;GAClB,iBAAiB,EAAE;GACnB,iBAAiB,EAAE;GACnB,aAAa,EAAE,YAAY,CAAC,UAAU,UAAU,EAAE;GACrD;EACD,QAAQ,EAAE;EACb;;AAGL,SAAgB,EAAS,EACrB,SACA,YACA,YACA,iBACA,YACA,aACA,aACA,YACA,YACA,kBACA,gBACA,gBACA,gBACA,kBACA,cACA,cACA,cACA,UACA,UACA,gBACA,mBAAgB,IAChB,sBAAmB,MAwBC;CACpB,IAAM,IAA8B,GAAyB;AAmB7D,QAlBA,EAAc,GAAQ;EAClB;EACA;EAAS;EAAS;EAClB;EAAS;EAAU;EACnB;EAAS;EACT;EACA;EACA;EAAa;EACb,uBAAuB,EAAE,YAAY,GAAe;EACpD;EACA,mBAAmB,EAAE,YAAY,GAAW;EAC5C;EACA;EACA;EACA;EACA;EACA;EACH,CAAC,EACK"}
1
+ {"version":3,"file":"getCells.js","names":[],"sources":["../../src/heatmap/getCells.ts"],"sourcesContent":["import type { DataFrame } from '../DataFrame';\nimport type { ColumnName } from '../types';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport type { Cell, GroupedCellsData } from './fillCellsData';\nimport { fillCellsData } from './fillCellsData';\n\nexport type CellHeatmap = Cell<'dataSource'>\nexport type GroupedCellsHeatmap = GroupedCellsData<'dataSource'>;\n\nexport function createEmptyGroupedCells(): GroupedCellsHeatmap {\n return {\n meta: {\n valueSources: ['dataSource'],\n facetKeys: [],\n xKeys: [],\n yKeys: [],\n xGroupKeys: [],\n yGroupKeys: [],\n xKeysByGroups: {},\n yKeysByGroups: {},\n xLabels: {},\n yLabels: {},\n xGroupLabels: {},\n yGroupLabels: {},\n xDataByKeys: {},\n yDataByKeys: {},\n facetKeyValues: {},\n xGroupKeyValues: {},\n yGroupKeyValues: {},\n valueExtent: { dataSource: [Infinity, -Infinity] },\n },\n facets: {},\n };\n}\n\nexport function getCells({\n data,\n x,\n y,\n valueColumns,\n facetBy,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalization,\n NAValueAs,\n transform,\n keysOrder,\n xAxis,\n yAxis,\n aggregation,\n showEmptyRows = false,\n showEmptyColumns = false,\n}: {\n data: DataFrame;\n x: ColumnName[];\n y: ColumnName[];\n valueColumns: Record<string, ColumnName>;\n facetBy: ColumnName[];\n xGroupBy: ColumnName[];\n yGroupBy: ColumnName[];\n xSortBy: ColumnName[];\n ySortBy: ColumnName[];\n facetSettings: HeatmapSettingsImpl['facetSettings'];\n annotations: HeatmapSettingsImpl['annotations'];\n dendrogramX: HeatmapSettingsImpl['dendrogramX'];\n dendrogramY: HeatmapSettingsImpl['dendrogramY'];\n normalization: HeatmapSettingsImpl['normalization'];\n NAValueAs: HeatmapSettingsImpl['NAValueAs'];\n transform: HeatmapSettingsImpl['transform'];\n keysOrder: HeatmapSettingsImpl['keysOrder'];\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'];\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'];\n aggregation: HeatmapSettingsImpl['aggregation'];\n showEmptyRows?: boolean;\n showEmptyColumns?: boolean;\n}): GroupedCellsHeatmap {\n const result: GroupedCellsHeatmap = createEmptyGroupedCells();\n fillCellsData(result, {\n data,\n x, y, valueColumns,\n facetBy, xGroupBy, yGroupBy,\n xSortBy, ySortBy,\n facetSettings,\n annotations,\n dendrogramX, dendrogramY,\n normalizationBySource: { dataSource: normalization },\n NAValueAs,\n transformBySource: { dataSource: transform },\n keysOrder,\n xAxis,\n yAxis,\n aggregation,\n showEmptyRows,\n showEmptyColumns,\n });\n return result;\n}\n"],"mappings":";AASA,SAAgB,IAA+C;AAC3D,QAAO;EACH,MAAM;GACF,cAAc,CAAC,aAAa;GAC5B,WAAW,EAAE;GACb,OAAO,EAAE;GACT,OAAO,EAAE;GACT,YAAY,EAAE;GACd,YAAY,EAAE;GACd,eAAe,EAAE;GACjB,eAAe,EAAE;GACjB,SAAS,EAAE;GACX,SAAS,EAAE;GACX,cAAc,EAAE;GAChB,cAAc,EAAE;GAChB,aAAa,EAAE;GACf,aAAa,EAAE;GACf,gBAAgB,EAAE;GAClB,iBAAiB,EAAE;GACnB,iBAAiB,EAAE;GACnB,aAAa,EAAE,YAAY,CAAC,UAAU,UAAU,EAAE;GACrD;EACD,QAAQ,EAAE;EACb;;AAGL,SAAgB,EAAS,EACrB,SACA,MACA,MACA,iBACA,YACA,aACA,aACA,YACA,YACA,kBACA,gBACA,gBACA,gBACA,kBACA,cACA,cACA,cACA,UACA,UACA,gBACA,mBAAgB,IAChB,sBAAmB,MAwBC;CACpB,IAAM,IAA8B,GAAyB;AAmB7D,QAlBA,EAAc,GAAQ;EAClB;EACA;EAAG;EAAG;EACN;EAAS;EAAU;EACnB;EAAS;EACT;EACA;EACA;EAAa;EACb,uBAAuB,EAAE,YAAY,GAAe;EACpD;EACA,mBAAmB,EAAE,YAAY,GAAW;EAC5C;EACA;EACA;EACA;EACA;EACA;EACH,CAAC,EACK"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/heatmap/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAmB,KAAK,SAAS,EAAuB,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAe,MAAM,UAAU,CAAC;AAE9I,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAK5D,qBAAa,YAAa,SAAQ,aAAa;IAC3C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,aAAa,gBAAuB;IAEpC,mBAAmB,EAAE,CAAC,CAAC,EAAC,OAAO,KAAK,IAAI,CAAQ;IAChD,eAAe,EAAE,CAAC,CAAC,EAAC,OAAO,KAAK,IAAI,CAAQ;IAE5C,cAAc,EAAE;QACZ,gBAAgB,EAAE,mBAAmB,CAAC;QACtC,eAAe,EAAE,eAAe,CAAC;QACjC,cAAc,EAAE,SAAS,EAAE,CAAC;KAC/B,GAAG,IAAI,CAAQ;IAEhB,gCAAgC,UAAS;gBAE7B,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,aAAa,CAAC,EAAC,oBAAoB;IAU3F,KAAK,CAAC,IAAI,EAAE,WAAW;IAgBvB,OAAO;IAIP,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe;IA0BhE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAIhD,MAAM,IAAI,MAAM;IAKhB,mCAAmC,CAAC,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,mBAAmB;IA4EpG,+BAA+B,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;IAU9D,WAAW;IAwEjB,gBAAgB;IAIhB,YAAY;CAsCf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/heatmap/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAmB,KAAK,SAAS,EAAuB,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAe,MAAM,UAAU,CAAC;AAE9I,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO5D,qBAAa,YAAa,SAAQ,aAAa;IAC3C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,aAAa,gBAAuB;IAEpC,mBAAmB,EAAE,CAAC,CAAC,EAAC,OAAO,KAAK,IAAI,CAAQ;IAChD,eAAe,EAAE,CAAC,CAAC,EAAC,OAAO,KAAK,IAAI,CAAQ;IAE5C,cAAc,EAAE;QACZ,gBAAgB,EAAE,mBAAmB,CAAC;QACtC,eAAe,EAAE,eAAe,CAAC;QACjC,cAAc,EAAE,SAAS,EAAE,CAAC;KAC/B,GAAG,IAAI,CAAQ;IAEhB,gCAAgC,UAAS;gBAE7B,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,aAAa,CAAC,EAAC,oBAAoB;IAU3F,KAAK,CAAC,IAAI,EAAE,WAAW;IAgBvB,OAAO;IAIP,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe;IA0BhE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAIhD,MAAM,IAAI,MAAM;IAKhB,mCAAmC,CAAC,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,mBAAmB;IAuEpG,+BAA+B,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;IAU9D,WAAW;IAwEjB,gBAAgB;IAIhB,YAAY;CAsCf"}
@@ -5,20 +5,22 @@ import { isColumnName as r } from "../utils/index.js";
5
5
  import { arraysAreDifferent as i } from "../utils/arraysAreDifferent.js";
6
6
  import "./constants.js";
7
7
  import a from "./ChartRenderer.js";
8
- import { getCells as o } from "./getCells.js";
9
- import { getDendrograms as s } from "./getDendrograms.js";
10
- import { HeatmapSettingsImpl as c } from "./HeatmapSettingsImpl.js";
11
- import { noop as l } from "lodash";
12
- import { renderToString as u } from "react-dom/server.browser";
13
- var d = class extends e {
8
+ import { labelPartsChanged as o } from "./labelParts.js";
9
+ import { getCells as s } from "./getCells.js";
10
+ import { getDendrograms as c } from "./getDendrograms.js";
11
+ import { HeatmapSettingsImpl as l } from "./HeatmapSettingsImpl.js";
12
+ import { compareColumnGroups as u } from "../utils/compareColumnGroups.js";
13
+ import { noop as d } from "lodash";
14
+ import { renderToString as f } from "react-dom/server.browser";
15
+ var p = class extends e {
14
16
  settings;
15
17
  chartRenderer = new a();
16
- onTooltipHintSwitch = l;
17
- onLoadingChange = l;
18
+ onTooltipHintSwitch = d;
19
+ onLoadingChange = d;
18
20
  calculatedData = null;
19
21
  clusteringCalculationsInProgress = !1;
20
22
  constructor(e, t, n) {
21
- super(e, t), this.settings = new c(t), n && (this.onTooltipHintSwitch = n.onTooltipHintSwitch ?? l, this.onLoadingChange = n.onLoadingChange ?? l);
23
+ super(e, t), this.settings = new l(t), n && (this.onTooltipHintSwitch = n.onTooltipHintSwitch ?? d, this.onLoadingChange = n.onLoadingChange ?? d);
22
24
  }
23
25
  mount(e) {
24
26
  try {
@@ -33,7 +35,7 @@ var d = class extends e {
33
35
  updateSettingsAndData(e, r) {
34
36
  try {
35
37
  let t = this.settings, n = this.data;
36
- this.settings = new c(r), this.data = e, this._needUpdateCalculatedDataBySettings(t, this.settings) || this._needUpdateCalculatedDataByData(n, this.data) ? this._updateData() : this._updateAesInData(), this.hasError = !1, this.errorInfo = null;
38
+ this.settings = new l(r), this.data = e, this._needUpdateCalculatedDataBySettings(t, this.settings) || this._needUpdateCalculatedDataByData(n, this.data) ? this._updateData() : this._updateAesInData(), this.hasError = !1, this.errorInfo = null;
37
39
  } catch (e) {
38
40
  this.hasError = !0, e instanceof Error && (this.errorInfo = n(e.cause) ? e.cause : t(e), this.chartRenderer.renderError(e.message), console.error(e));
39
41
  }
@@ -42,30 +44,27 @@ var d = class extends e {
42
44
  console.warn("no chart state for heatmap");
43
45
  }
44
46
  export() {
45
- return this._updateChart(), u(this.chartRenderer.component);
47
+ return this._updateChart(), f(this.chartRenderer.component);
46
48
  }
47
49
  _needUpdateCalculatedDataBySettings(e, t) {
48
- let { xColumn: n, yColumn: a, valueColumn: o, xGroupBy: s, yGroupBy: c, xSortBy: l, ySortBy: u, facetBy: d, annotations: f, chartSettings: p, facetSettings: m, dendrogramX: h, dendrogramY: g, normalization: _, aggregation: v, NAValueAs: y, transform: b } = t, x = Object.values(e.dendrogramX?.aes || {}).filter(r), S = Object.values(h?.aes || {}).filter(r), C = Object.values(e.dendrogramY?.aes || {}).filter(r), w = Object.values(g?.aes || {}).filter(r);
49
- function T(e, t) {
50
- return e.length !== t.length || e.some((e, n) => e.value !== t[n].value);
51
- }
52
- return e.xColumn.value !== n.value || e.yColumn.value !== a.value || e.valueColumn.value !== o.value || T(e.xGroupBy, s) || T(e.yGroupBy, c) || T(e.xSortBy, l) || T(e.ySortBy, u) || e.chartSettings.xAxis.sorting !== p.xAxis.sorting || e.chartSettings.yAxis.sorting !== p.yAxis.sorting || T(e.facetBy, d) || T(e.annotations.map((e) => e.valueColumn), f.map((e) => e.valueColumn)) || T(x, S) || T(C, w) || (t.dendrogramX || e.dendrogramX) && (e.dendrogramX?.distance !== t.dendrogramX?.distance || e.dendrogramX?.linkage !== t.dendrogramX?.linkage) || (t.dendrogramY || e.dendrogramY) && (e.dendrogramY?.distance !== t.dendrogramY?.distance || e.dendrogramY?.linkage !== t.dendrogramY?.linkage) || e.chartSettings.valueType !== p.valueType || e.facetSettings.sharedX !== m.sharedX || e.facetSettings.sharedY !== m.sharedY || i(e.facetSettings?.order ?? [], t.facetSettings?.order ?? []) || e.normalization?.method !== _?.method || e.normalization?.direction !== _?.direction || e.transform !== b || e.NAValueAs !== y || e.aggregation?.method !== v?.method || e.aggregation?.x !== v?.x || e.aggregation?.y !== v?.y || e.showEmptyRows !== t.showEmptyRows || e.showEmptyColumns !== t.showEmptyColumns;
50
+ let { x: n, y: a, valueColumn: s, xGroupBy: c, yGroupBy: l, xSortBy: d, ySortBy: f, facetBy: p, annotations: m, chartSettings: h, facetSettings: g, dendrogramX: _, dendrogramY: v, normalization: y, aggregation: b, NAValueAs: x, transform: S } = t, C = Object.values(e.dendrogramX?.aes || {}).filter(r), w = Object.values(_?.aes || {}).filter(r), T = Object.values(e.dendrogramY?.aes || {}).filter(r), E = Object.values(v?.aes || {}).filter(r);
51
+ return u(e.x, n) || u(e.y, a) || e.valueColumn.value !== s.value || u(e.xGroupBy, c) || u(e.yGroupBy, l) || u(e.xSortBy, d) || u(e.ySortBy, f) || e.chartSettings.xAxis.sorting !== h.xAxis.sorting || e.chartSettings.yAxis.sorting !== h.yAxis.sorting || u(e.facetBy, p) || u(e.annotations.map((e) => e.valueColumn), m.map((e) => e.valueColumn)) || u(C, w) || u(T, E) || (t.dendrogramX || e.dendrogramX) && (e.dendrogramX?.distance !== t.dendrogramX?.distance || e.dendrogramX?.linkage !== t.dendrogramX?.linkage) || (t.dendrogramY || e.dendrogramY) && (e.dendrogramY?.distance !== t.dendrogramY?.distance || e.dendrogramY?.linkage !== t.dendrogramY?.linkage) || e.chartSettings.valueType !== h.valueType || e.facetSettings.sharedX !== g.sharedX || e.facetSettings.sharedY !== g.sharedY || i(e.facetSettings?.order ?? [], t.facetSettings?.order ?? []) || e.normalization?.method !== y?.method || e.normalization?.direction !== y?.direction || e.transform !== S || e.NAValueAs !== x || e.aggregation?.method !== b?.method || e.aggregation?.x !== b?.x || e.aggregation?.y !== b?.y || e.showEmptyRows !== t.showEmptyRows || e.showEmptyColumns !== t.showEmptyColumns || o(e.chartSettings.xAxis.labelParts, h.xAxis.labelParts) || o(e.chartSettings.yAxis.labelParts, h.yAxis.labelParts);
53
52
  }
54
53
  _needUpdateCalculatedDataByData(e, t) {
55
54
  let n = Object.keys(e.data), r = Object.keys(t.data);
56
55
  return e.id !== t.id || n.length !== r.length || n.some((n) => e.data[n].length !== t.data[n]?.length);
57
56
  }
58
57
  async _updateData() {
59
- let { xColumn: e, yColumn: t, valueColumn: n, xGroupBy: r, yGroupBy: i, xSortBy: a, ySortBy: c, facetBy: l, chartSettings: u, facetSettings: d, annotations: f, dendrogramX: p, dendrogramY: m, normalization: h, NAValueAs: g, transform: _, keysOrder: v, aggregation: y, showEmptyRows: b, showEmptyColumns: x } = this.settings, S = o({
58
+ let { x: e, y: t, valueColumn: n, xGroupBy: r, yGroupBy: i, xSortBy: a, ySortBy: o, facetBy: l, chartSettings: u, facetSettings: d, annotations: f, dendrogramX: p, dendrogramY: m, normalization: h, NAValueAs: g, transform: _, keysOrder: v, aggregation: y, showEmptyRows: b, showEmptyColumns: x } = this.settings, S = s({
60
59
  data: this.data,
61
- xColumn: e,
62
- yColumn: t,
60
+ x: e,
61
+ y: t,
63
62
  valueColumns: { dataSource: n },
64
63
  facetBy: l,
65
64
  xGroupBy: r,
66
65
  yGroupBy: i,
67
66
  xSortBy: a,
68
- ySortBy: c,
67
+ ySortBy: o,
69
68
  facetSettings: d,
70
69
  annotations: f,
71
70
  dendrogramX: p,
@@ -83,7 +82,7 @@ var d = class extends e {
83
82
  if (p && d.sharedX && l.length > 0) throw Error("Dendrogram on X axis is not available with shared by facets X axis");
84
83
  if (m && d.sharedY && l.length > 0) throw Error("Dendrogram on Y axis is not available with shared by facets Y axis");
85
84
  this.clusteringCalculationsInProgress = !0, this.onLoadingChange(!0);
86
- let w = await s({
85
+ let w = await c({
87
86
  groupedCellsData: S,
88
87
  dendrogramX: p,
89
88
  dendrogramY: m
@@ -103,6 +102,6 @@ var d = class extends e {
103
102
  this.chartRenderer.render(this.data, e, n, r, i, this.calculatedData.groupedCellsData, a, t, o, s, this.calculatedData.dendrogramsData, c, this.calculatedData.cellUniqValues, l, this.onTooltipHintSwitch, d);
104
103
  }
105
104
  };
106
- export { d as ChartHeatmap };
105
+ export { p as ChartHeatmap };
107
106
 
108
107
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/heatmap/index.ts"],"sourcesContent":["import { renderToString } from 'react-dom/server.browser';\nimport { AbstractChart } from '../AbstractChart';\nimport type { DataFrame } from '../DataFrame';\nimport { type ColumnName, type DataValue, getUnknownErrorInfo, type HeatmapEventHandlers, type HeatmapSettings, isErrorInfo } from '../types';\nimport { isColumnName } from '../utils';\nimport ChartRenderer from './ChartRenderer';\nimport type { GroupedCellsHeatmap } from './getCells';\nimport { getCells } from './getCells';\nimport type { DendrogramsData } from './getDendrograms';\nimport { getDendrograms } from './getDendrograms';\nimport { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport { MAX_SVG_RENDERED_CELLS_COUNT } from './constants';\nimport { noop } from 'lodash';\nimport { arraysAreDifferent } from '../utils/arraysAreDifferent';\n\nexport class ChartHeatmap extends AbstractChart {\n settings: HeatmapSettingsImpl;\n chartRenderer = new ChartRenderer();\n\n onTooltipHintSwitch: (v:boolean) => void = noop;\n onLoadingChange: (v:boolean) => void = noop;\n\n calculatedData: {\n groupedCellsData: GroupedCellsHeatmap;\n dendrogramsData: DendrogramsData;\n cellUniqValues: DataValue[];\n } | null = null;\n\n clusteringCalculationsInProgress = false;\n\n constructor(data: DataFrame, settings: HeatmapSettings, eventHandlers?:HeatmapEventHandlers) {\n super(data, settings);\n\n this.settings = new HeatmapSettingsImpl(settings);\n if (eventHandlers) {\n this.onTooltipHintSwitch = eventHandlers.onTooltipHintSwitch ?? noop;\n this.onLoadingChange = eventHandlers.onLoadingChange ?? noop;\n }\n }\n\n mount(node: HTMLElement) {\n try {\n this.chartRenderer.init(node);\n this._updateData();\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n unmount() {\n this.chartRenderer.clear();\n }\n\n updateSettingsAndData(data: DataFrame, settings: HeatmapSettings) {\n try {\n const previousSettings = this.settings;\n const previousData = this.data;\n this.settings = new HeatmapSettingsImpl(settings);\n this.data = data;\n if (\n this._needUpdateCalculatedDataBySettings(previousSettings, this.settings) ||\n this._needUpdateCalculatedDataByData(previousData, this.data)\n ) {\n this._updateData();\n } else {\n this._updateAesInData();\n }\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n updateChartState(_field: string, _value: unknown) {\n console.warn('no chart state for heatmap');\n }\n\n export(): string {\n this._updateChart();\n return renderToString(this.chartRenderer.component);\n }\n\n _needUpdateCalculatedDataBySettings(prevSettings: HeatmapSettingsImpl, settings: HeatmapSettingsImpl) {\n const {\n xColumn,\n yColumn,\n valueColumn,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetBy,\n annotations,\n chartSettings,\n facetSettings,\n dendrogramX,\n dendrogramY,\n normalization,\n aggregation,\n NAValueAs,\n transform,\n } = settings;\n\n const prevDendrogramXColumns: ColumnName[] = Object.values(prevSettings.dendrogramX?.aes || {}).filter(\n isColumnName\n );\n const currentDendrogramXColumns: ColumnName[] = Object.values(dendrogramX?.aes || {}).filter(isColumnName);\n const prevDendrogramYColumns: ColumnName[] = Object.values(prevSettings.dendrogramY?.aes || {}).filter(\n isColumnName\n );\n const currentDendrogramYColumns: ColumnName[] = Object.values(dendrogramY?.aes || {}).filter(isColumnName);\n\n function compareColumnGroups(columns1: ColumnName[], columns2: ColumnName[]) {\n return (\n columns1.length !== columns2.length ||\n columns1.some((column, idx) => column.value !== columns2[idx].value)\n );\n }\n\n return (\n prevSettings.xColumn.value !== xColumn.value ||\n prevSettings.yColumn.value !== yColumn.value ||\n prevSettings.valueColumn.value !== valueColumn.value ||\n compareColumnGroups(prevSettings.xGroupBy, xGroupBy) ||\n compareColumnGroups(prevSettings.yGroupBy, yGroupBy) ||\n compareColumnGroups(prevSettings.xSortBy, xSortBy) ||\n compareColumnGroups(prevSettings.ySortBy, ySortBy) ||\n prevSettings.chartSettings.xAxis.sorting !== chartSettings.xAxis.sorting ||\n prevSettings.chartSettings.yAxis.sorting !== chartSettings.yAxis.sorting ||\n compareColumnGroups(prevSettings.facetBy, facetBy) ||\n compareColumnGroups(\n prevSettings.annotations.map(a => a.valueColumn),\n annotations.map(a => a.valueColumn)\n ) ||\n compareColumnGroups(prevDendrogramXColumns, currentDendrogramXColumns) ||\n compareColumnGroups(prevDendrogramYColumns, currentDendrogramYColumns) ||\n ((settings.dendrogramX || prevSettings.dendrogramX) &&\n (prevSettings.dendrogramX?.distance !== settings.dendrogramX?.distance ||\n prevSettings.dendrogramX?.linkage !== settings.dendrogramX?.linkage)) ||\n ((settings.dendrogramY || prevSettings.dendrogramY) &&\n (prevSettings.dendrogramY?.distance !== settings.dendrogramY?.distance ||\n prevSettings.dendrogramY?.linkage !== settings.dendrogramY?.linkage)) ||\n prevSettings.chartSettings.valueType !== chartSettings.valueType ||\n prevSettings.facetSettings.sharedX !== facetSettings.sharedX ||\n prevSettings.facetSettings.sharedY !== facetSettings.sharedY ||\n arraysAreDifferent(prevSettings.facetSettings?.order ?? [], settings.facetSettings?.order ?? []) ||\n prevSettings.normalization?.method !== normalization?.method ||\n prevSettings.normalization?.direction !== normalization?.direction ||\n prevSettings.transform !== transform ||\n prevSettings.NAValueAs !== NAValueAs ||\n prevSettings.aggregation?.method !== aggregation?.method ||\n prevSettings.aggregation?.x !== aggregation?.x ||\n prevSettings.aggregation?.y !== aggregation?.y ||\n prevSettings.showEmptyRows !== settings.showEmptyRows ||\n prevSettings.showEmptyColumns !== settings.showEmptyColumns\n );\n }\n\n _needUpdateCalculatedDataByData(prevData: DataFrame, data: DataFrame) {\n const prevKeys = Object.keys(prevData.data);\n const keys = Object.keys(data.data);\n return (\n prevData.id !== data.id ||\n prevKeys.length !== keys.length ||\n prevKeys.some(key => prevData.data[key].length !== data.data[key]?.length)\n );\n }\n\n async _updateData() {\n const {\n xColumn,\n yColumn,\n valueColumn,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetBy,\n chartSettings,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalization,\n NAValueAs,\n transform,\n keysOrder,\n aggregation,\n showEmptyRows,\n showEmptyColumns,\n } = this.settings;\n\n const groupedCellsData = getCells({\n data: this.data,\n xColumn,\n yColumn,\n valueColumns: { dataSource: valueColumn },\n facetBy,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalization,\n NAValueAs,\n transform,\n keysOrder,\n xAxis: chartSettings.xAxis,\n yAxis: chartSettings.yAxis,\n aggregation,\n showEmptyRows,\n showEmptyColumns,\n });\n\n const cellUniqValues = chartSettings.valueType === 'discrete' ? this.data.getColumnCategories(valueColumn.value) : [];\n \n if (dendrogramX && facetSettings.sharedX && facetBy.length > 0) {\n throw Error('Dendrogram on X axis is not available with shared by facets X axis');\n }\n if (dendrogramY && facetSettings.sharedY && facetBy.length > 0) {\n throw Error('Dendrogram on Y axis is not available with shared by facets Y axis');\n }\n this.clusteringCalculationsInProgress = true;\n this.onLoadingChange(true);\n const dendrogramsData = await getDendrograms({ groupedCellsData, dendrogramX, dendrogramY });\n this.clusteringCalculationsInProgress = false;\n this.onLoadingChange(false);\n\n this.calculatedData = {\n groupedCellsData,\n dendrogramsData,\n cellUniqValues,\n };\n \n this._updateChart();\n }\n\n _updateAesInData() {\n this._updateChart();\n }\n\n _updateChart() {\n if (!this.calculatedData || this.clusteringCalculationsInProgress) {\n return;\n }\n const {\n id,\n valueColumn,\n chartSettings,\n facetSettings,\n aes,\n annotations,\n dendrogramX,\n dendrogramY,\n inheritedDendrogramAes,\n normalization,\n } = this.settings;\n const dataSize = this.data.columnNames.length ? this.data.getColumn(this.data.columnNames[0]).length : 0;\n const cellsRenderingMode = this.settings.cellsRenderingMode ?? (dataSize > MAX_SVG_RENDERED_CELLS_COUNT ? 'canvas' : 'svg');\n\n this.chartRenderer.render(\n this.data,\n id,\n chartSettings,\n facetSettings,\n aes,\n this.calculatedData.groupedCellsData,\n annotations,\n valueColumn,\n dendrogramX,\n dendrogramY,\n this.calculatedData.dendrogramsData,\n inheritedDendrogramAes,\n this.calculatedData.cellUniqValues,\n normalization,\n this.onTooltipHintSwitch,\n cellsRenderingMode\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/heatmap/index.ts"],"sourcesContent":["import { renderToString } from 'react-dom/server.browser';\nimport { AbstractChart } from '../AbstractChart';\nimport type { DataFrame } from '../DataFrame';\nimport { type ColumnName, type DataValue, getUnknownErrorInfo, type HeatmapEventHandlers, type HeatmapSettings, isErrorInfo } from '../types';\nimport { isColumnName } from '../utils';\nimport ChartRenderer from './ChartRenderer';\nimport type { GroupedCellsHeatmap } from './getCells';\nimport { getCells } from './getCells';\nimport type { DendrogramsData } from './getDendrograms';\nimport { getDendrograms } from './getDendrograms';\nimport { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport { MAX_SVG_RENDERED_CELLS_COUNT } from './constants';\nimport { noop } from 'lodash';\nimport { arraysAreDifferent } from '../utils/arraysAreDifferent';\nimport { compareColumnGroups } from '../utils/compareColumnGroups';\nimport { labelPartsChanged } from './labelParts';\n\nexport class ChartHeatmap extends AbstractChart {\n settings: HeatmapSettingsImpl;\n chartRenderer = new ChartRenderer();\n\n onTooltipHintSwitch: (v:boolean) => void = noop;\n onLoadingChange: (v:boolean) => void = noop;\n\n calculatedData: {\n groupedCellsData: GroupedCellsHeatmap;\n dendrogramsData: DendrogramsData;\n cellUniqValues: DataValue[];\n } | null = null;\n\n clusteringCalculationsInProgress = false;\n\n constructor(data: DataFrame, settings: HeatmapSettings, eventHandlers?:HeatmapEventHandlers) {\n super(data, settings);\n\n this.settings = new HeatmapSettingsImpl(settings);\n if (eventHandlers) {\n this.onTooltipHintSwitch = eventHandlers.onTooltipHintSwitch ?? noop;\n this.onLoadingChange = eventHandlers.onLoadingChange ?? noop;\n }\n }\n\n mount(node: HTMLElement) {\n try {\n this.chartRenderer.init(node);\n this._updateData();\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n unmount() {\n this.chartRenderer.clear();\n }\n\n updateSettingsAndData(data: DataFrame, settings: HeatmapSettings) {\n try {\n const previousSettings = this.settings;\n const previousData = this.data;\n this.settings = new HeatmapSettingsImpl(settings);\n this.data = data;\n if (\n this._needUpdateCalculatedDataBySettings(previousSettings, this.settings) ||\n this._needUpdateCalculatedDataByData(previousData, this.data)\n ) {\n this._updateData();\n } else {\n this._updateAesInData();\n }\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n updateChartState(_field: string, _value: unknown) {\n console.warn('no chart state for heatmap');\n }\n\n export(): string {\n this._updateChart();\n return renderToString(this.chartRenderer.component);\n }\n\n _needUpdateCalculatedDataBySettings(prevSettings: HeatmapSettingsImpl, settings: HeatmapSettingsImpl) {\n const {\n x,\n y,\n valueColumn,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetBy,\n annotations,\n chartSettings,\n facetSettings,\n dendrogramX,\n dendrogramY,\n normalization,\n aggregation,\n NAValueAs,\n transform,\n } = settings;\n\n const prevDendrogramXColumns: ColumnName[] = Object.values(prevSettings.dendrogramX?.aes || {}).filter(\n isColumnName\n );\n const currentDendrogramXColumns: ColumnName[] = Object.values(dendrogramX?.aes || {}).filter(isColumnName);\n const prevDendrogramYColumns: ColumnName[] = Object.values(prevSettings.dendrogramY?.aes || {}).filter(\n isColumnName\n );\n const currentDendrogramYColumns: ColumnName[] = Object.values(dendrogramY?.aes || {}).filter(isColumnName);\n\n return (\n compareColumnGroups(prevSettings.x, x) ||\n compareColumnGroups(prevSettings.y, y) ||\n prevSettings.valueColumn.value !== valueColumn.value ||\n compareColumnGroups(prevSettings.xGroupBy, xGroupBy) ||\n compareColumnGroups(prevSettings.yGroupBy, yGroupBy) ||\n compareColumnGroups(prevSettings.xSortBy, xSortBy) ||\n compareColumnGroups(prevSettings.ySortBy, ySortBy) ||\n prevSettings.chartSettings.xAxis.sorting !== chartSettings.xAxis.sorting ||\n prevSettings.chartSettings.yAxis.sorting !== chartSettings.yAxis.sorting ||\n compareColumnGroups(prevSettings.facetBy, facetBy) ||\n compareColumnGroups(\n prevSettings.annotations.map(a => a.valueColumn),\n annotations.map(a => a.valueColumn)\n ) ||\n compareColumnGroups(prevDendrogramXColumns, currentDendrogramXColumns) ||\n compareColumnGroups(prevDendrogramYColumns, currentDendrogramYColumns) ||\n ((settings.dendrogramX || prevSettings.dendrogramX) &&\n (prevSettings.dendrogramX?.distance !== settings.dendrogramX?.distance ||\n prevSettings.dendrogramX?.linkage !== settings.dendrogramX?.linkage)) ||\n ((settings.dendrogramY || prevSettings.dendrogramY) &&\n (prevSettings.dendrogramY?.distance !== settings.dendrogramY?.distance ||\n prevSettings.dendrogramY?.linkage !== settings.dendrogramY?.linkage)) ||\n prevSettings.chartSettings.valueType !== chartSettings.valueType ||\n prevSettings.facetSettings.sharedX !== facetSettings.sharedX ||\n prevSettings.facetSettings.sharedY !== facetSettings.sharedY ||\n arraysAreDifferent(prevSettings.facetSettings?.order ?? [], settings.facetSettings?.order ?? []) ||\n prevSettings.normalization?.method !== normalization?.method ||\n prevSettings.normalization?.direction !== normalization?.direction ||\n prevSettings.transform !== transform ||\n prevSettings.NAValueAs !== NAValueAs ||\n prevSettings.aggregation?.method !== aggregation?.method ||\n prevSettings.aggregation?.x !== aggregation?.x ||\n prevSettings.aggregation?.y !== aggregation?.y ||\n prevSettings.showEmptyRows !== settings.showEmptyRows ||\n prevSettings.showEmptyColumns !== settings.showEmptyColumns ||\n labelPartsChanged(prevSettings.chartSettings.xAxis.labelParts, chartSettings.xAxis.labelParts) ||\n labelPartsChanged(prevSettings.chartSettings.yAxis.labelParts, chartSettings.yAxis.labelParts)\n );\n }\n\n _needUpdateCalculatedDataByData(prevData: DataFrame, data: DataFrame) {\n const prevKeys = Object.keys(prevData.data);\n const keys = Object.keys(data.data);\n return (\n prevData.id !== data.id ||\n prevKeys.length !== keys.length ||\n prevKeys.some(key => prevData.data[key].length !== data.data[key]?.length)\n );\n }\n\n async _updateData() {\n const {\n x,\n y,\n valueColumn,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetBy,\n chartSettings,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalization,\n NAValueAs,\n transform,\n keysOrder,\n aggregation,\n showEmptyRows,\n showEmptyColumns,\n } = this.settings;\n\n const groupedCellsData = getCells({\n data: this.data,\n x,\n y,\n valueColumns: { dataSource: valueColumn },\n facetBy,\n xGroupBy,\n yGroupBy,\n xSortBy,\n ySortBy,\n facetSettings,\n annotations,\n dendrogramX,\n dendrogramY,\n normalization,\n NAValueAs,\n transform,\n keysOrder,\n xAxis: chartSettings.xAxis,\n yAxis: chartSettings.yAxis,\n aggregation,\n showEmptyRows,\n showEmptyColumns,\n });\n\n const cellUniqValues = chartSettings.valueType === 'discrete' ? this.data.getColumnCategories(valueColumn.value) : [];\n \n if (dendrogramX && facetSettings.sharedX && facetBy.length > 0) {\n throw Error('Dendrogram on X axis is not available with shared by facets X axis');\n }\n if (dendrogramY && facetSettings.sharedY && facetBy.length > 0) {\n throw Error('Dendrogram on Y axis is not available with shared by facets Y axis');\n }\n this.clusteringCalculationsInProgress = true;\n this.onLoadingChange(true);\n const dendrogramsData = await getDendrograms({ groupedCellsData, dendrogramX, dendrogramY });\n this.clusteringCalculationsInProgress = false;\n this.onLoadingChange(false);\n\n this.calculatedData = {\n groupedCellsData,\n dendrogramsData,\n cellUniqValues,\n };\n \n this._updateChart();\n }\n\n _updateAesInData() {\n this._updateChart();\n }\n\n _updateChart() {\n if (!this.calculatedData || this.clusteringCalculationsInProgress) {\n return;\n }\n const {\n id,\n valueColumn,\n chartSettings,\n facetSettings,\n aes,\n annotations,\n dendrogramX,\n dendrogramY,\n inheritedDendrogramAes,\n normalization,\n } = this.settings;\n const dataSize = this.data.columnNames.length ? this.data.getColumn(this.data.columnNames[0]).length : 0;\n const cellsRenderingMode = this.settings.cellsRenderingMode ?? (dataSize > MAX_SVG_RENDERED_CELLS_COUNT ? 'canvas' : 'svg');\n\n this.chartRenderer.render(\n this.data,\n id,\n chartSettings,\n facetSettings,\n aes,\n this.calculatedData.groupedCellsData,\n annotations,\n valueColumn,\n dendrogramX,\n dendrogramY,\n this.calculatedData.dendrogramsData,\n inheritedDendrogramAes,\n this.calculatedData.cellUniqValues,\n normalization,\n this.onTooltipHintSwitch,\n cellsRenderingMode\n );\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { DataFrame } from '../DataFrame';
2
+ import { ColumnName } from '../types';
3
+ /**
4
+ * Selects and orders the axis parts to render as labels from the resolved id
5
+ * list (`labelParts`), which graph-maker has already ordered and filtered to
6
+ * the visible set. `x` / `y` remain the source of truth for the column schema;
7
+ * this only reorders/subsets them by id. undefined ids → render all parts.
8
+ * Ids with no matching part (e.g. stale) are skipped.
9
+ */
10
+ export declare function resolveLabelParts(parts: ColumnName[], ids: ColumnName['value'][] | null | undefined): ColumnName[];
11
+ /** Per-row joined display label across the given parts. */
12
+ export declare function joinLabel(parts: ColumnName[], data: DataFrame, rowIdx: number): string;
13
+ /** Axis title built from per-source labels of the given (already-resolved) parts. */
14
+ export declare function joinAxisTitle(parts: ColumnName[]): string;
15
+ /**
16
+ * True when the resolved label-part ids differ. labelParts feeds
17
+ * meta.xLabels/yLabels via fillCellsData, so any change to the visible set or
18
+ * its order must invalidate cached cells.
19
+ */
20
+ export declare function labelPartsChanged(prev: ColumnName['value'][] | null | undefined, curr: ColumnName['value'][] | null | undefined): boolean;
21
+ //# sourceMappingURL=labelParts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labelParts.d.ts","sourceRoot":"","sources":["../../src/heatmap/labelParts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI3C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,KAAK,EAAE,UAAU,EAAE,EACnB,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAC9C,UAAU,EAAE,CAad;AAiCD,2DAA2D;AAC3D,wBAAgB,SAAS,CACrB,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,EAAE,SAAS,EACf,MAAM,EAAE,MAAM,GACf,MAAM,CAER;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,CAEzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,EAC9C,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAC/C,OAAO,CAKT"}
@@ -0,0 +1,55 @@
1
+ var e = ", ";
2
+ /**
3
+ * Selects and orders the axis parts to render as labels from the resolved id
4
+ * list (`labelParts`), which graph-maker has already ordered and filtered to
5
+ * the visible set. `x` / `y` remain the source of truth for the column schema;
6
+ * this only reorders/subsets them by id. undefined ids → render all parts.
7
+ * Ids with no matching part (e.g. stale) are skipped.
8
+ */
9
+ function t(e, t) {
10
+ if (!t) return e;
11
+ let n = new Map(e.map((e) => [e.value, e])), r = [];
12
+ for (let e of t) {
13
+ let t = n.get(e);
14
+ t && r.push(t);
15
+ }
16
+ return r;
17
+ }
18
+ /**
19
+ * Picks the display label for a single source on a given row.
20
+ *
21
+ * Priority: per-row label column (`valueLabels`) → finite value map
22
+ * (`valueLabelsMap` from `pl7.app/valueLabels`) → raw value → the column's
23
+ * `nullValueLabel` (falling back to `'NA'`).
24
+ */
25
+ function n(e, t, n) {
26
+ if (e.valueLabels) {
27
+ let r = t.getColumnValue(e.valueLabels, n);
28
+ if (r != null) return String(r);
29
+ }
30
+ let r = t.getColumnValue(e.value, n);
31
+ if (e.valueLabelsMap && r != null) {
32
+ let t = e.valueLabelsMap[String(r)];
33
+ if (t !== void 0) return t;
34
+ }
35
+ return r == null ? e.nullValueLabel ?? "NA" : String(r);
36
+ }
37
+ /** Per-row joined display label across the given parts. */
38
+ function r(t, r, i) {
39
+ return t.map((e) => n(e, r, i)).join(e);
40
+ }
41
+ /** Axis title built from per-source labels of the given (already-resolved) parts. */
42
+ function i(t) {
43
+ return t.map((e) => e.label ?? e.value).join(e);
44
+ }
45
+ /**
46
+ * True when the resolved label-part ids differ. labelParts feeds
47
+ * meta.xLabels/yLabels via fillCellsData, so any change to the visible set or
48
+ * its order must invalidate cached cells.
49
+ */
50
+ function a(e, t) {
51
+ return e === t ? !1 : !e || !t || e.length !== t.length ? !0 : e.some((e, n) => e !== t[n]);
52
+ }
53
+ export { i as joinAxisTitle, r as joinLabel, a as labelPartsChanged, t as resolveLabelParts };
54
+
55
+ //# sourceMappingURL=labelParts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labelParts.js","names":[],"sources":["../../src/heatmap/labelParts.ts"],"sourcesContent":["import type { DataFrame } from '../DataFrame';\nimport type { ColumnName } from '../types';\n\nconst SEPARATOR = ', ';\n\n/**\n * Selects and orders the axis parts to render as labels from the resolved id\n * list (`labelParts`), which graph-maker has already ordered and filtered to\n * the visible set. `x` / `y` remain the source of truth for the column schema;\n * this only reorders/subsets them by id. undefined ids → render all parts.\n * Ids with no matching part (e.g. stale) are skipped.\n */\nexport function resolveLabelParts(\n parts: ColumnName[],\n ids: ColumnName['value'][] | null | undefined,\n): ColumnName[] {\n if (!ids) {\n return parts;\n }\n const byKey = new Map(parts.map((p) => [p.value, p]));\n const result: ColumnName[] = [];\n for (const id of ids) {\n const p = byKey.get(id);\n if (p) {\n result.push(p);\n }\n }\n return result;\n}\n\n/**\n * Picks the display label for a single source on a given row.\n *\n * Priority: per-row label column (`valueLabels`) → finite value map\n * (`valueLabelsMap` from `pl7.app/valueLabels`) → raw value → the column's\n * `nullValueLabel` (falling back to `'NA'`).\n */\nfunction labelOf(\n column: ColumnName,\n data: DataFrame,\n rowIdx: number,\n): string {\n if (column.valueLabels) {\n const v = data.getColumnValue(column.valueLabels, rowIdx);\n if (v !== null && v !== undefined) {\n return String(v);\n }\n }\n const raw = data.getColumnValue(column.value, rowIdx);\n if (column.valueLabelsMap && raw !== null && raw !== undefined) {\n const mapped = column.valueLabelsMap[String(raw)];\n if (mapped !== undefined) {\n return mapped;\n }\n }\n if (raw !== null && raw !== undefined) {\n return String(raw);\n }\n return column.nullValueLabel ?? 'NA';\n}\n\n/** Per-row joined display label across the given parts. */\nexport function joinLabel(\n parts: ColumnName[],\n data: DataFrame,\n rowIdx: number,\n): string {\n return parts.map((p) => labelOf(p, data, rowIdx)).join(SEPARATOR);\n}\n\n/** Axis title built from per-source labels of the given (already-resolved) parts. */\nexport function joinAxisTitle(parts: ColumnName[]): string {\n return parts.map((p) => p.label ?? p.value).join(SEPARATOR);\n}\n\n/**\n * True when the resolved label-part ids differ. labelParts feeds\n * meta.xLabels/yLabels via fillCellsData, so any change to the visible set or\n * its order must invalidate cached cells.\n */\nexport function labelPartsChanged(\n prev: ColumnName['value'][] | null | undefined,\n curr: ColumnName['value'][] | null | undefined,\n): boolean {\n if (prev === curr) return false;\n if (!prev || !curr) return true;\n if (prev.length !== curr.length) return true;\n return prev.some((id, idx) => id !== curr[idx]);\n}\n"],"mappings":"AAGA,IAAM,IAAY;;;;;;;;AASlB,SAAgB,EACZ,GACA,GACY;AACZ,KAAI,CAAC,EACD,QAAO;CAEX,IAAM,IAAQ,IAAI,IAAI,EAAM,KAAK,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAC/C,IAAuB,EAAE;AAC/B,MAAK,IAAM,KAAM,GAAK;EAClB,IAAM,IAAI,EAAM,IAAI,EAAG;AACvB,EAAI,KACA,EAAO,KAAK,EAAE;;AAGtB,QAAO;;;;;;;;;AAUX,SAAS,EACL,GACA,GACA,GACM;AACN,KAAI,EAAO,aAAa;EACpB,IAAM,IAAI,EAAK,eAAe,EAAO,aAAa,EAAO;AACzD,MAAI,KAAM,KACN,QAAO,OAAO,EAAE;;CAGxB,IAAM,IAAM,EAAK,eAAe,EAAO,OAAO,EAAO;AACrD,KAAI,EAAO,kBAAkB,KAAQ,MAA2B;EAC5D,IAAM,IAAS,EAAO,eAAe,OAAO,EAAI;AAChD,MAAI,MAAW,KAAA,EACX,QAAO;;AAMf,QAHI,KAAQ,OAGL,EAAO,kBAAkB,OAFrB,OAAO,EAAI;;;AAM1B,SAAgB,EACZ,GACA,GACA,GACM;AACN,QAAO,EAAM,KAAK,MAAM,EAAQ,GAAG,GAAM,EAAO,CAAC,CAAC,KAAK,EAAU;;;AAIrE,SAAgB,EAAc,GAA6B;AACvD,QAAO,EAAM,KAAK,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAU;;;;;;;AAQ/D,SAAgB,EACZ,GACA,GACO;AAIP,QAHI,MAAS,IAAa,KACtB,CAAC,KAAQ,CAAC,KACV,EAAK,WAAW,EAAK,SAAe,KACjC,EAAK,MAAM,GAAI,MAAQ,MAAO,EAAK,GAAK"}