@milaboratories/miplots4 1.2.3 → 1.3.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.
- package/dist/discrete/components/layers/ErrorBarElement.d.ts.map +1 -1
- package/dist/discrete/components/layers/ErrorBarElement.js +1 -0
- package/dist/discrete/components/layers/ErrorBarElement.js.map +1 -1
- package/dist/discrete/components/layers/LineElement.d.ts.map +1 -1
- package/dist/discrete/components/layers/LineElement.js +1 -0
- package/dist/discrete/components/layers/LineElement.js.map +1 -1
- package/dist/heatmap/ChartRenderer.d.ts.map +1 -1
- package/dist/heatmap/ChartRenderer.js +72 -78
- package/dist/heatmap/ChartRenderer.js.map +1 -1
- package/dist/scatterplot/ChartRenderer.d.ts.map +1 -1
- package/dist/scatterplot/ChartRenderer.js +2 -1
- package/dist/scatterplot/ChartRenderer.js.map +1 -1
- package/dist/scatterplot/ScatterplotSettingsImpl.d.ts +1 -0
- package/dist/scatterplot/ScatterplotSettingsImpl.d.ts.map +1 -1
- package/dist/scatterplot/ScatterplotSettingsImpl.js +2 -1
- package/dist/scatterplot/ScatterplotSettingsImpl.js.map +1 -1
- package/dist/scatterplot/components/ChartTrendsData.d.ts.map +1 -1
- package/dist/scatterplot/components/ChartTrendsData.js +2 -1
- package/dist/scatterplot/components/ChartTrendsData.js.map +1 -1
- package/dist/scatterplot/components/types.d.ts +1 -0
- package/dist/scatterplot/components/types.d.ts.map +1 -1
- package/dist/scatterplot-umap/ChartRenderer.d.ts.map +1 -1
- package/dist/scatterplot-umap/ChartRenderer.js +2 -0
- package/dist/scatterplot-umap/ChartRenderer.js.map +1 -1
- package/dist/scatterplot-umap/components/LowerSVG.js +1 -1
- package/dist/scatterplot-umap/components/LowerSVG.js.map +1 -1
- package/dist/scatterplot-umap/types.d.ts +1 -0
- package/dist/scatterplot-umap/types.d.ts.map +1 -1
- package/dist/types/scatterplot.d.ts +5 -0
- package/dist/types/scatterplot.d.ts.map +1 -1
- package/dist/types/scatterplot.js +2 -1
- package/dist/types/scatterplot.js.map +1 -1
- package/dist/utils/computeChartInnerSize.d.ts +18 -0
- package/dist/utils/computeChartInnerSize.d.ts.map +1 -0
- package/dist/utils/computeChartInnerSize.js +22 -0
- package/dist/utils/computeChartInnerSize.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/heatmap/ChartRenderer.tsx"],"sourcesContent":["import { extent } from 'd3-array';\nimport type { HierarchyNode, HierarchyPointNode } from 'd3-hierarchy';\nimport { cluster } from 'd3-hierarchy';\nimport type { ScaleLinear, ScaleOrdinal } from 'd3-scale';\nimport { scaleLinear, scaleOrdinal } from 'd3-scale';\nimport lodash from 'lodash';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\nimport { Error } from '../common/Error';\nimport type { LegendData, LegendItem } from '../common/types';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport { DEFAULT_HEIGHT, DEFAULT_WIDTH, MAX_LEGEND_GRADIENT_HEIGHT, MIN_LEGEND_GRADIENT_HEIGHT, TITLE_LINE_HEIGHT, TITLE_MARGIN } from '../constants';\nimport type { DataFrame } from '../DataFrame';\nimport type { AesItem, ColumnName, DataValue } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { getChartEdgeSides } from '../utils/getChartEdgeSides';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type {\n AnnotationColorScales,\n CaptionsSizes,\n ChartDendrograms,\n ChartDimensionsData,\n ChartSizes,\n ChartsScales,\n Cluster,\n DendrogramAesScales,\n LabelAngles,\n Margins,\n} from './components/types';\nimport { CHART_SIDE_ELEMENTS, DEFAULT_AES, LEGEND_OFFSET, MIN_MARGIN, TITLE_LINE } from './constants';\nimport type { GroupedCellsHeatmap } from './getCells';\nimport type { DendrogramsData } from './getDendrograms';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport {\n calculateAnnotationTitleSizes,\n calculateChartSideElementSizes,\n calculateSideElementsBBoxes,\n createContinuousColorScale,\n createDiscreteColorScale,\n createDiscreteRoundColorScale,\n} from './utils';\nimport { calculateCaptionTails } from './utils/calculateCaptionTails';\n\nconst COS_PI_4 = Math.cos(Math.PI / 4);\nconst INCLINE_OFFSET = 5; // height of little triangle of text for captions inclined 45deg\nfunction updateLinksHeight(root: HierarchyPointNode<Cluster>, scale: (v: number) => number, coord: 'x' | 'y') {\n function setHeight(d: HierarchyPointNode<Cluster>) {\n d[coord] = scale(d.data.height);\n if (d.children) d.children.forEach(setHeight);\n }\n setHeight(root);\n}\n\n// add shift to move nodes positions with group gaps\nfunction addShiftToLinkCoord(\n root: HierarchyPointNode<Cluster>,\n shift: number,\n coordFrom: 'x' | 'y',\n coordTo = coordFrom\n) {\n function setX(d: HierarchyPointNode<Cluster>) {\n d[coordTo] = d[coordFrom] + shift;\n if (d.children) d.children.forEach(setX);\n }\n setX(root);\n}\n\nconst getSteps = (count: number, valueExtent: number[]) => {\n const min = Math.min(...valueExtent);\n const max = Math.max(...valueExtent);\n if (min === max) {\n const steps = count % 2 === 0 ? [] : [min];\n for (let i = 1; i < count / 2 + 1; i++) {\n steps.push(min + i);\n steps.unshift(min - i);\n }\n return steps;\n }\n if (count < 2) {\n return [min, max];\n }\n const step = (max - min) / (count - 1);\n const steps = [];\n for (let i = 0; i < count - 1; i++) {\n steps.push(min + step * i);\n }\n steps.push(max);\n return steps;\n};\n\nfunction getContinuousColorRange(normalization: HeatmapSettingsImpl['normalization'], colorsCount: number, valueExtent: number[]) {\n let extent = valueExtent;\n if (normalization) {\n if (normalization.colorRange) {\n extent = normalization.colorRange;\n }\n if (normalization.method === 'standardScaling') {\n extent = [-2, 2];\n }\n if (normalization.method === 'meanNormalization') {\n extent = [-0.75, 0.75];\n }\n }\n return getSteps(colorsCount, extent);\n}\n\nfunction getMaxTextLength(keys: string[], labels: Record<string, string>, textMeasurer: TextMeasurer) {\n let maxLabelSize = 0;\n for (const key of keys) {\n if (labels[key] === undefined) continue;\n const l = textMeasurer.getTextWidth(labels[key]);\n if (l > maxLabelSize) maxLabelSize = l;\n }\n return maxLabelSize;\n}\n\nfunction getCaptionHeight(size: number, angle: number) {\n if (angle === 90) {\n return size;\n }\n if (angle === 45) {\n return size * COS_PI_4 + (size > 0 ? 2 * INCLINE_OFFSET : 0);\n }\n return TITLE_LINE;\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = (<></>);\n chartsDimensions: Record<string, ChartDimensionsData> = {};\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\n chartsWidth: DEFAULT_WIDTH, // width of all charts in charts row\n chartsHeight: DEFAULT_HEIGHT, // width of all charts in charts column, without axes\n totalWidth: DEFAULT_WIDTH, // width of all charts in charts row, plus left axis, plus legend\n totalHeight: DEFAULT_HEIGHT, // width of all charts in charts height, plus bottom axis, plus top title\n };\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n captionsSizes: CaptionsSizes = {\n xAxisCaptions: 100,\n yAxisCaptions: 100,\n xGroupCaptions: TITLE_LINE,\n yGroupCaptions: TITLE_LINE,\n xCaptionTail: 0,\n yCaptionTail: 0,\n };\n labelAngles: LabelAngles = {\n xAxisLabels: 0,\n yAxisLabels: 0,\n xGroupLabels: 0,\n yGroupLabels: 0,\n };\n columnsCount = 1;\n rowsCount = 1;\n scales: ChartsScales = {\n // scales grouped by facet\n x: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n y: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n };\n step: {\n x: Record<string, number>;\n y: Record<string, number>;\n } = { x: {}, y: {} };\n colorScale: ScaleLinear<string, string> | ScaleOrdinal<string, string, string> = scaleLinear<string, string>()\n .domain([0, 1])\n .range(['white', 'black']);\n annotationColorScales: AnnotationColorScales = {};\n dendrogramAesScales: DendrogramAesScales = {};\n legend: LegendData = {\n width: 0,\n height: 0,\n items: [],\n };\n dendrograms: Record<string, ChartDendrograms> = {};\n\n clear() {\n if (this.parentNode && this.rootNode) {\n this.parentNode?.removeChild(this.rootNode);\n this.parentNode = null;\n this.rootNode = null;\n }\n // timeout to avoid trying to unmount during rendering\n setTimeout(() => {\n this.reactRoot?.unmount();\n this.reactRoot = null;\n });\n }\n\n init(node: HTMLElement) {\n if (this.parentNode === null) {\n this.parentNode = node;\n this.rootNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateMargins(title: HeatmapSettingsImpl['chartSettings']['title'], size: HeatmapSettingsImpl['chartSettings']['size']) {\n this.margins = {\n top: title.show ? TITLE_LINE_HEIGHT + TITLE_MARGIN * 2 : size.outerOffset,\n bottom: size.outerOffset,\n left: size.outerOffset,\n right: this.legend.width + size.outerOffset,\n };\n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartsHeight + this.margins.bottom, this.legend.height);\n }\n\n updateLegendSize(\n valueType: HeatmapSettingsImpl['chartSettings']['valueType'],\n legend: HeatmapSettingsImpl['chartSettings']['legend'],\n annotations: HeatmapSettingsImpl['annotations'],\n columnValue: ColumnName,\n valueExtent: [number, number]\n ) {\n if (!legend.show) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n const continuousHeight = Math.min(\n Math.max(this.chartSizes.chartHeight, MIN_LEGEND_GRADIENT_HEIGHT),\n MAX_LEGEND_GRADIENT_HEIGHT\n );\n const legendHeight = Math.max(this.chartSizes.chartHeight, continuousHeight);\n const legendItems: LegendItem[] = [];\n const emptySizes = { width: 0, height: 0, left: 0, top: 0 };\n\n const getDefaultLabels = (values: (string | number)[]) => values.reduce((res: Record<string, string>, v: string | number) => { res[v] = String(v); return res; }, {});\n if (valueType === 'continuous') {\n const scale = this.colorScale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n const title = columnValue.label ?? columnValue.value;\n legendItems.push({\n ...emptySizes,\n type: 'continuous',\n id: 'heatmapValue',\n scale,\n values,\n title,\n tickPositionScale\n });\n } else if (valueType === 'discrete') {\n const scale = this.colorScale as ScaleOrdinal<string, string>;\n const title = columnValue.label ?? columnValue.value;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: 'heatmapValue', title, scale, values, labels });\n }\n annotations.forEach(item => {\n const title = item.valueColumn.label ?? item.valueColumn.value;\n if (item.type === 'continuous') {\n const scale = this.annotationColorScales[item.id].scale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n\n legendItems.push({ ...emptySizes, type: 'continuous', id: item.id, tickPositionScale, title, scale, values });\n }\n if (item.type === 'discrete') {\n const scale = this.annotationColorScales[item.id].scale as ScaleOrdinal<string, string>;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: item.id, title, scale, values, labels });\n }\n });\n\n if (!legendItems.length) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n\n const items = arrangeLegendParts(legendItems, this.chartSizes.chartHeight,continuousHeight);\n const maxRightEdge = items.reduce((max, item) => Math.max(max, item.left + item.width), 0);\n\n const legendWidth = maxRightEdge + LEGEND_OFFSET;\n\n this.legend = {\n width: legendWidth,\n height: legendHeight,\n items\n };\n }\n\n updateCaptionsSize(\n groupedCells: GroupedCellsHeatmap,\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n facetSettings: HeatmapSettingsImpl['facetSettings']\n ) {\n const textMeasurer = new TextMeasurer('bold 16px Manrope');\n const { xGroupKeys, yGroupKeys, xGroupLabels, yGroupLabels, xKeysByGroups, yKeysByGroups, xLabels, yLabels } = groupedCells.meta;\n this.labelAngles = {\n xAxisLabels: xAxis.axisLabelsAngle,\n yAxisLabels: yAxis.axisLabelsAngle,\n xGroupLabels: xAxis.groupLabelsAngle,\n yGroupLabels: yAxis.groupLabelsAngle,\n };\n\n const maxXLabelSize = xGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(xKeysByGroups[key], xLabels, textMeasurer)), 0);\n const maxYLabelSize = yGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(yKeysByGroups[key], yLabels, textMeasurer)), 0);\n const maxXGroupLabelSize = getMaxTextLength(xGroupKeys, xGroupLabels, textMeasurer);\n const maxYGroupLabelSize = getMaxTextLength(yGroupKeys, yGroupLabels, textMeasurer);\n const { xCaptionTail, yCaptionTail } = calculateCaptionTails(\n this.labelAngles,\n facetSettings,\n this.scales,\n this.step,\n groupedCells,\n textMeasurer\n );\n this.captionsSizes = {\n xCaptionTail,\n yCaptionTail,\n xGroupCaptions: getCaptionHeight(maxXGroupLabelSize, this.labelAngles.xGroupLabels),\n yGroupCaptions: getCaptionHeight(maxYGroupLabelSize, this.labelAngles.yGroupLabels),\n xAxisCaptions: getCaptionHeight(maxXLabelSize, this.labelAngles.xAxisLabels),\n yAxisCaptions: getCaptionHeight(maxYLabelSize, this.labelAngles.yAxisLabels),\n };\n }\n\n updateChartDimensions(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n annotations: HeatmapSettingsImpl['annotations'],\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n const facetCount = facetKeys.length;\n const maxNRows = Math.min(facetSettings.nRows ?? facetCount, facetCount);\n const maxNCols = Math.min(facetSettings.nCols ?? facetCount, facetCount);\n // Use columns/rows count from settings if some of them defined, else make 1 column\n this.columnsCount = facetSettings.nRows ? Math.ceil(facetCount / maxNRows) : maxNCols;\n this.rowsCount = Math.ceil(facetCount / this.columnsCount);\n const { sharedX, sharedY } = facetSettings;\n\n this.chartsDimensions = {};\n\n let currentLeft = 0;\n let currentTop = 0;\n facetKeys.forEach((key, index) => {\n const currentColumn = (index % this.columnsCount) + 1;\n const chartSides = getChartEdgeSides(index, facetKeys.length, this.columnsCount, this.rowsCount);\n const stepX = this.step.x[key];\n const stepY = this.step.y[key];\n const sideElementSizes = calculateChartSideElementSizes(\n xAxis,\n yAxis,\n this.captionsSizes,\n annotations,\n dendrogramX,\n dendrogramY,\n chartSides,\n sharedX,\n sharedY,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n stepX,\n stepY\n );\n const annotationsTitleSizes = calculateAnnotationTitleSizes(annotations, chartSides, sharedX, sharedY);\n function getPadding(side: 'left' | 'right' | 'top' | 'bottom') {\n return Math.max(\n CHART_SIDE_ELEMENTS[side].reduce((res, el) => res + sideElementSizes[side][el], 0),\n annotationsTitleSizes[side],\n size.innerOffset\n );\n }\n const padding = {\n left: getPadding('left'),\n right: getPadding('right'),\n top: getPadding('top'),\n bottom: getPadding('bottom'),\n };\n if (padding.left < this.captionsSizes.xCaptionTail) {\n padding.left = this.captionsSizes.xCaptionTail;\n }\n if (padding.bottom < this.captionsSizes.yCaptionTail) {\n padding.bottom = this.captionsSizes.yCaptionTail;\n }\n const sideElementBBoxes = calculateSideElementsBBoxes(sideElementSizes, this.chartSizes.chartWidth, this.chartSizes.chartHeight);\n const outerWidth = this.chartSizes.chartWidth + padding.left + padding.right;\n const outerHeight = this.chartSizes.chartHeight + padding.top + padding.bottom;\n this.chartsDimensions[key] = {\n left: currentLeft,\n top: currentTop,\n inner: { width: this.chartSizes.chartWidth, height: this.chartSizes.chartHeight },\n outer: { width: outerWidth, height: outerHeight },\n padding,\n sideElementBBoxes,\n chartEdgeSides: chartSides,\n };\n currentLeft += outerWidth;\n if (currentColumn === this.columnsCount) {\n currentLeft = 0;\n currentTop += outerHeight;\n }\n });\n\n // sum of widths of first row\n const chartsWidth = facetKeys\n .slice(0, this.columnsCount)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.width, 0);\n // sum of heights of first column\n const chartsHeight = facetKeys\n .filter((_key, index) => index % this.columnsCount === 0)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.height, 0);\n this.chartSizes.chartsWidth = chartsWidth;\n this.chartSizes.chartsHeight = chartsHeight;\n }\n\n updateChartsSizes(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const firstFacet = groupedCells.meta.facetKeys[0];\n if (cellWidth && firstFacet) {\n const keysCount = groupedCells.facets[firstFacet].xKeys.length;\n const nonEmptyXGroupsCount = groupedCells.meta.xGroupKeys.filter(\n k => (groupedCells.facets[firstFacet]?.xKeysByGroups[k]?.length ?? 0) > 0\n ).length;\n this.chartSizes.chartWidth = keysCount * cellWidth + groupGap * (nonEmptyXGroupsCount - 1);\n } else {\n this.chartSizes.chartWidth = width;\n }\n\n if (cellHeight && firstFacet) {\n const keysCount = groupedCells.facets[firstFacet].yKeys.length;\n const nonEmptyYGroupsCount = groupedCells.meta.yGroupKeys.filter(\n k => (groupedCells.facets[firstFacet]?.yKeysByGroups[k]?.length ?? 0) > 0\n ).length;\n this.chartSizes.chartHeight = keysCount * cellHeight + groupGap * (nonEmptyYGroupsCount - 1);\n } else {\n this.chartSizes.chartHeight = height;\n }\n }\n\n // update scales for cell positions, x and y for each facet.\n // Keys arrive pre-sorted from fillCellsData (and re-ordered by getDendrograms for clustered axes).\n updateScales(\n facetKeys: string[],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n size: HeatmapSettingsImpl['chartSettings']['size'],\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const { meta, facets } = groupedCells;\n const { sharedX, sharedY } = facetSettings;\n // All sorting is done upstream in fillCellsData; keys arrive already ordered.\n facetKeys.forEach(facetKey => {\n const facetGroup = facets[facetKey];\n const xGroupKeys = meta.xGroupKeys;\n const yGroupKeys = meta.yGroupKeys;\n const { xKeysByGroups } = sharedX ? meta : facetGroup;\n const { yKeysByGroups } = sharedY ? meta : facetGroup;\n // for shared facets max cells counts in group should be used\n const xCounts = xGroupKeys.map(xGroupKey => xKeysByGroups[xGroupKey].length);\n const yCounts = yGroupKeys.map(yGroupKey => yKeysByGroups[yGroupKey].length);\n const xCellsCount = xCounts.reduce((sum, count) => sum + count, 0);\n const yCellsCount = yCounts.reduce((sum, count) => sum + count, 0);\n const xStep = cellWidth ? cellWidth : (width - (xCounts.filter(count => count > 0).length - 1) * groupGap) / xCellsCount;\n const yStep = cellHeight ? cellHeight : (height - (yCounts.filter(count => count > 0).length - 1) * groupGap) / yCellsCount;\n\n const xPositions: number[] = [];\n let xKeys: string[] = [];\n let currentX = 0;\n const resolvedXGroups = xGroupKeys.map(xKey => xKeysByGroups[xKey]);\n resolvedXGroups.forEach((axisKeys, idx) => {\n xKeys = xKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n xPositions.push(currentX);\n currentX += xStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedXGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentX += groupGap;\n }\n });\n\n const yPositions: number[] = [];\n let yKeys: string[] = [];\n let currentY = 0;\n const resolvedYGroups = yGroupKeys.map(yKey => yKeysByGroups[yKey]);\n resolvedYGroups.forEach((axisKeys, idx) => {\n yKeys = yKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n yPositions.push(currentY);\n currentY += yStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedYGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentY += groupGap;\n }\n });\n\n this.scales.x[facetKey] = scaleOrdinal<string, number>().domain(xKeys).range(xPositions);\n this.scales.y[facetKey] = scaleOrdinal<string, number>().domain(yKeys).range(yPositions);\n this.step.x[facetKey] = xStep;\n this.step.y[facetKey] = yStep;\n });\n }\n\n updateAesScale(\n valueType: 'discrete' | 'continuous',\n valueExtent: [number, number],\n aes: HeatmapSettingsImpl['aes'],\n annotations: HeatmapSettingsImpl['annotations'],\n groupedCellsData: GroupedCellsHeatmap,\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization']\n ) {\n if (valueType === 'continuous') {\n if (aes.valueColors) {\n this.colorScale = scaleLinear<string, string>()\n .domain(aes.valuesByColors ?? getContinuousColorRange(normalization, aes.valueColors.length, valueExtent))\n .range(aes.valueColors);\n } else if (aes.colorsList) {\n this.colorScale = scaleLinear<string, string>()\n .domain(getContinuousColorRange(normalization, aes.colorsList.length, valueExtent))\n .range(aes.colorsList);\n }\n } else {\n if (aes.colorsMap) {\n const valueKeys = Object.entries(aes.colorsMap);\n this.colorScale = scaleOrdinal<string, string>()\n .domain(valueKeys.map(v => v[0]))\n .range(valueKeys.map(v => v[1]))\n .unknown('#ccc');\n } else if (aes.colorsList) {\n this.colorScale = createDiscreteColorScale(aes.colorsList, cellUniqValues.map(String));\n }\n }\n\n const { xDataByKeys, yDataByKeys } = groupedCellsData.meta;\n annotations.forEach(item => {\n const { colors, type, axis, valueColumn } = item;\n const data = (axis === 'x' ? xDataByKeys : yDataByKeys)[valueColumn.valueLabels ?? valueColumn.value];\n if (type === 'discrete') {\n const discreteValues = lodash.uniq(Object.values(data).map(String)).sort();\n this.annotationColorScales[item.id] = {\n type: 'discrete',\n scale: createDiscreteRoundColorScale(colors, discreteValues),\n };\n } else {\n const values = Object.values(data).map(Number);\n if (!values.length) {\n return;\n }\n const [min = values[0], max = values[0]] = extent(values);\n this.annotationColorScales[item.id] = {\n type: 'continuous',\n scale: createContinuousColorScale(colors, min, max, 0, 0.5, 1),\n };\n }\n });\n }\n\n updateDendrogram(\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n groups: GroupedCellsHeatmap['facets'],\n dendrogramsData: DendrogramsData,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n facetKeys.forEach(facetKey => {\n this.dendrograms[facetKey] = { x: { treesByGroupKey: {}, data: dendrogramX }, y: { treesByGroupKey: {}, data: dendrogramY } };\n const { xKeysByGroups, yKeysByGroups } = groups[facetKey];\n if (dendrogramX) {\n const { hierarchyByGroupX } = dendrogramsData[facetKey];\n const maxHeightX = xGroupKeys.reduce((res, xKey) => Math.max(res, hierarchyByGroupX[xKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].x.treesByGroupKey = xGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupX[groupKey];\n if (!hierarchy) return res;\n const xKeys = xKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.x[facetKey], dendrogramX.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramX.position === 'top' ? [0, maxHeightX] : [maxHeightX, 0])\n .range([dendrogramX.size, 0]);\n updateLinksHeight(root, heightScale, 'y');\n addShiftToLinkCoord(root, this.scales.x[facetKey](xKeys[0]), 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].x.data = dendrogramX;\n }\n if (dendrogramY) {\n const { hierarchyByGroupY } = dendrogramsData[facetKey];\n const maxHeightY = yGroupKeys.reduce((res, yKey) => Math.max(res, hierarchyByGroupY[yKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].y.treesByGroupKey = yGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupY[groupKey];\n if (!hierarchy) return res;\n const yKeys = yKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.y[facetKey], dendrogramY.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramY.position === 'left' ? [0, maxHeightY] : [maxHeightY, 0])\n .range([dendrogramY.size, 0]);\n addShiftToLinkCoord(root, this.scales.y[facetKey](yKeys[0]), 'x', 'y');\n updateLinksHeight(root, heightScale, 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].y.data = dendrogramY;\n }\n });\n }\n\n updateDendrogramAesScales(inheritedAes: HeatmapSettingsImpl['inheritedDendrogramAes']) {\n if (!inheritedAes) {\n return;\n }\n const usedColumns = Object.keys(inheritedAes);\n this.dendrogramAesScales = usedColumns.reduce((res: DendrogramAesScales, columnName) => {\n const aesMap = inheritedAes[columnName];\n const columnValues: string[] = Object.keys(aesMap);\n res[columnName] = scaleOrdinal<string, AesItem, AesItem>()\n .domain(columnValues)\n .range(\n columnValues.map(value => ({\n ...DEFAULT_AES,\n ...aesMap[value],\n }))\n )\n .unknown(DEFAULT_AES);\n return res;\n }, {});\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: HeatmapSettingsImpl['chartSettings'],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n aes: HeatmapSettingsImpl['aes'],\n groupedCellsData: GroupedCellsHeatmap,\n annotations: HeatmapSettingsImpl['annotations'],\n valueColumn: ColumnName,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY'],\n dendrogramsData: DendrogramsData,\n inheritedDendrogramAes: HeatmapSettingsImpl['inheritedDendrogramAes'],\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization'],\n onTooltipHintSwitch: (v: boolean) => void,\n cellsRenderingMode: 'canvas' | 'svg'\n ) {\n const { meta, facets } = groupedCellsData;\n const { facetKeys, xGroupKeys, yGroupKeys, valueExtent } = meta;\n const { xAxis, yAxis, title, size, valueType } = chartSettings;\n this.updateChartsSizes(size, groupedCellsData, aes.groupGap);\n this.updateAesScale(valueType, valueExtent.dataSource, aes, annotations, groupedCellsData, cellUniqValues, normalization);\n this.updateScales(facetKeys, groupedCellsData, aes.groupGap, facetSettings, size);\n // caption sizes are needed for chart paddings in chart dimensions\n this.updateCaptionsSize(groupedCellsData, xAxis, yAxis, facetSettings);\n this.updateChartDimensions(\n size,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n facetSettings,\n xAxis,\n yAxis,\n annotations,\n dendrogramX,\n dendrogramY\n );\n this.updateLegendSize(valueType, chartSettings.legend, annotations, valueColumn, valueExtent.dataSource);\n this.updateMargins(title, size);\n this.updateDendrogram(facetKeys, xGroupKeys, yGroupKeys, facets, dendrogramsData, dendrogramX, dendrogramY);\n this.updateDendrogramAesScales(inheritedDendrogramAes);\n const component = (\n <DataFrameProvider dataFrame={dataFrame}>\n <ChartsGroup\n aes={aes}\n annotations={annotations}\n annotationColorScales={this.annotationColorScales}\n captionsSizes={this.captionsSizes}\n cellsMeta={meta}\n columnsCount={this.columnsCount}\n chartsDimensions={this.chartsDimensions}\n chartSettings={chartSettings}\n chartSizes={this.chartSizes}\n colorScale={this.colorScale as (v: unknown) => string}\n dendrogramAesScales={this.dendrogramAesScales}\n dendrograms={this.dendrograms}\n facetKeys={facetKeys}\n facetSettings={facetSettings}\n groupedCells={facets}\n labelAngles={this.labelAngles}\n legend={this.legend}\n margins={this.margins}\n scales={this.scales}\n settingsId={settingsId}\n step={this.step}\n xGroupKeys={xGroupKeys}\n yGroupKeys={yGroupKeys}\n onTooltipHintSwitch={onTooltipHintSwitch}\n cellsRenderingMode={cellsRenderingMode}\n />\n </DataFrameProvider>\n );\n this.component = component;\n this.reactRoot?.render(component);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/heatmap/ChartRenderer.tsx"],"sourcesContent":["import { extent } from 'd3-array';\nimport type { HierarchyNode, HierarchyPointNode } from 'd3-hierarchy';\nimport { cluster } from 'd3-hierarchy';\nimport type { ScaleLinear, ScaleOrdinal } from 'd3-scale';\nimport { scaleLinear, scaleOrdinal } from 'd3-scale';\nimport lodash from 'lodash';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\nimport { Error } from '../common/Error';\nimport type { LegendData, LegendItem } from '../common/types';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport { DEFAULT_HEIGHT, DEFAULT_WIDTH, MAX_LEGEND_GRADIENT_HEIGHT, MIN_LEGEND_GRADIENT_HEIGHT, TITLE_LINE_HEIGHT, TITLE_MARGIN } from '../constants';\nimport type { DataFrame } from '../DataFrame';\nimport type { AesItem, ColumnName, DataValue } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { computeChartInnerSize } from '../utils/computeChartInnerSize';\nimport { getChartEdgeSides } from '../utils/getChartEdgeSides';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type {\n AnnotationColorScales,\n CaptionsSizes,\n ChartDendrograms,\n ChartDimensionsData,\n ChartSizes,\n ChartsScales,\n Cluster,\n DendrogramAesScales,\n LabelAngles,\n Margins,\n} from './components/types';\nimport { CHART_SIDE_ELEMENTS, DEFAULT_AES, LEGEND_OFFSET, MIN_MARGIN, TITLE_LINE } from './constants';\nimport type { GroupedCellsHeatmap } from './getCells';\nimport type { DendrogramsData } from './getDendrograms';\nimport type { HeatmapSettingsImpl } from './HeatmapSettingsImpl';\nimport {\n calculateAnnotationTitleSizes,\n calculateChartSideElementSizes,\n calculateSideElementsBBoxes,\n createContinuousColorScale,\n createDiscreteColorScale,\n createDiscreteRoundColorScale,\n} from './utils';\nimport { calculateCaptionTails } from './utils/calculateCaptionTails';\n\nconst COS_PI_4 = Math.cos(Math.PI / 4);\nconst INCLINE_OFFSET = 5; // height of little triangle of text for captions inclined 45deg\nfunction updateLinksHeight(root: HierarchyPointNode<Cluster>, scale: (v: number) => number, coord: 'x' | 'y') {\n function setHeight(d: HierarchyPointNode<Cluster>) {\n d[coord] = scale(d.data.height);\n if (d.children) d.children.forEach(setHeight);\n }\n setHeight(root);\n}\n\n// add shift to move nodes positions with group gaps\nfunction addShiftToLinkCoord(\n root: HierarchyPointNode<Cluster>,\n shift: number,\n coordFrom: 'x' | 'y',\n coordTo = coordFrom\n) {\n function setX(d: HierarchyPointNode<Cluster>) {\n d[coordTo] = d[coordFrom] + shift;\n if (d.children) d.children.forEach(setX);\n }\n setX(root);\n}\n\nconst getSteps = (count: number, valueExtent: number[]) => {\n const min = Math.min(...valueExtent);\n const max = Math.max(...valueExtent);\n if (min === max) {\n const steps = count % 2 === 0 ? [] : [min];\n for (let i = 1; i < count / 2 + 1; i++) {\n steps.push(min + i);\n steps.unshift(min - i);\n }\n return steps;\n }\n if (count < 2) {\n return [min, max];\n }\n const step = (max - min) / (count - 1);\n const steps = [];\n for (let i = 0; i < count - 1; i++) {\n steps.push(min + step * i);\n }\n steps.push(max);\n return steps;\n};\n\nfunction getContinuousColorRange(normalization: HeatmapSettingsImpl['normalization'], colorsCount: number, valueExtent: number[]) {\n let extent = valueExtent;\n if (normalization) {\n if (normalization.colorRange) {\n extent = normalization.colorRange;\n }\n if (normalization.method === 'standardScaling') {\n extent = [-2, 2];\n }\n if (normalization.method === 'meanNormalization') {\n extent = [-0.75, 0.75];\n }\n }\n return getSteps(colorsCount, extent);\n}\n\nfunction getMaxTextLength(keys: string[], labels: Record<string, string>, textMeasurer: TextMeasurer) {\n let maxLabelSize = 0;\n for (const key of keys) {\n if (labels[key] === undefined) continue;\n const l = textMeasurer.getTextWidth(labels[key]);\n if (l > maxLabelSize) maxLabelSize = l;\n }\n return maxLabelSize;\n}\n\nfunction getCaptionHeight(size: number, angle: number) {\n if (angle === 90) {\n return size;\n }\n if (angle === 45) {\n return size * COS_PI_4 + (size > 0 ? 2 * INCLINE_OFFSET : 0);\n }\n return TITLE_LINE;\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = (<></>);\n chartsDimensions: Record<string, ChartDimensionsData> = {};\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\n chartsWidth: DEFAULT_WIDTH, // width of all charts in charts row\n chartsHeight: DEFAULT_HEIGHT, // width of all charts in charts column, without axes\n totalWidth: DEFAULT_WIDTH, // width of all charts in charts row, plus left axis, plus legend\n totalHeight: DEFAULT_HEIGHT, // width of all charts in charts height, plus bottom axis, plus top title\n };\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n captionsSizes: CaptionsSizes = {\n xAxisCaptions: 100,\n yAxisCaptions: 100,\n xGroupCaptions: TITLE_LINE,\n yGroupCaptions: TITLE_LINE,\n xCaptionTail: 0,\n yCaptionTail: 0,\n };\n labelAngles: LabelAngles = {\n xAxisLabels: 0,\n yAxisLabels: 0,\n xGroupLabels: 0,\n yGroupLabels: 0,\n };\n columnsCount = 1;\n rowsCount = 1;\n scales: ChartsScales = {\n // scales grouped by facet\n x: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n y: { null: scaleOrdinal<string, number>().domain(['null']).range([1]) },\n };\n step: {\n x: Record<string, number>;\n y: Record<string, number>;\n } = { x: {}, y: {} };\n colorScale: ScaleLinear<string, string> | ScaleOrdinal<string, string, string> = scaleLinear<string, string>()\n .domain([0, 1])\n .range(['white', 'black']);\n annotationColorScales: AnnotationColorScales = {};\n dendrogramAesScales: DendrogramAesScales = {};\n legend: LegendData = {\n width: 0,\n height: 0,\n items: [],\n };\n dendrograms: Record<string, ChartDendrograms> = {};\n\n clear() {\n if (this.parentNode && this.rootNode) {\n this.parentNode?.removeChild(this.rootNode);\n this.parentNode = null;\n this.rootNode = null;\n }\n // timeout to avoid trying to unmount during rendering\n setTimeout(() => {\n this.reactRoot?.unmount();\n this.reactRoot = null;\n });\n }\n\n init(node: HTMLElement) {\n if (this.parentNode === null) {\n this.parentNode = node;\n this.rootNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateMargins(title: HeatmapSettingsImpl['chartSettings']['title'], size: HeatmapSettingsImpl['chartSettings']['size']) {\n this.margins = {\n top: title.show ? TITLE_LINE_HEIGHT + TITLE_MARGIN * 2 : size.outerOffset,\n bottom: size.outerOffset,\n left: size.outerOffset,\n right: this.legend.width + size.outerOffset,\n };\n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartsHeight + this.margins.bottom, this.legend.height);\n }\n\n updateLegendSize(\n valueType: HeatmapSettingsImpl['chartSettings']['valueType'],\n legend: HeatmapSettingsImpl['chartSettings']['legend'],\n annotations: HeatmapSettingsImpl['annotations'],\n columnValue: ColumnName,\n valueExtent: [number, number]\n ) {\n if (!legend.show) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n const continuousHeight = Math.min(\n Math.max(this.chartSizes.chartHeight, MIN_LEGEND_GRADIENT_HEIGHT),\n MAX_LEGEND_GRADIENT_HEIGHT\n );\n const legendHeight = Math.max(this.chartSizes.chartHeight, continuousHeight);\n const legendItems: LegendItem[] = [];\n const emptySizes = { width: 0, height: 0, left: 0, top: 0 };\n\n const getDefaultLabels = (values: (string | number)[]) => values.reduce((res: Record<string, string>, v: string | number) => { res[v] = String(v); return res; }, {});\n if (valueType === 'continuous') {\n const scale = this.colorScale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n const title = columnValue.label ?? columnValue.value;\n legendItems.push({\n ...emptySizes,\n type: 'continuous',\n id: 'heatmapValue',\n scale,\n values,\n title,\n tickPositionScale\n });\n } else if (valueType === 'discrete') {\n const scale = this.colorScale as ScaleOrdinal<string, string>;\n const title = columnValue.label ?? columnValue.value;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: 'heatmapValue', title, scale, values, labels });\n }\n annotations.forEach(item => {\n const title = item.valueColumn.label ?? item.valueColumn.value;\n if (item.type === 'continuous') {\n const scale = this.annotationColorScales[item.id].scale as ScaleLinear<string, string>;\n const values = getContinuousLegendTicks(scale, valueExtent);\n const tickPositionScale = scaleLinear([values[0], values[values.length - 1]], [continuousHeight, 0]); //TODO: update during adding log scale for heatmap\n\n legendItems.push({ ...emptySizes, type: 'continuous', id: item.id, tickPositionScale, title, scale, values });\n }\n if (item.type === 'discrete') {\n const scale = this.annotationColorScales[item.id].scale as ScaleOrdinal<string, string>;\n const values = scale.domain();\n const labels = getDefaultLabels(values);\n\n legendItems.push({ ...emptySizes, type: 'discreteColor', id: item.id, title, scale, values, labels });\n }\n });\n\n if (!legendItems.length) {\n this.legend = { width: 0, height: 0, items: [] };\n return;\n }\n\n const items = arrangeLegendParts(legendItems, this.chartSizes.chartHeight,continuousHeight);\n const maxRightEdge = items.reduce((max, item) => Math.max(max, item.left + item.width), 0);\n\n const legendWidth = maxRightEdge + LEGEND_OFFSET;\n\n this.legend = {\n width: legendWidth,\n height: legendHeight,\n items\n };\n }\n\n updateCaptionsSize(\n groupedCells: GroupedCellsHeatmap,\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n facetSettings: HeatmapSettingsImpl['facetSettings']\n ) {\n const textMeasurer = new TextMeasurer('bold 16px Manrope');\n const { xGroupKeys, yGroupKeys, xGroupLabels, yGroupLabels, xKeysByGroups, yKeysByGroups, xLabels, yLabels } = groupedCells.meta;\n this.labelAngles = {\n xAxisLabels: xAxis.axisLabelsAngle,\n yAxisLabels: yAxis.axisLabelsAngle,\n xGroupLabels: xAxis.groupLabelsAngle,\n yGroupLabels: yAxis.groupLabelsAngle,\n };\n\n const maxXLabelSize = xGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(xKeysByGroups[key], xLabels, textMeasurer)), 0);\n const maxYLabelSize = yGroupKeys.reduce((res, key) => Math.max(res, getMaxTextLength(yKeysByGroups[key], yLabels, textMeasurer)), 0);\n const maxXGroupLabelSize = getMaxTextLength(xGroupKeys, xGroupLabels, textMeasurer);\n const maxYGroupLabelSize = getMaxTextLength(yGroupKeys, yGroupLabels, textMeasurer);\n const { xCaptionTail, yCaptionTail } = calculateCaptionTails(\n this.labelAngles,\n facetSettings,\n this.scales,\n this.step,\n groupedCells,\n textMeasurer\n );\n this.captionsSizes = {\n xCaptionTail,\n yCaptionTail,\n xGroupCaptions: getCaptionHeight(maxXGroupLabelSize, this.labelAngles.xGroupLabels),\n yGroupCaptions: getCaptionHeight(maxYGroupLabelSize, this.labelAngles.yGroupLabels),\n xAxisCaptions: getCaptionHeight(maxXLabelSize, this.labelAngles.xAxisLabels),\n yAxisCaptions: getCaptionHeight(maxYLabelSize, this.labelAngles.yAxisLabels),\n };\n }\n\n updateChartDimensions(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n xAxis: HeatmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: HeatmapSettingsImpl['chartSettings']['yAxis'],\n annotations: HeatmapSettingsImpl['annotations'],\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n const facetCount = facetKeys.length;\n const maxNRows = Math.min(facetSettings.nRows ?? facetCount, facetCount);\n const maxNCols = Math.min(facetSettings.nCols ?? facetCount, facetCount);\n // Use columns/rows count from settings if some of them defined, else make 1 column\n this.columnsCount = facetSettings.nRows ? Math.ceil(facetCount / maxNRows) : maxNCols;\n this.rowsCount = Math.ceil(facetCount / this.columnsCount);\n const { sharedX, sharedY } = facetSettings;\n\n this.chartsDimensions = {};\n\n let currentLeft = 0;\n let currentTop = 0;\n facetKeys.forEach((key, index) => {\n const currentColumn = (index % this.columnsCount) + 1;\n const chartSides = getChartEdgeSides(index, facetKeys.length, this.columnsCount, this.rowsCount);\n const stepX = this.step.x[key];\n const stepY = this.step.y[key];\n const sideElementSizes = calculateChartSideElementSizes(\n xAxis,\n yAxis,\n this.captionsSizes,\n annotations,\n dendrogramX,\n dendrogramY,\n chartSides,\n sharedX,\n sharedY,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n stepX,\n stepY\n );\n const annotationsTitleSizes = calculateAnnotationTitleSizes(annotations, chartSides, sharedX, sharedY);\n function getPadding(side: 'left' | 'right' | 'top' | 'bottom') {\n return Math.max(\n CHART_SIDE_ELEMENTS[side].reduce((res, el) => res + sideElementSizes[side][el], 0),\n annotationsTitleSizes[side],\n size.innerOffset\n );\n }\n const padding = {\n left: getPadding('left'),\n right: getPadding('right'),\n top: getPadding('top'),\n bottom: getPadding('bottom'),\n };\n if (padding.left < this.captionsSizes.xCaptionTail) {\n padding.left = this.captionsSizes.xCaptionTail;\n }\n if (padding.bottom < this.captionsSizes.yCaptionTail) {\n padding.bottom = this.captionsSizes.yCaptionTail;\n }\n const sideElementBBoxes = calculateSideElementsBBoxes(sideElementSizes, this.chartSizes.chartWidth, this.chartSizes.chartHeight);\n const outerWidth = this.chartSizes.chartWidth + padding.left + padding.right;\n const outerHeight = this.chartSizes.chartHeight + padding.top + padding.bottom;\n this.chartsDimensions[key] = {\n left: currentLeft,\n top: currentTop,\n inner: { width: this.chartSizes.chartWidth, height: this.chartSizes.chartHeight },\n outer: { width: outerWidth, height: outerHeight },\n padding,\n sideElementBBoxes,\n chartEdgeSides: chartSides,\n };\n currentLeft += outerWidth;\n if (currentColumn === this.columnsCount) {\n currentLeft = 0;\n currentTop += outerHeight;\n }\n });\n\n // sum of widths of first row\n const chartsWidth = facetKeys\n .slice(0, this.columnsCount)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.width, 0);\n // sum of heights of first column\n const chartsHeight = facetKeys\n .filter((_key, index) => index % this.columnsCount === 0)\n .reduce((sum, key) => sum + this.chartsDimensions[key].outer.height, 0);\n this.chartSizes.chartsWidth = chartsWidth;\n this.chartSizes.chartsHeight = chartsHeight;\n }\n\n updateChartsSizes(\n size: HeatmapSettingsImpl['chartSettings']['size'],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n ) {\n const { chartWidth, chartHeight } = computeChartInnerSize(size, groupedCells.meta, groupGap);\n this.chartSizes.chartWidth = chartWidth;\n this.chartSizes.chartHeight = chartHeight;\n }\n\n // update scales for cell positions, x and y for each facet.\n // Keys arrive pre-sorted from fillCellsData (and re-ordered by getDendrograms for clustered axes).\n updateScales(\n facetKeys: string[],\n groupedCells: GroupedCellsHeatmap,\n groupGap: number,\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n size: HeatmapSettingsImpl['chartSettings']['size'],\n ) {\n const { width, height, cellWidth, cellHeight } = size;\n const { meta, facets } = groupedCells;\n const { sharedX, sharedY } = facetSettings;\n // All sorting is done upstream in fillCellsData; keys arrive already ordered.\n facetKeys.forEach(facetKey => {\n const facetGroup = facets[facetKey];\n const xGroupKeys = meta.xGroupKeys;\n const yGroupKeys = meta.yGroupKeys;\n const { xKeysByGroups } = sharedX ? meta : facetGroup;\n const { yKeysByGroups } = sharedY ? meta : facetGroup;\n // for shared facets max cells counts in group should be used\n const xCounts = xGroupKeys.map(xGroupKey => xKeysByGroups[xGroupKey].length);\n const yCounts = yGroupKeys.map(yGroupKey => yKeysByGroups[yGroupKey].length);\n const xCellsCount = xCounts.reduce((sum, count) => sum + count, 0);\n const yCellsCount = yCounts.reduce((sum, count) => sum + count, 0);\n const xStep = cellWidth ? cellWidth : (width - (xCounts.filter(count => count > 0).length - 1) * groupGap) / xCellsCount;\n const yStep = cellHeight ? cellHeight : (height - (yCounts.filter(count => count > 0).length - 1) * groupGap) / yCellsCount;\n\n const xPositions: number[] = [];\n let xKeys: string[] = [];\n let currentX = 0;\n const resolvedXGroups = xGroupKeys.map(xKey => xKeysByGroups[xKey]);\n resolvedXGroups.forEach((axisKeys, idx) => {\n xKeys = xKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n xPositions.push(currentX);\n currentX += xStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedXGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentX += groupGap;\n }\n });\n\n const yPositions: number[] = [];\n let yKeys: string[] = [];\n let currentY = 0;\n const resolvedYGroups = yGroupKeys.map(yKey => yKeysByGroups[yKey]);\n resolvedYGroups.forEach((axisKeys, idx) => {\n yKeys = yKeys.concat(axisKeys);\n axisKeys.forEach(() => {\n yPositions.push(currentY);\n currentY += yStep;\n });\n // add gap only if a non-empty group follows (skip trailing gap after last visible group)\n const hasMoreNonEmpty = resolvedYGroups.slice(idx + 1).some(keys => keys.length > 0);\n if (axisKeys.length > 0 && hasMoreNonEmpty) {\n currentY += groupGap;\n }\n });\n\n this.scales.x[facetKey] = scaleOrdinal<string, number>().domain(xKeys).range(xPositions);\n this.scales.y[facetKey] = scaleOrdinal<string, number>().domain(yKeys).range(yPositions);\n this.step.x[facetKey] = xStep;\n this.step.y[facetKey] = yStep;\n });\n }\n\n updateAesScale(\n valueType: 'discrete' | 'continuous',\n valueExtent: [number, number],\n aes: HeatmapSettingsImpl['aes'],\n annotations: HeatmapSettingsImpl['annotations'],\n groupedCellsData: GroupedCellsHeatmap,\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization']\n ) {\n if (valueType === 'continuous') {\n if (aes.valueColors) {\n this.colorScale = scaleLinear<string, string>()\n .domain(aes.valuesByColors ?? getContinuousColorRange(normalization, aes.valueColors.length, valueExtent))\n .range(aes.valueColors);\n } else if (aes.colorsList) {\n this.colorScale = scaleLinear<string, string>()\n .domain(getContinuousColorRange(normalization, aes.colorsList.length, valueExtent))\n .range(aes.colorsList);\n }\n } else {\n if (aes.colorsMap) {\n const valueKeys = Object.entries(aes.colorsMap);\n this.colorScale = scaleOrdinal<string, string>()\n .domain(valueKeys.map(v => v[0]))\n .range(valueKeys.map(v => v[1]))\n .unknown('#ccc');\n } else if (aes.colorsList) {\n this.colorScale = createDiscreteColorScale(aes.colorsList, cellUniqValues.map(String));\n }\n }\n\n const { xDataByKeys, yDataByKeys } = groupedCellsData.meta;\n annotations.forEach(item => {\n const { colors, type, axis, valueColumn } = item;\n const data = (axis === 'x' ? xDataByKeys : yDataByKeys)[valueColumn.valueLabels ?? valueColumn.value];\n if (type === 'discrete') {\n const discreteValues = lodash.uniq(Object.values(data).map(String)).sort();\n this.annotationColorScales[item.id] = {\n type: 'discrete',\n scale: createDiscreteRoundColorScale(colors, discreteValues),\n };\n } else {\n const values = Object.values(data).map(Number);\n if (!values.length) {\n return;\n }\n const [min = values[0], max = values[0]] = extent(values);\n this.annotationColorScales[item.id] = {\n type: 'continuous',\n scale: createContinuousColorScale(colors, min, max, 0, 0.5, 1),\n };\n }\n });\n }\n\n updateDendrogram(\n facetKeys: string[],\n xGroupKeys: string[],\n yGroupKeys: string[],\n groups: GroupedCellsHeatmap['facets'],\n dendrogramsData: DendrogramsData,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY']\n ) {\n facetKeys.forEach(facetKey => {\n this.dendrograms[facetKey] = { x: { treesByGroupKey: {}, data: dendrogramX }, y: { treesByGroupKey: {}, data: dendrogramY } };\n const { xKeysByGroups, yKeysByGroups } = groups[facetKey];\n if (dendrogramX) {\n const { hierarchyByGroupX } = dendrogramsData[facetKey];\n const maxHeightX = xGroupKeys.reduce((res, xKey) => Math.max(res, hierarchyByGroupX[xKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].x.treesByGroupKey = xGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupX[groupKey];\n if (!hierarchy) return res;\n const xKeys = xKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.x[facetKey], dendrogramX.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramX.position === 'top' ? [0, maxHeightX] : [maxHeightX, 0])\n .range([dendrogramX.size, 0]);\n updateLinksHeight(root, heightScale, 'y');\n addShiftToLinkCoord(root, this.scales.x[facetKey](xKeys[0]), 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].x.data = dendrogramX;\n }\n if (dendrogramY) {\n const { hierarchyByGroupY } = dendrogramsData[facetKey];\n const maxHeightY = yGroupKeys.reduce((res, yKey) => Math.max(res, hierarchyByGroupY[yKey]?.data.height ?? 0), 0);\n this.dendrograms[facetKey].y.treesByGroupKey = yGroupKeys.reduce((res, groupKey) => {\n const hierarchy = hierarchyByGroupY[groupKey];\n if (!hierarchy) return res;\n const yKeys = yKeysByGroups[groupKey];\n cluster()\n .separation(() => 1)\n .size([hierarchy.leaves().length * this.step.y[facetKey], dendrogramY.size])(\n hierarchy as HierarchyNode<unknown>\n );\n const root = hierarchy as HierarchyPointNode<Cluster>;\n const heightScale = scaleLinear()\n .domain(dendrogramY.position === 'left' ? [0, maxHeightY] : [maxHeightY, 0])\n .range([dendrogramY.size, 0]);\n addShiftToLinkCoord(root, this.scales.y[facetKey](yKeys[0]), 'x', 'y');\n updateLinksHeight(root, heightScale, 'x');\n res[groupKey] = root;\n return res;\n }, {} as Record<string, HierarchyPointNode<Cluster>>);\n this.dendrograms[facetKey].y.data = dendrogramY;\n }\n });\n }\n\n updateDendrogramAesScales(inheritedAes: HeatmapSettingsImpl['inheritedDendrogramAes']) {\n if (!inheritedAes) {\n return;\n }\n const usedColumns = Object.keys(inheritedAes);\n this.dendrogramAesScales = usedColumns.reduce((res: DendrogramAesScales, columnName) => {\n const aesMap = inheritedAes[columnName];\n const columnValues: string[] = Object.keys(aesMap);\n res[columnName] = scaleOrdinal<string, AesItem, AesItem>()\n .domain(columnValues)\n .range(\n columnValues.map(value => ({\n ...DEFAULT_AES,\n ...aesMap[value],\n }))\n )\n .unknown(DEFAULT_AES);\n return res;\n }, {});\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: HeatmapSettingsImpl['chartSettings'],\n facetSettings: HeatmapSettingsImpl['facetSettings'],\n aes: HeatmapSettingsImpl['aes'],\n groupedCellsData: GroupedCellsHeatmap,\n annotations: HeatmapSettingsImpl['annotations'],\n valueColumn: ColumnName,\n dendrogramX: HeatmapSettingsImpl['dendrogramX'],\n dendrogramY: HeatmapSettingsImpl['dendrogramY'],\n dendrogramsData: DendrogramsData,\n inheritedDendrogramAes: HeatmapSettingsImpl['inheritedDendrogramAes'],\n cellUniqValues: DataValue[],\n normalization: HeatmapSettingsImpl['normalization'],\n onTooltipHintSwitch: (v: boolean) => void,\n cellsRenderingMode: 'canvas' | 'svg'\n ) {\n const { meta, facets } = groupedCellsData;\n const { facetKeys, xGroupKeys, yGroupKeys, valueExtent } = meta;\n const { xAxis, yAxis, title, size, valueType } = chartSettings;\n this.updateChartsSizes(size, groupedCellsData, aes.groupGap);\n this.updateAesScale(valueType, valueExtent.dataSource, aes, annotations, groupedCellsData, cellUniqValues, normalization);\n this.updateScales(facetKeys, groupedCellsData, aes.groupGap, facetSettings, size);\n // caption sizes are needed for chart paddings in chart dimensions\n this.updateCaptionsSize(groupedCellsData, xAxis, yAxis, facetSettings);\n this.updateChartDimensions(\n size,\n facetKeys,\n xGroupKeys,\n yGroupKeys,\n facetSettings,\n xAxis,\n yAxis,\n annotations,\n dendrogramX,\n dendrogramY\n );\n this.updateLegendSize(valueType, chartSettings.legend, annotations, valueColumn, valueExtent.dataSource);\n this.updateMargins(title, size);\n this.updateDendrogram(facetKeys, xGroupKeys, yGroupKeys, facets, dendrogramsData, dendrogramX, dendrogramY);\n this.updateDendrogramAesScales(inheritedDendrogramAes);\n const component = (\n <DataFrameProvider dataFrame={dataFrame}>\n <ChartsGroup\n aes={aes}\n annotations={annotations}\n annotationColorScales={this.annotationColorScales}\n captionsSizes={this.captionsSizes}\n cellsMeta={meta}\n columnsCount={this.columnsCount}\n chartsDimensions={this.chartsDimensions}\n chartSettings={chartSettings}\n chartSizes={this.chartSizes}\n colorScale={this.colorScale as (v: unknown) => string}\n dendrogramAesScales={this.dendrogramAesScales}\n dendrograms={this.dendrograms}\n facetKeys={facetKeys}\n facetSettings={facetSettings}\n groupedCells={facets}\n labelAngles={this.labelAngles}\n legend={this.legend}\n margins={this.margins}\n scales={this.scales}\n settingsId={settingsId}\n step={this.step}\n xGroupKeys={xGroupKeys}\n yGroupKeys={yGroupKeys}\n onTooltipHintSwitch={onTooltipHintSwitch}\n cellsRenderingMode={cellsRenderingMode}\n />\n </DataFrameProvider>\n );\n this.component = component;\n this.reactRoot?.render(component);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartRenderer.d.ts","sourceRoot":"","sources":["../../src/scatterplot/ChartRenderer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,EAAc,UAAU,EAAc,MAAM,iBAAiB,CAAC;AAY1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAiC,UAAU,EAAc,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAQ7G,OAAO,KAAK,EAAc,aAAa,EAAE,mBAAmB,EAAe,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAiB,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAa1K,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAyB,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"ChartRenderer.d.ts","sourceRoot":"","sources":["../../src/scatterplot/ChartRenderer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -59,6 +59,7 @@ function j(e, t, r, i, a) {
|
|
|
59
59
|
lineShape: _(e, t, s?.aes.lineShape ?? "solid", "lineShape"),
|
|
60
60
|
lineColor: _(e, t, s?.aes.lineColor ?? "#110529", "lineColor"),
|
|
61
61
|
trendColor: _(e, t, i?.color ?? n.color, "fillColor"),
|
|
62
|
+
trendLineWidth: i?.lineWidth ?? 1,
|
|
62
63
|
additionalCurveLineColor: (a?.curves ?? []).map((n) => _(e, t, n.lineColor, "lineColor")),
|
|
63
64
|
additionalCurveTrendColor: (a?.curves ?? []).map((n) => _(e, t, n.trend?.color ?? n.lineColor, "lineColor"))
|
|
64
65
|
};
|
|
@@ -177,7 +178,7 @@ var F = class {
|
|
|
177
178
|
b[e] = i, C ||= E(o, i);
|
|
178
179
|
});
|
|
179
180
|
let T = e.reduce((e, t) => (e[t] = (c ? c[t] : []).reduce((e, n) => {
|
|
180
|
-
let r = n.bounded ? n.xBounds :
|
|
181
|
+
let r = n.bounded ? n.xBounds : b[t].domain(), i = n.getInterval(r[0]), a = n.getInterval(r[1]);
|
|
181
182
|
return e.minY = Math.min(e.minY, isNaN(i.left) ? e.minY : i.left, isNaN(a.left) ? e.minY : a.left), e.maxY = Math.max(e.maxY, isNaN(i.right) ? e.maxY : i.right, isNaN(a.right) ? e.maxY : a.right), e;
|
|
182
183
|
}, {
|
|
183
184
|
minY: Infinity,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/scatterplot/ChartRenderer.tsx"],"sourcesContent":["import type { ScaleLinear } from 'd3-scale';\nimport { scaleLinear, scaleLog, scaleOrdinal, scalePoint, scaleSymlog } from 'd3-scale';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\nimport { Error } from '../common/Error';\nimport type { DotAesItem, LegendData, LegendItem } from '../common/types';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport {\n BLACK,\n DEFAULT_HEIGHT,\n DEFAULT_WIDTH,\n MAX_LEGEND_GRADIENT_HEIGHT,\n MAX_SHOWN_UNIQUE_VALUES_IN_LABELS,\n MIN_LEGEND_GRADIENT_HEIGHT,\n TITLE_LINE_HEIGHT,\n TITLE_MARGIN,\n} from '../constants';\nimport type { DataFrame } from '../DataFrame';\nimport { FACET_TITLE_LINE } from '../discrete/constants';\nimport { splitTextByWidth } from '../discrete/utils';\nimport type { AesItem, AxisSettingsDiscrete, ColumnName, PointShape, ScatterplotLegendInfo } from '../types';\nimport { isContinuousAes } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { getSizeLegendItem } from '../utils/getSizeLegendItem';\nimport { getContinuousColorScale } from '../utils/getContinuousColorScale';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type { AesGetters, CaptionsSizes, ChartDimensionsData, ChartScales, ChartSizes, ChartsScales, DiscreteAxisData, DiscreteScale, Margins } from './components/types';\nimport {\n DEFAULT_DOT_AES,\n DEFAULT_TICKS_SIZE,\n FACET_AXIS_OFFSET,\n FACET_TITLE_OFFSET,\n LEGEND_OFFSET,\n MIN_MARGIN,\n MIN_PADDING,\n PADDINGS,\n TICK_OFFSET,\n TITLE_LINE,\n} from './constants';\nimport type { GroupedDots } from './dots';\nimport type { ScatterplotLayerData } from './getLayersData';\nimport type { TrendsData } from './linearRegression';\nimport type { CurveLayer, DotsLayer, ScatterplotLayer, ScatterplotSettingsImpl } from './ScatterplotSettingsImpl';\nimport { createAesGetter } from './utils/createAesGetter';\nimport { getTicksAndFormat } from './utils/getTicksAndFormat';\nimport { isContinuousAxis } from './utils/isNumericScale';\nimport { createMultilineDiscreteLabels } from '../utils/createMultilineDiscreteLabels';\nimport { measureMultilineDiscreteLabels } from '../utils/measureMultilineDiscreteLabels';\n\nfunction scalesAreDifferent(prevScale:ChartScales['x'|'y'], currentScale:ChartScales['x'|'y']):boolean {\n if (prevScale === undefined) {\n return true;\n } else {\n const domain = prevScale.domain();\n const range = prevScale.range();\n const newDomain = currentScale.domain();\n const newRange = currentScale.range();\n if (\n domain.length !== newDomain.length ||\n domain.some((v, idx) => v !== newDomain[idx]) ||\n range[0] !== newRange[0] || range[1] !== newRange[1]\n ) {\n return true;\n }\n }\n return false;\n}\nfunction getChartEdgeSides(index: number, facetsCount: number, columnsCount: number, rowsCount: number) {\n const chartSides: ('left' | 'right' | 'top' | 'bottom')[] = [];\n if (index % columnsCount === columnsCount - 1) {\n chartSides.push('right');\n }\n if (index % columnsCount === 0) {\n chartSides.push('left');\n }\n if (index < columnsCount) {\n chartSides.push('top');\n }\n if (\n Math.ceil((index + 1) / columnsCount) === rowsCount ||\n (Math.ceil((index + 1) / columnsCount) === rowsCount - 1 &&\n index % columnsCount > (facetsCount - 1) % columnsCount)\n ) {\n chartSides.push('bottom');\n }\n return chartSides;\n}\n\nfunction calculatePaddings(\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis'],\n captionsSizes: CaptionsSizes,\n currentRowFacetKeys: string[],\n facetTitles: Record<string, string[]>,\n chartEdgeSides: ('left' | 'right' | 'top' | 'bottom')[],\n currentRow: number,\n currentColumn: number,\n lastInRow: boolean,\n facetSettings?: ScatterplotSettingsImpl['facetSettings'],\n) {\n const discreteX = xAxis.scale === 'discrete';\n const discreteY = yAxis.scale === 'discrete';\n\n const needLeftAxis = chartEdgeSides.includes('left') || !facetSettings?.sharedY;\n const needLeftAxisTitle = chartEdgeSides.includes('left') && yAxis.title !== '';\n const needBottomAxis = chartEdgeSides.includes('bottom') || !facetSettings?.sharedX;\n const needBottomAxisTitle = chartEdgeSides.includes('bottom') && xAxis.title !== '';\n\n const yCaptions = yAxis.hiddenLabels ? 0 : discreteY ? captionsSizes.leftAxisCaptionsWidthByColumns[currentColumn] + 2 * TICK_OFFSET : captionsSizes.yAxisCaptionsWidth + 2 * TICK_OFFSET;\n const yTicks = (yAxis.showTicks ? DEFAULT_TICKS_SIZE : 0) + TICK_OFFSET;\n const yAxisTitle = needLeftAxisTitle ? TITLE_LINE : 0;\n\n const xCaptions = xAxis.hiddenLabels ? 0 : discreteX ? captionsSizes.bottomAxisCaptionsWidthByRows[currentRow] + 2 * TICK_OFFSET: captionsSizes.xAxisCaptionsWidth + 2 * TICK_OFFSET;\n const xTicks = xAxis.showTicks ? DEFAULT_TICKS_SIZE : 0;\n const xAxisTitle = needBottomAxisTitle ? TITLE_LINE : 0;\n\n const leftAxisElements = yCaptions + yTicks + yAxisTitle + FACET_AXIS_OFFSET;\n const bottomAxisElements = xCaptions + xTicks + xAxisTitle + FACET_AXIS_OFFSET;\n\n const facetTitlesLinesCount = Math.max(...currentRowFacetKeys.map(key => facetTitles[key].length));\n return {\n left: needLeftAxis ? leftAxisElements : MIN_PADDING,\n top: facetTitlesLinesCount === 0 ? 0 : FACET_TITLE_OFFSET * 2 + facetTitlesLinesCount * FACET_TITLE_LINE,\n bottom: needBottomAxis ? bottomAxisElements + 8 : MIN_PADDING,\n right: lastInRow ? 0 : MIN_PADDING,\n };\n}\n\n// facet keys grouped by rows\nfunction getFacetRows(facetKeys: string[], nRows: number, nColumns: number): string[][] {\n const result: string[][] = [];\n for (let i = 0; i < nRows; i++) {\n result.push(facetKeys.slice(i * nColumns, i * nColumns + nColumns));\n }\n return result;\n}\n\nfunction getRowColumn(idx: number, columnsCount: number) {\n const row = Math.floor(idx / columnsCount);\n const column = idx - row * columnsCount;\n return [row, column];\n}\n\nfunction createAesGetters(\n dataFrame: DataFrame,\n legendInfo: ScatterplotLegendInfo,\n layers: ScatterplotLayer[],\n trend: ScatterplotSettingsImpl['trend'],\n additionalCurves: ScatterplotSettingsImpl['additionalCurves']\n): AesGetters {\n const dotLayer = layers.find(l => l.type === 'dots') as DotsLayer | undefined;\n const curveLayer = layers.find(l => l.type === 'curve') as CurveLayer | undefined;\n\n return {\n dotShape: createAesGetter(dataFrame, legendInfo, dotLayer?.aes.dotShape ?? DEFAULT_DOT_AES.shape,'dotShape'),\n dotColor: createAesGetter(dataFrame, legendInfo, dotLayer?.aes.dotFill ?? DEFAULT_DOT_AES.color, 'dotFill'),\n dotSize: createAesGetter(dataFrame, legendInfo, dotLayer?.aes.dotSize ?? DEFAULT_DOT_AES.size, 'dotSize'),\n lineShape: createAesGetter(dataFrame, legendInfo, curveLayer?.aes.lineShape ?? 'solid', 'lineShape'),\n lineColor: createAesGetter(dataFrame, legendInfo, curveLayer?.aes.lineColor ?? BLACK, 'lineColor'),\n trendColor: createAesGetter(dataFrame, legendInfo, trend?.color ?? DEFAULT_DOT_AES.color, 'fillColor'),\n additionalCurveLineColor: (additionalCurves?.curves ?? []).map(\n (entry) => createAesGetter<string>(dataFrame, legendInfo, entry.lineColor, 'lineColor'),\n ),\n additionalCurveTrendColor: (additionalCurves?.curves ?? []).map(\n (entry) => createAesGetter<string>(dataFrame, legendInfo, entry.trend?.color ?? entry.lineColor, 'lineColor'),\n ),\n };\n}\n\nconst COS_PI_4 = Math.cos(Math.PI / 4);\nconst INCLINE_OFFSET = 5; // height of little triangle of text for captions inclined 45deg\n\nfunction getCaptionHeight (size: number, axis: ScatterplotSettingsImpl['chartSettings']['xAxis' | 'yAxis']) {\n if (axis.scale === 'discrete') {\n if (axis.labelsPosition === '90deg') {\n return size;\n }\n if (axis.labelsPosition === '45deg') {\n return size * COS_PI_4 + (size > 0 ? 2 * INCLINE_OFFSET : 0) ;\n }\n return TITLE_LINE;\n }\n return Math.max(size, TITLE_LINE);\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = (<></>);\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n chartsDimensions: Record<string, ChartDimensionsData> = {};\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\n chartsWidth: DEFAULT_WIDTH, // width of all charts in charts row\n chartsHeight: DEFAULT_HEIGHT, // width of all charts in charts column, without axes\n totalWidth: DEFAULT_WIDTH, // width of all charts in charts row, plus left axis, plus legend\n totalHeight: DEFAULT_HEIGHT, // width of all charts in charts height, plus bottom axis, plus top title\n };\n columnsCount = 1;\n rowsCount = 1;\n scales: ChartsScales = {\n x: {null: scaleLinear().domain([0, 1]).range([0, DEFAULT_WIDTH])},\n y: {null: scaleLinear().domain([0, 1]).range([DEFAULT_HEIGHT, 0])},\n };\n captionsSizes: CaptionsSizes = {\n xAxisCaptionsWidth: 30,\n yAxisCaptionsWidth: 100,\n bottomAxisCaptionsWidthByRows: [],\n leftAxisCaptionsWidthByColumns: [],\n bottomCaptionsTail: 0,\n leftCaptionsTail: 0,\n };\n facetTitles: Record<string, string[]> = {}; // can be multiline\n mainTitle: string[] = []; // can be multiline\n discreteAxesLabels: {\n x: Record<string, Record<string, string[]>>,\n y: Record<string, Record<string, string[]>>\n } = {x: {}, y: {}}; // only for discrete axes, by facets, can be multiline\n\n legend: LegendData = {width: 0, height: 0, items: []};\n\n clear() {\n if (this.parentNode && this.rootNode) {\n this.parentNode?.removeChild(this.rootNode);\n this.parentNode = null;\n this.rootNode = null;\n }\n // timeout to avoid trying to unmount during rendering\n setTimeout(() => {\n this.reactRoot?.unmount();\n this.reactRoot = null;\n });\n }\n\n init(node: HTMLElement) {\n if (this.parentNode === null) {\n this.parentNode = node;\n this.rootNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateChartSizes(size: ScatterplotSettingsImpl['chartSettings']['size']) {\n this.chartSizes.chartWidth = size.width;\n this.chartSizes.chartHeight = size.height;\n }\n\n updateChartDimensions(\n facetKeys: string[],\n facetSettings: ScatterplotSettingsImpl['facetSettings'],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis']\n ) {\n const {chartWidth, chartHeight} = this.chartSizes;\n let currentLeft = 0;\n let currentTop = 0;\n const facetRows = getFacetRows(facetKeys, this.rowsCount, this.columnsCount);\n this.chartsDimensions = facetKeys.reduce((res: Record<string, ChartDimensionsData>, key: string, index) => {\n const [currentRow, currentColumn] = getRowColumn(index, this.columnsCount);\n const chartEdgeSides = getChartEdgeSides(index, facetKeys.length, this.columnsCount, this.rowsCount);\n const padding = calculatePaddings(\n xAxis,\n yAxis,\n this.captionsSizes,\n facetRows[currentRow],\n this.facetTitles,\n chartEdgeSides,\n currentRow,\n currentColumn,\n currentColumn === this.columnsCount - 1,\n facetSettings\n );\n\n const outerWidth = chartWidth + padding.left + padding.right;\n const outerHeight = chartHeight + padding.top + padding.bottom;\n res[key] = {\n left: currentLeft,\n top: currentTop,\n chartEdgeSides,\n padding,\n inner: {width: chartWidth, height: chartHeight},\n outer: {width: outerWidth, height: outerHeight},\n };\n currentLeft += outerWidth;\n if (currentColumn === this.columnsCount - 1) {\n currentLeft = 0;\n currentTop += outerHeight;\n }\n return res;\n }, {});\n\n const chartsWidth = Math.max(\n ...facetKeys.map(key => this.chartsDimensions[key].outer.width + this.chartsDimensions[key].left)\n );\n const chartsHeight = Math.max(\n ...facetKeys.map(key => this.chartsDimensions[key].outer.height + this.chartsDimensions[key].top)\n );\n this.chartSizes.chartsWidth = chartsWidth;\n this.chartSizes.chartsHeight = chartsHeight;\n }\n\n updateViewport(\n facetKeys: string[],\n facetSettings: ScatterplotSettingsImpl['facetSettings'],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis'],\n discreteAxisDataX: DiscreteAxisData,\n discreteAxisDataY: DiscreteAxisData,\n groupedDots: GroupedDots,\n trendsData: TrendsData | null\n ) {\n const facetCount = facetKeys.length;\n const maxNRows = Math.min(facetSettings.nRows ?? facetCount, facetCount);\n const maxNCols = Math.min(facetSettings.nCols ?? facetCount, facetCount);\n // Use columns/rows count from settings if some of them defined, else make 1 column\n this.columnsCount = facetSettings.nRows ? Math.ceil(facetCount / maxNRows) : maxNCols;\n this.rowsCount = Math.ceil(facetCount / this.columnsCount);\n\n let [minXAll, maxXAll] = [Infinity, -Infinity];\n let [minYAll, maxYAll] = [Infinity, -Infinity];\n const dotExtentsByKeys = facetKeys.reduce((res: Record<string, Record<string, number>>, key) => {\n const dotsData = groupedDots[key];\n const {minX, minY, maxX, maxY} = dotsData;\n minXAll = Math.min(minXAll, minX);\n minYAll = Math.min(minYAll, minY);\n maxXAll = Math.max(maxXAll, maxX);\n maxYAll = Math.max(maxYAll, maxY);\n res[key] = {minX, maxX, minY, maxY};\n return res;\n }, {});\n\n const newScalesX:ChartsScales['x'] = {};\n const newScalesY:ChartsScales['y'] = {};\n\n let needsUpdateXScales = false;\n let needsUpdateYScales = false;\n facetKeys.forEach(key => {\n let scaleX: ChartsScales['x'][string];\n if (!isContinuousAxis(xAxis)) {\n scaleX = scalePoint<string | number>()\n .range([0, this.chartSizes.chartWidth])\n .domain(discreteAxisDataX.keys ?? []).padding(0.5);\n\n } else {\n scaleX = xAxis.scale === 'log' ? scaleLog() : scaleLinear();\n const extents = dotExtentsByKeys[key];\n let minX = xAxis.lowerValue ? Number(xAxis.lowerValue) : facetSettings.sharedX ? minXAll : extents.minX;\n let maxX = xAxis.upperValue ? Number(xAxis.upperValue) : facetSettings.sharedX ? maxXAll : extents.maxX;\n\n if (typeof xAxis.symmetricRange !== 'undefined') {\n const middle = xAxis.symmetricRange;\n if (middle >= minX && middle <= maxX) {\n const halfRange = Math.max(middle - minX, maxX - middle);\n minX = middle - halfRange;\n maxX = middle + halfRange;\n }\n }\n\n const rangeH = [0, this.chartSizes.chartWidth];\n // supporting scale, it needs to add offsets of fixed size in pixels to general scale Y\n const tempX = scaleX\n .copy()\n .domain([minX, maxX])\n .range([PADDINGS.LEFT, this.chartSizes.chartWidth - PADDINGS.RIGHT]);\n scaleX\n .domain([tempX.invert(0), tempX.invert(this.chartSizes.chartWidth)])\n .range(rangeH)\n .nice();\n\n }\n const prevScale = this.scales.x[key];\n newScalesX[key] = scaleX;\n needsUpdateXScales = needsUpdateXScales || scalesAreDifferent(prevScale, scaleX);\n });\n // for right Y viewport bounds we must know X bounds, to calculate trends area Y bounds\n const trendYBoundsByKeys = facetKeys.reduce((res: Record<string, Record<string, number>>, key) => {\n const trendsList = trendsData ? trendsData[key] : [];\n res[key] = trendsList.reduce(\n (res, trend) => {\n const xBounds = trend.bounded ? trend.xBounds : this.scales.x[key].domain(); // trends exist only with continuous scales\n const i1 = trend.getInterval(xBounds[0] as number);\n const i2 = trend.getInterval(xBounds[1] as number);\n res.minY = Math.min(res.minY, isNaN(i1.left) ? res.minY : i1.left, isNaN(i2.left) ? res.minY : i2.left);\n res.maxY = Math.max(res.maxY, isNaN(i1.right) ? res.maxY : i1.right, isNaN(i2.right) ? res.maxY : i2.right);\n return res;\n },\n {minY: Infinity, maxY: -Infinity}\n );\n minYAll = Math.min(minYAll, res[key].minY);\n maxYAll = Math.max(maxYAll, res[key].maxY);\n return res;\n }, {});\n facetKeys.forEach(key => {\n let scaleY: ChartsScales['y'][string];\n if (!isContinuousAxis(yAxis)) {\n scaleY = scalePoint<string | number>()\n .range([this.chartSizes.chartHeight, 0])\n .domain(discreteAxisDataY.keys ?? [])\n .padding(0.5);\n } else {\n scaleY = yAxis.scale === 'log' ? scaleLog() : scaleLinear();\n\n const dotExtents = dotExtentsByKeys[key];\n const trendExtents = trendYBoundsByKeys[key];\n let minY = yAxis.lowerValue ? Number(yAxis.lowerValue) : facetSettings.sharedY ? minYAll : Math.min(dotExtents.minY, trendExtents.minY);\n let maxY = yAxis.upperValue ? Number(yAxis.upperValue) : facetSettings.sharedY ? maxYAll : Math.max(dotExtents.maxY, trendExtents.maxY);\n\n if (typeof yAxis.symmetricRange !== 'undefined') {\n const middle = yAxis.symmetricRange;\n if (middle >= minY && middle <= maxY) {\n const halfRange = Math.max(middle - minY, maxY - middle);\n minY = middle - halfRange;\n maxY = middle + halfRange;\n }\n }\n\n const rangeV = [this.chartSizes.chartHeight, 0];\n // supporting scale, it needs to add offsets of fixed size in pixels to general scale Y\n const tempY = scaleY\n .copy()\n .domain([minY, maxY])\n .range([this.chartSizes.chartHeight - PADDINGS.BOTTOM, PADDINGS.TOP]);\n scaleY\n .domain([tempY.invert(this.chartSizes.chartHeight), tempY.invert(0)])\n .range(rangeV)\n .nice();\n }\n const prevScale = this.scales.y[key];\n newScalesY[key] = scaleY;\n needsUpdateYScales = needsUpdateYScales || scalesAreDifferent(prevScale, scaleY);\n });\n\n if (needsUpdateXScales) {\n this.scales.x = newScalesX;\n }\n if (needsUpdateYScales) {\n this.scales.y = newScalesY;\n }\n }\n\n updateCaptionsSize(\n facetKeys: string[],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis'],\n onlyPositive: boolean\n ) {\n const textMeasurer = new TextMeasurer('600 14px Manrope');\n function getMaxTickWidth(ticks: string[]) {\n return Math.max(...ticks.map(key => textMeasurer.getTextWidth(key)));\n }\n\n let xTail = 0;\n let yTail = 0;\n let xAxisCaptionsWidthByRows:number[] = [];\n let yAxisCaptionsWidthByColumns:number[] = [];\n let maxXLabelSize = 0;\n let maxYLabelSize = 0;\n if (xAxis.scale === 'discrete') {\n const sizes = measureMultilineDiscreteLabels(\n facetKeys,\n this.rowsCount,\n this.columnsCount,\n xAxis.labelsPosition ?? 'center',\n this.discreteAxesLabels.x,\n 'vertical',\n this.scales.x as Record<string, DiscreteScale>,\n );\n xTail = sizes.xTail;\n xAxisCaptionsWidthByRows = sizes.axisCaptionsWidthByRows;\n } else {\n maxXLabelSize = 20;\n }\n\n if (yAxis.scale === 'discrete') {\n const sizes = measureMultilineDiscreteLabels(\n facetKeys,\n this.rowsCount,\n this.columnsCount,\n yAxis.labelsPosition ?? 'center',\n this.discreteAxesLabels.y,\n 'horizontal',\n this.scales.y as Record<string, DiscreteScale>,\n );\n yTail = sizes.yTail;\n yAxisCaptionsWidthByColumns = sizes.axisCaptionsWidthByColumns;\n } else {\n Object.values(this.scales.y).forEach(scale => {\n const {ticks, format} = getTicksAndFormat(scale, onlyPositive);\n maxYLabelSize = Math.max(maxYLabelSize, getMaxTickWidth(ticks.map(format)));\n });\n }\n\n this.captionsSizes = {\n xAxisCaptionsWidth: xAxis.hiddenLabels ? 0 : getCaptionHeight(maxXLabelSize, xAxis),\n yAxisCaptionsWidth: yAxis.hiddenLabels ? 0 : getCaptionHeight(maxYLabelSize, yAxis),\n bottomAxisCaptionsWidthByRows: xAxisCaptionsWidthByRows,\n leftAxisCaptionsWidthByColumns: yAxisCaptionsWidthByColumns,\n bottomCaptionsTail: xTail,\n leftCaptionsTail: yTail\n };\n }\n\n createMainTitle(facetKeys: string[], title: ScatterplotSettingsImpl['chartSettings']['title']) {\n const firstChart = this.chartsDimensions[facetKeys[0]];\n const lastChart = this.chartsDimensions[facetKeys[facetKeys.length - 1]];\n\n this.mainTitle = splitTextByWidth(\n title.name,\n this.chartSizes.chartsWidth - firstChart.padding.left - lastChart.padding.right,\n 20\n );\n }\n\n createFacetTitles(facetKeys: string[], facetLabels: string[][]) {\n this.facetTitles = facetKeys.reduce((res: Record<string, string[]>, key, idx) => {\n if (facetLabels[idx].length === 1 && facetLabels[idx][0] === 'null') {\n res[key] = [];\n } else {\n res[key] = splitTextByWidth(facetLabels[idx].join(', '), this.chartSizes.chartWidth, 14);\n }\n return res;\n }, {});\n }\n\n createAxisLabels(\n facetKeys: string[],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n discreteAxisDataX: DiscreteAxisData,\n discreteAxisDataY: DiscreteAxisData,\n ) {\n this.discreteAxesLabels = {\n x: xAxis.scale !== 'discrete' ? {} : createMultilineDiscreteLabels(\n facetKeys,\n (xAxis as AxisSettingsDiscrete)?.labelsPosition ?? 'center',\n discreteAxisDataX.labels,\n false,\n 'vertical',\n this.scales.x as Record<string, DiscreteScale>,\n ),\n y: yAxis.scale !== 'discrete' ? {} : createMultilineDiscreteLabels(\n facetKeys,\n (yAxis as AxisSettingsDiscrete).labelsPosition ?? 'center',\n discreteAxisDataY.labels,\n false,\n 'horizontal',\n this.scales.y as Record<string, DiscreteScale>,\n )\n };\n }\n\n updateMargins(facetKeys: string[]) {\n const titleTextHeight = TITLE_LINE_HEIGHT * this.mainTitle.length;\n const titleHeight = titleTextHeight > 0 ? titleTextHeight + TITLE_MARGIN * 2 : 0;\n const firstChart = this.chartsDimensions[facetKeys[0]];\n const lastChart = this.chartsDimensions[facetKeys[facetKeys.length - 1]];\n this.margins = {\n top: Math.max(titleHeight, MIN_MARGIN),\n bottom: Math.max(MIN_MARGIN, this.captionsSizes.leftCaptionsTail - lastChart.padding.bottom),\n left: Math.max(MIN_MARGIN, this.captionsSizes.bottomCaptionsTail - firstChart.padding.left),\n right: this.legend.width + MIN_MARGIN,\n }; \n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartsHeight, this.legend.height) + this.margins.bottom;\n }\n\n updateLegendSize(\n legend: ScatterplotSettingsImpl['chartSettings']['legend'],\n legendInfo: ScatterplotLegendInfo,\n grouping: ColumnName[],\n layers: ScatterplotLayer[],\n additionalCurves: ScatterplotSettingsImpl['additionalCurves'],\n yColumn: ColumnName,\n ) {\n if (!legend.show) {\n this.legend = {width: 0, height: 0, items: []};\n return;\n }\n\n const legendItems: LegendItem[] = [];\n const emptySizes = {width:0, height:0, left:0, top: 0};\n const continuousHeight = Math.min(\n Math.max(this.chartSizes.chartHeight, MIN_LEGEND_GRADIENT_HEIGHT),\n MAX_LEGEND_GRADIENT_HEIGHT\n );\n const legendHeight = Math.max(this.chartSizes.chartHeight, continuousHeight);\n grouping.forEach(column => {\n const info = legendInfo[column.value];\n if (info.usedAes.length === 0 || !info.aesMap) {\n return;\n }\n if (info.values.length > MAX_SHOWN_UNIQUE_VALUES_IN_LABELS) {\n console.warn(`Too many values for discrete legend (${info.values.length})`);\n return;\n }\n const aesData: Record<string, DotAesItem> = {};\n info.values.forEach(columnValue => {\n if (!aesData[columnValue]) {\n aesData[columnValue] = {...DEFAULT_DOT_AES} as DotAesItem;\n }\n info.usedAes.forEach(key => {\n if (key === 'dotFill' || key === 'lineColor') {\n aesData[columnValue].color = (info.aesMap(columnValue, key) ?? BLACK) as string;\n }\n if (key === 'dotShape') {\n aesData[columnValue].shape = (info.aesMap(columnValue,key) ?? '21') as PointShape;\n }\n if (key === 'dotSize') {\n aesData[columnValue].size = (info.aesMap(columnValue,key) ?? 3) as number;\n }\n });\n });\n\n const title = column.label ?? column.value;\n const scale = scaleOrdinal<DotAesItem>()\n .domain(info.values)\n .range(info.values.map(value => aesData[value]))\n .unknown(DEFAULT_DOT_AES);\n legendItems.push({...emptySizes, id: column.value, type: 'dots', title, scale, values:info.values, labels:info.labels});\n });\n\n layers.forEach(layer => {\n if (layer.type === 'dots' && isContinuousAes(layer.aes.dotFill)) {\n const {domain, range, columnName, type = 'linear'} = layer.aes.dotFill;\n const title = columnName.label ?? columnName.value;\n const colorScale = getContinuousColorScale(range, domain, 'linear') as ScaleLinear<string, string>; // always linear for legend - scale to render gradient, not for dots\n const tickPositionScale = (type === 'log' ? scaleSymlog<string, string>() : scaleLinear<string, string>())\n .domain(domain)\n // @ts-ignore\n .range([continuousHeight, 0]);\n const values = getContinuousLegendTicks(tickPositionScale, domain as [number, number]);\n legendItems.push({...emptySizes, id: 'dotFill', type: 'continuous', title, scale: colorScale, tickPositionScale, values});\n }\n if (layer.type === 'dots' && isContinuousAes(layer.aes.dotSize)) {\n legendItems.push(getSizeLegendItem(layer.aes.dotSize));\n }\n });\n\n // Dedicated curves section appears when at least one additional curve is active. Main curve layer\n // is the first entry when it's enabled. When grouping is active, line samples use a neutral color\n // (BLACK) — actual group colors live in the grouping legend; otherwise the curve's fixed lineColor\n // is used. InheritAes/continuous-mapping cases also render neutral (proper resolution is future work).\n if (additionalCurves && additionalCurves.curves.length > 0) {\n // Legend sample color: mirrors the curve's own `lineColor` when fixed (so a Fixed Red setting\n // shows a red sample), and falls back to neutral BLACK when the color inherits from grouping\n // (a single sample can't represent multiple group colors — actual group colors are shown in\n // the grouping's own color legend, per spec R19).\n const neutralColor = BLACK;\n const curveLegendValues: string[] = [];\n const curveLegendLabels: Record<string, string> = {};\n const curveLegendAes: Record<string, AesItem> = {};\n const curveLayer = layers.find(l => l.type === 'curve') as CurveLayer | undefined;\n if (curveLayer) {\n const label = yColumn.label ?? yColumn.value;\n const resolvedColor = typeof curveLayer.aes.lineColor === 'string'\n ? curveLayer.aes.lineColor\n : neutralColor;\n curveLegendValues.push(label);\n curveLegendLabels[label] = label;\n curveLegendAes[label] = {\n lineShape: curveLayer.aes.lineShape,\n lineColor: resolvedColor,\n };\n }\n for (const entry of additionalCurves.curves) {\n // Ensure labels are unique in the legend even if block authors repeat them\n let key = entry.label;\n let dedupeCounter = 1;\n while (curveLegendValues.includes(key)) {\n key = `${entry.label} (${++dedupeCounter})`;\n }\n const resolvedColor = typeof entry.lineColor === 'string'\n ? entry.lineColor\n : neutralColor;\n curveLegendValues.push(key);\n curveLegendLabels[key] = key;\n curveLegendAes[key] = {\n lineShape: entry.lineShape,\n lineColor: resolvedColor,\n };\n }\n if (curveLegendValues.length > 0) {\n const scale = scaleOrdinal<AesItem>()\n .domain(curveLegendValues)\n .range(curveLegendValues.map(v => curveLegendAes[v]))\n .unknown({});\n legendItems.push({\n ...emptySizes,\n id: 'additionalCurves',\n type: 'discreteMulti',\n title: 'Curves',\n scale,\n values: curveLegendValues,\n labels: curveLegendLabels,\n usedAes: { lineShape: true, lineColor: true, dotFill: false, dotShape: false, fillColor: false },\n });\n }\n }\n\n if (!legendItems.length) {\n this.legend = {width: 0, height: 0, items: []};\n return;\n }\n\n const items = arrangeLegendParts(legendItems, legendHeight, continuousHeight);\n\n const maxRightEdge = items.reduce((max, item) => Math.max(max, item.left + item.width), 0);\n const legendWidth = maxRightEdge + LEGEND_OFFSET;\n\n this.legend = {\n width: legendWidth,\n height: legendHeight,\n items,\n };\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: ScatterplotSettingsImpl['chartSettings'],\n facetSettings: ScatterplotSettingsImpl['facetSettings'],\n facetKeys: string[],\n facetLabels: string[][],\n groupedDots: GroupedDots,\n trendsData: TrendsData | null,\n keyColumn: ColumnName,\n onlyPositive: {x: boolean; y: boolean},\n legendInfo: ScatterplotLegendInfo,\n layersData: Record<string, ScatterplotLayerData[]>,\n grouping: ColumnName[],\n layers: ScatterplotLayer[],\n trend: ScatterplotSettingsImpl['trend'],\n discreteAxisDataX: DiscreteAxisData,\n discreteAxisDataY: DiscreteAxisData,\n onTooltipHintSwitch: (v:boolean) => void,\n additionalCurves: ScatterplotSettingsImpl['additionalCurves'],\n yColumn: ColumnName,\n ) {\n const {xAxis, yAxis, size, title, legend} = chartSettings;\n this.updateChartSizes(size);\n this.updateViewport(facetKeys, facetSettings, xAxis, yAxis, discreteAxisDataX, discreteAxisDataY, groupedDots, trendsData);\n this.createAxisLabels(facetKeys, xAxis, yAxis, discreteAxisDataX, discreteAxisDataY);\n this.updateCaptionsSize(facetKeys, xAxis, yAxis, onlyPositive.y);\n this.createFacetTitles(facetKeys, facetLabels);\n this.updateChartDimensions(facetKeys, facetSettings, xAxis, yAxis);\n this.updateLegendSize(legend, legendInfo, grouping, layers, additionalCurves, yColumn);\n this.createMainTitle(facetKeys, title);\n this.updateMargins(facetKeys);\n const component = (\n <DataFrameProvider dataFrame={dataFrame}>\n <ChartsGroup\n settingsId={settingsId}\n chartSettings={chartSettings}\n facetKeys={facetKeys}\n facetSettings={facetSettings}\n chartSizes={this.chartSizes}\n chartsDimensions={this.chartsDimensions}\n scales={this.scales}\n groupedDots={groupedDots}\n trendsData={trendsData}\n legendData={this.legend}\n columnsCount={this.columnsCount}\n margins={this.margins}\n keyColumn={keyColumn}\n mainTitle={this.mainTitle}\n facetTitles={this.facetTitles}\n captionsSizes={this.captionsSizes}\n onlyPositive={onlyPositive}\n layersData={layersData}\n aesGetters={createAesGetters(dataFrame, legendInfo, layers, trend, additionalCurves)}\n onTooltipHintSwitch={onTooltipHintSwitch}\n discreteAxesLabels={this.discreteAxesLabels}\n />\n </DataFrameProvider>\n );\n this.component = component;\n this.reactRoot?.render(component);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/scatterplot/ChartRenderer.tsx"],"sourcesContent":["import type { ScaleLinear } from 'd3-scale';\nimport { scaleLinear, scaleLog, scaleOrdinal, scalePoint, scaleSymlog } from 'd3-scale';\nimport type { ReactElement } from 'react';\nimport type { Root } from 'react-dom/client';\nimport { createRoot } from 'react-dom/client';\nimport { Error } from '../common/Error';\nimport type { DotAesItem, LegendData, LegendItem } from '../common/types';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport {\n BLACK,\n DEFAULT_HEIGHT,\n DEFAULT_WIDTH,\n MAX_LEGEND_GRADIENT_HEIGHT,\n MAX_SHOWN_UNIQUE_VALUES_IN_LABELS,\n MIN_LEGEND_GRADIENT_HEIGHT,\n TITLE_LINE_HEIGHT,\n TITLE_MARGIN,\n} from '../constants';\nimport type { DataFrame } from '../DataFrame';\nimport { FACET_TITLE_LINE } from '../discrete/constants';\nimport { splitTextByWidth } from '../discrete/utils';\nimport type { AesItem, AxisSettingsDiscrete, ColumnName, PointShape, ScatterplotLegendInfo } from '../types';\nimport { isContinuousAes } from '../types';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { getSizeLegendItem } from '../utils/getSizeLegendItem';\nimport { getContinuousColorScale } from '../utils/getContinuousColorScale';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { ChartsGroup } from './components/ChartsGroup';\nimport type { AesGetters, CaptionsSizes, ChartDimensionsData, ChartScales, ChartSizes, ChartsScales, DiscreteAxisData, DiscreteScale, Margins } from './components/types';\nimport {\n DEFAULT_DOT_AES,\n DEFAULT_TICKS_SIZE,\n FACET_AXIS_OFFSET,\n FACET_TITLE_OFFSET,\n LEGEND_OFFSET,\n MIN_MARGIN,\n MIN_PADDING,\n PADDINGS,\n TICK_OFFSET,\n TITLE_LINE,\n} from './constants';\nimport type { GroupedDots } from './dots';\nimport type { ScatterplotLayerData } from './getLayersData';\nimport type { TrendsData } from './linearRegression';\nimport type { CurveLayer, DotsLayer, ScatterplotLayer, ScatterplotSettingsImpl } from './ScatterplotSettingsImpl';\nimport { createAesGetter } from './utils/createAesGetter';\nimport { getTicksAndFormat } from './utils/getTicksAndFormat';\nimport { isContinuousAxis } from './utils/isNumericScale';\nimport { createMultilineDiscreteLabels } from '../utils/createMultilineDiscreteLabels';\nimport { measureMultilineDiscreteLabels } from '../utils/measureMultilineDiscreteLabels';\n\nfunction scalesAreDifferent(prevScale:ChartScales['x'|'y'], currentScale:ChartScales['x'|'y']):boolean {\n if (prevScale === undefined) {\n return true;\n } else {\n const domain = prevScale.domain();\n const range = prevScale.range();\n const newDomain = currentScale.domain();\n const newRange = currentScale.range();\n if (\n domain.length !== newDomain.length ||\n domain.some((v, idx) => v !== newDomain[idx]) ||\n range[0] !== newRange[0] || range[1] !== newRange[1]\n ) {\n return true;\n }\n }\n return false;\n}\nfunction getChartEdgeSides(index: number, facetsCount: number, columnsCount: number, rowsCount: number) {\n const chartSides: ('left' | 'right' | 'top' | 'bottom')[] = [];\n if (index % columnsCount === columnsCount - 1) {\n chartSides.push('right');\n }\n if (index % columnsCount === 0) {\n chartSides.push('left');\n }\n if (index < columnsCount) {\n chartSides.push('top');\n }\n if (\n Math.ceil((index + 1) / columnsCount) === rowsCount ||\n (Math.ceil((index + 1) / columnsCount) === rowsCount - 1 &&\n index % columnsCount > (facetsCount - 1) % columnsCount)\n ) {\n chartSides.push('bottom');\n }\n return chartSides;\n}\n\nfunction calculatePaddings(\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis'],\n captionsSizes: CaptionsSizes,\n currentRowFacetKeys: string[],\n facetTitles: Record<string, string[]>,\n chartEdgeSides: ('left' | 'right' | 'top' | 'bottom')[],\n currentRow: number,\n currentColumn: number,\n lastInRow: boolean,\n facetSettings?: ScatterplotSettingsImpl['facetSettings'],\n) {\n const discreteX = xAxis.scale === 'discrete';\n const discreteY = yAxis.scale === 'discrete';\n\n const needLeftAxis = chartEdgeSides.includes('left') || !facetSettings?.sharedY;\n const needLeftAxisTitle = chartEdgeSides.includes('left') && yAxis.title !== '';\n const needBottomAxis = chartEdgeSides.includes('bottom') || !facetSettings?.sharedX;\n const needBottomAxisTitle = chartEdgeSides.includes('bottom') && xAxis.title !== '';\n\n const yCaptions = yAxis.hiddenLabels ? 0 : discreteY ? captionsSizes.leftAxisCaptionsWidthByColumns[currentColumn] + 2 * TICK_OFFSET : captionsSizes.yAxisCaptionsWidth + 2 * TICK_OFFSET;\n const yTicks = (yAxis.showTicks ? DEFAULT_TICKS_SIZE : 0) + TICK_OFFSET;\n const yAxisTitle = needLeftAxisTitle ? TITLE_LINE : 0;\n\n const xCaptions = xAxis.hiddenLabels ? 0 : discreteX ? captionsSizes.bottomAxisCaptionsWidthByRows[currentRow] + 2 * TICK_OFFSET: captionsSizes.xAxisCaptionsWidth + 2 * TICK_OFFSET;\n const xTicks = xAxis.showTicks ? DEFAULT_TICKS_SIZE : 0;\n const xAxisTitle = needBottomAxisTitle ? TITLE_LINE : 0;\n\n const leftAxisElements = yCaptions + yTicks + yAxisTitle + FACET_AXIS_OFFSET;\n const bottomAxisElements = xCaptions + xTicks + xAxisTitle + FACET_AXIS_OFFSET;\n\n const facetTitlesLinesCount = Math.max(...currentRowFacetKeys.map(key => facetTitles[key].length));\n return {\n left: needLeftAxis ? leftAxisElements : MIN_PADDING,\n top: facetTitlesLinesCount === 0 ? 0 : FACET_TITLE_OFFSET * 2 + facetTitlesLinesCount * FACET_TITLE_LINE,\n bottom: needBottomAxis ? bottomAxisElements + 8 : MIN_PADDING,\n right: lastInRow ? 0 : MIN_PADDING,\n };\n}\n\n// facet keys grouped by rows\nfunction getFacetRows(facetKeys: string[], nRows: number, nColumns: number): string[][] {\n const result: string[][] = [];\n for (let i = 0; i < nRows; i++) {\n result.push(facetKeys.slice(i * nColumns, i * nColumns + nColumns));\n }\n return result;\n}\n\nfunction getRowColumn(idx: number, columnsCount: number) {\n const row = Math.floor(idx / columnsCount);\n const column = idx - row * columnsCount;\n return [row, column];\n}\n\nfunction createAesGetters(\n dataFrame: DataFrame,\n legendInfo: ScatterplotLegendInfo,\n layers: ScatterplotLayer[],\n trend: ScatterplotSettingsImpl['trend'],\n additionalCurves: ScatterplotSettingsImpl['additionalCurves']\n): AesGetters {\n const dotLayer = layers.find(l => l.type === 'dots') as DotsLayer | undefined;\n const curveLayer = layers.find(l => l.type === 'curve') as CurveLayer | undefined;\n\n return {\n dotShape: createAesGetter(dataFrame, legendInfo, dotLayer?.aes.dotShape ?? DEFAULT_DOT_AES.shape,'dotShape'),\n dotColor: createAesGetter(dataFrame, legendInfo, dotLayer?.aes.dotFill ?? DEFAULT_DOT_AES.color, 'dotFill'),\n dotSize: createAesGetter(dataFrame, legendInfo, dotLayer?.aes.dotSize ?? DEFAULT_DOT_AES.size, 'dotSize'),\n lineShape: createAesGetter(dataFrame, legendInfo, curveLayer?.aes.lineShape ?? 'solid', 'lineShape'),\n lineColor: createAesGetter(dataFrame, legendInfo, curveLayer?.aes.lineColor ?? BLACK, 'lineColor'),\n trendColor: createAesGetter(dataFrame, legendInfo, trend?.color ?? DEFAULT_DOT_AES.color, 'fillColor'),\n trendLineWidth: trend?.lineWidth ?? 1,\n additionalCurveLineColor: (additionalCurves?.curves ?? []).map(\n (entry) => createAesGetter<string>(dataFrame, legendInfo, entry.lineColor, 'lineColor'),\n ),\n additionalCurveTrendColor: (additionalCurves?.curves ?? []).map(\n (entry) => createAesGetter<string>(dataFrame, legendInfo, entry.trend?.color ?? entry.lineColor, 'lineColor'),\n ),\n };\n}\n\nconst COS_PI_4 = Math.cos(Math.PI / 4);\nconst INCLINE_OFFSET = 5; // height of little triangle of text for captions inclined 45deg\n\nfunction getCaptionHeight (size: number, axis: ScatterplotSettingsImpl['chartSettings']['xAxis' | 'yAxis']) {\n if (axis.scale === 'discrete') {\n if (axis.labelsPosition === '90deg') {\n return size;\n }\n if (axis.labelsPosition === '45deg') {\n return size * COS_PI_4 + (size > 0 ? 2 * INCLINE_OFFSET : 0) ;\n }\n return TITLE_LINE;\n }\n return Math.max(size, TITLE_LINE);\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n component: ReactElement = (<></>);\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n chartsDimensions: Record<string, ChartDimensionsData> = {};\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\n chartsWidth: DEFAULT_WIDTH, // width of all charts in charts row\n chartsHeight: DEFAULT_HEIGHT, // width of all charts in charts column, without axes\n totalWidth: DEFAULT_WIDTH, // width of all charts in charts row, plus left axis, plus legend\n totalHeight: DEFAULT_HEIGHT, // width of all charts in charts height, plus bottom axis, plus top title\n };\n columnsCount = 1;\n rowsCount = 1;\n scales: ChartsScales = {\n x: {null: scaleLinear().domain([0, 1]).range([0, DEFAULT_WIDTH])},\n y: {null: scaleLinear().domain([0, 1]).range([DEFAULT_HEIGHT, 0])},\n };\n captionsSizes: CaptionsSizes = {\n xAxisCaptionsWidth: 30,\n yAxisCaptionsWidth: 100,\n bottomAxisCaptionsWidthByRows: [],\n leftAxisCaptionsWidthByColumns: [],\n bottomCaptionsTail: 0,\n leftCaptionsTail: 0,\n };\n facetTitles: Record<string, string[]> = {}; // can be multiline\n mainTitle: string[] = []; // can be multiline\n discreteAxesLabels: {\n x: Record<string, Record<string, string[]>>,\n y: Record<string, Record<string, string[]>>\n } = {x: {}, y: {}}; // only for discrete axes, by facets, can be multiline\n\n legend: LegendData = {width: 0, height: 0, items: []};\n\n clear() {\n if (this.parentNode && this.rootNode) {\n this.parentNode?.removeChild(this.rootNode);\n this.parentNode = null;\n this.rootNode = null;\n }\n // timeout to avoid trying to unmount during rendering\n setTimeout(() => {\n this.reactRoot?.unmount();\n this.reactRoot = null;\n });\n }\n\n init(node: HTMLElement) {\n if (this.parentNode === null) {\n this.parentNode = node;\n this.rootNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateChartSizes(size: ScatterplotSettingsImpl['chartSettings']['size']) {\n this.chartSizes.chartWidth = size.width;\n this.chartSizes.chartHeight = size.height;\n }\n\n updateChartDimensions(\n facetKeys: string[],\n facetSettings: ScatterplotSettingsImpl['facetSettings'],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis']\n ) {\n const {chartWidth, chartHeight} = this.chartSizes;\n let currentLeft = 0;\n let currentTop = 0;\n const facetRows = getFacetRows(facetKeys, this.rowsCount, this.columnsCount);\n this.chartsDimensions = facetKeys.reduce((res: Record<string, ChartDimensionsData>, key: string, index) => {\n const [currentRow, currentColumn] = getRowColumn(index, this.columnsCount);\n const chartEdgeSides = getChartEdgeSides(index, facetKeys.length, this.columnsCount, this.rowsCount);\n const padding = calculatePaddings(\n xAxis,\n yAxis,\n this.captionsSizes,\n facetRows[currentRow],\n this.facetTitles,\n chartEdgeSides,\n currentRow,\n currentColumn,\n currentColumn === this.columnsCount - 1,\n facetSettings\n );\n\n const outerWidth = chartWidth + padding.left + padding.right;\n const outerHeight = chartHeight + padding.top + padding.bottom;\n res[key] = {\n left: currentLeft,\n top: currentTop,\n chartEdgeSides,\n padding,\n inner: {width: chartWidth, height: chartHeight},\n outer: {width: outerWidth, height: outerHeight},\n };\n currentLeft += outerWidth;\n if (currentColumn === this.columnsCount - 1) {\n currentLeft = 0;\n currentTop += outerHeight;\n }\n return res;\n }, {});\n\n const chartsWidth = Math.max(\n ...facetKeys.map(key => this.chartsDimensions[key].outer.width + this.chartsDimensions[key].left)\n );\n const chartsHeight = Math.max(\n ...facetKeys.map(key => this.chartsDimensions[key].outer.height + this.chartsDimensions[key].top)\n );\n this.chartSizes.chartsWidth = chartsWidth;\n this.chartSizes.chartsHeight = chartsHeight;\n }\n\n updateViewport(\n facetKeys: string[],\n facetSettings: ScatterplotSettingsImpl['facetSettings'],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis'],\n discreteAxisDataX: DiscreteAxisData,\n discreteAxisDataY: DiscreteAxisData,\n groupedDots: GroupedDots,\n trendsData: TrendsData | null\n ) {\n const facetCount = facetKeys.length;\n const maxNRows = Math.min(facetSettings.nRows ?? facetCount, facetCount);\n const maxNCols = Math.min(facetSettings.nCols ?? facetCount, facetCount);\n // Use columns/rows count from settings if some of them defined, else make 1 column\n this.columnsCount = facetSettings.nRows ? Math.ceil(facetCount / maxNRows) : maxNCols;\n this.rowsCount = Math.ceil(facetCount / this.columnsCount);\n\n let [minXAll, maxXAll] = [Infinity, -Infinity];\n let [minYAll, maxYAll] = [Infinity, -Infinity];\n const dotExtentsByKeys = facetKeys.reduce((res: Record<string, Record<string, number>>, key) => {\n const dotsData = groupedDots[key];\n const {minX, minY, maxX, maxY} = dotsData;\n minXAll = Math.min(minXAll, minX);\n minYAll = Math.min(minYAll, minY);\n maxXAll = Math.max(maxXAll, maxX);\n maxYAll = Math.max(maxYAll, maxY);\n res[key] = {minX, maxX, minY, maxY};\n return res;\n }, {});\n\n const newScalesX:ChartsScales['x'] = {};\n const newScalesY:ChartsScales['y'] = {};\n\n let needsUpdateXScales = false;\n let needsUpdateYScales = false;\n facetKeys.forEach(key => {\n let scaleX: ChartsScales['x'][string];\n if (!isContinuousAxis(xAxis)) {\n scaleX = scalePoint<string | number>()\n .range([0, this.chartSizes.chartWidth])\n .domain(discreteAxisDataX.keys ?? []).padding(0.5);\n\n } else {\n scaleX = xAxis.scale === 'log' ? scaleLog() : scaleLinear();\n const extents = dotExtentsByKeys[key];\n let minX = xAxis.lowerValue ? Number(xAxis.lowerValue) : facetSettings.sharedX ? minXAll : extents.minX;\n let maxX = xAxis.upperValue ? Number(xAxis.upperValue) : facetSettings.sharedX ? maxXAll : extents.maxX;\n\n if (typeof xAxis.symmetricRange !== 'undefined') {\n const middle = xAxis.symmetricRange;\n if (middle >= minX && middle <= maxX) {\n const halfRange = Math.max(middle - minX, maxX - middle);\n minX = middle - halfRange;\n maxX = middle + halfRange;\n }\n }\n\n const rangeH = [0, this.chartSizes.chartWidth];\n // supporting scale, it needs to add offsets of fixed size in pixels to general scale Y\n const tempX = scaleX\n .copy()\n .domain([minX, maxX])\n .range([PADDINGS.LEFT, this.chartSizes.chartWidth - PADDINGS.RIGHT]);\n scaleX\n .domain([tempX.invert(0), tempX.invert(this.chartSizes.chartWidth)])\n .range(rangeH)\n .nice();\n\n }\n const prevScale = this.scales.x[key];\n newScalesX[key] = scaleX;\n needsUpdateXScales = needsUpdateXScales || scalesAreDifferent(prevScale, scaleX);\n });\n // for right Y viewport bounds we must know X bounds, to calculate trends area Y bounds\n const trendYBoundsByKeys = facetKeys.reduce((res: Record<string, Record<string, number>>, key) => {\n const trendsList = trendsData ? trendsData[key] : [];\n res[key] = trendsList.reduce(\n (res, trend) => {\n const xBounds = trend.bounded ? trend.xBounds : newScalesX[key].domain(); // trends exist only with continuous scales\n const i1 = trend.getInterval(xBounds[0] as number);\n const i2 = trend.getInterval(xBounds[1] as number);\n res.minY = Math.min(res.minY, isNaN(i1.left) ? res.minY : i1.left, isNaN(i2.left) ? res.minY : i2.left);\n res.maxY = Math.max(res.maxY, isNaN(i1.right) ? res.maxY : i1.right, isNaN(i2.right) ? res.maxY : i2.right);\n return res;\n },\n {minY: Infinity, maxY: -Infinity}\n );\n minYAll = Math.min(minYAll, res[key].minY);\n maxYAll = Math.max(maxYAll, res[key].maxY);\n return res;\n }, {});\n facetKeys.forEach(key => {\n let scaleY: ChartsScales['y'][string];\n if (!isContinuousAxis(yAxis)) {\n scaleY = scalePoint<string | number>()\n .range([this.chartSizes.chartHeight, 0])\n .domain(discreteAxisDataY.keys ?? [])\n .padding(0.5);\n } else {\n scaleY = yAxis.scale === 'log' ? scaleLog() : scaleLinear();\n\n const dotExtents = dotExtentsByKeys[key];\n const trendExtents = trendYBoundsByKeys[key];\n let minY = yAxis.lowerValue ? Number(yAxis.lowerValue) : facetSettings.sharedY ? minYAll : Math.min(dotExtents.minY, trendExtents.minY);\n let maxY = yAxis.upperValue ? Number(yAxis.upperValue) : facetSettings.sharedY ? maxYAll : Math.max(dotExtents.maxY, trendExtents.maxY);\n\n if (typeof yAxis.symmetricRange !== 'undefined') {\n const middle = yAxis.symmetricRange;\n if (middle >= minY && middle <= maxY) {\n const halfRange = Math.max(middle - minY, maxY - middle);\n minY = middle - halfRange;\n maxY = middle + halfRange;\n }\n }\n\n const rangeV = [this.chartSizes.chartHeight, 0];\n // supporting scale, it needs to add offsets of fixed size in pixels to general scale Y\n const tempY = scaleY\n .copy()\n .domain([minY, maxY])\n .range([this.chartSizes.chartHeight - PADDINGS.BOTTOM, PADDINGS.TOP]);\n scaleY\n .domain([tempY.invert(this.chartSizes.chartHeight), tempY.invert(0)])\n .range(rangeV)\n .nice();\n }\n const prevScale = this.scales.y[key];\n newScalesY[key] = scaleY;\n needsUpdateYScales = needsUpdateYScales || scalesAreDifferent(prevScale, scaleY);\n });\n\n if (needsUpdateXScales) {\n this.scales.x = newScalesX;\n }\n if (needsUpdateYScales) {\n this.scales.y = newScalesY;\n }\n }\n\n updateCaptionsSize(\n facetKeys: string[],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['yAxis'],\n onlyPositive: boolean\n ) {\n const textMeasurer = new TextMeasurer('600 14px Manrope');\n function getMaxTickWidth(ticks: string[]) {\n return Math.max(...ticks.map(key => textMeasurer.getTextWidth(key)));\n }\n\n let xTail = 0;\n let yTail = 0;\n let xAxisCaptionsWidthByRows:number[] = [];\n let yAxisCaptionsWidthByColumns:number[] = [];\n let maxXLabelSize = 0;\n let maxYLabelSize = 0;\n if (xAxis.scale === 'discrete') {\n const sizes = measureMultilineDiscreteLabels(\n facetKeys,\n this.rowsCount,\n this.columnsCount,\n xAxis.labelsPosition ?? 'center',\n this.discreteAxesLabels.x,\n 'vertical',\n this.scales.x as Record<string, DiscreteScale>,\n );\n xTail = sizes.xTail;\n xAxisCaptionsWidthByRows = sizes.axisCaptionsWidthByRows;\n } else {\n maxXLabelSize = 20;\n }\n\n if (yAxis.scale === 'discrete') {\n const sizes = measureMultilineDiscreteLabels(\n facetKeys,\n this.rowsCount,\n this.columnsCount,\n yAxis.labelsPosition ?? 'center',\n this.discreteAxesLabels.y,\n 'horizontal',\n this.scales.y as Record<string, DiscreteScale>,\n );\n yTail = sizes.yTail;\n yAxisCaptionsWidthByColumns = sizes.axisCaptionsWidthByColumns;\n } else {\n Object.values(this.scales.y).forEach(scale => {\n const {ticks, format} = getTicksAndFormat(scale, onlyPositive);\n maxYLabelSize = Math.max(maxYLabelSize, getMaxTickWidth(ticks.map(format)));\n });\n }\n\n this.captionsSizes = {\n xAxisCaptionsWidth: xAxis.hiddenLabels ? 0 : getCaptionHeight(maxXLabelSize, xAxis),\n yAxisCaptionsWidth: yAxis.hiddenLabels ? 0 : getCaptionHeight(maxYLabelSize, yAxis),\n bottomAxisCaptionsWidthByRows: xAxisCaptionsWidthByRows,\n leftAxisCaptionsWidthByColumns: yAxisCaptionsWidthByColumns,\n bottomCaptionsTail: xTail,\n leftCaptionsTail: yTail\n };\n }\n\n createMainTitle(facetKeys: string[], title: ScatterplotSettingsImpl['chartSettings']['title']) {\n const firstChart = this.chartsDimensions[facetKeys[0]];\n const lastChart = this.chartsDimensions[facetKeys[facetKeys.length - 1]];\n\n this.mainTitle = splitTextByWidth(\n title.name,\n this.chartSizes.chartsWidth - firstChart.padding.left - lastChart.padding.right,\n 20\n );\n }\n\n createFacetTitles(facetKeys: string[], facetLabels: string[][]) {\n this.facetTitles = facetKeys.reduce((res: Record<string, string[]>, key, idx) => {\n if (facetLabels[idx].length === 1 && facetLabels[idx][0] === 'null') {\n res[key] = [];\n } else {\n res[key] = splitTextByWidth(facetLabels[idx].join(', '), this.chartSizes.chartWidth, 14);\n }\n return res;\n }, {});\n }\n\n createAxisLabels(\n facetKeys: string[],\n xAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n discreteAxisDataX: DiscreteAxisData,\n discreteAxisDataY: DiscreteAxisData,\n ) {\n this.discreteAxesLabels = {\n x: xAxis.scale !== 'discrete' ? {} : createMultilineDiscreteLabels(\n facetKeys,\n (xAxis as AxisSettingsDiscrete)?.labelsPosition ?? 'center',\n discreteAxisDataX.labels,\n false,\n 'vertical',\n this.scales.x as Record<string, DiscreteScale>,\n ),\n y: yAxis.scale !== 'discrete' ? {} : createMultilineDiscreteLabels(\n facetKeys,\n (yAxis as AxisSettingsDiscrete).labelsPosition ?? 'center',\n discreteAxisDataY.labels,\n false,\n 'horizontal',\n this.scales.y as Record<string, DiscreteScale>,\n )\n };\n }\n\n updateMargins(facetKeys: string[]) {\n const titleTextHeight = TITLE_LINE_HEIGHT * this.mainTitle.length;\n const titleHeight = titleTextHeight > 0 ? titleTextHeight + TITLE_MARGIN * 2 : 0;\n const firstChart = this.chartsDimensions[facetKeys[0]];\n const lastChart = this.chartsDimensions[facetKeys[facetKeys.length - 1]];\n this.margins = {\n top: Math.max(titleHeight, MIN_MARGIN),\n bottom: Math.max(MIN_MARGIN, this.captionsSizes.leftCaptionsTail - lastChart.padding.bottom),\n left: Math.max(MIN_MARGIN, this.captionsSizes.bottomCaptionsTail - firstChart.padding.left),\n right: this.legend.width + MIN_MARGIN,\n }; \n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartsWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartsHeight, this.legend.height) + this.margins.bottom;\n }\n\n updateLegendSize(\n legend: ScatterplotSettingsImpl['chartSettings']['legend'],\n legendInfo: ScatterplotLegendInfo,\n grouping: ColumnName[],\n layers: ScatterplotLayer[],\n additionalCurves: ScatterplotSettingsImpl['additionalCurves'],\n yColumn: ColumnName,\n ) {\n if (!legend.show) {\n this.legend = {width: 0, height: 0, items: []};\n return;\n }\n\n const legendItems: LegendItem[] = [];\n const emptySizes = {width:0, height:0, left:0, top: 0};\n const continuousHeight = Math.min(\n Math.max(this.chartSizes.chartHeight, MIN_LEGEND_GRADIENT_HEIGHT),\n MAX_LEGEND_GRADIENT_HEIGHT\n );\n const legendHeight = Math.max(this.chartSizes.chartHeight, continuousHeight);\n grouping.forEach(column => {\n const info = legendInfo[column.value];\n if (info.usedAes.length === 0 || !info.aesMap) {\n return;\n }\n if (info.values.length > MAX_SHOWN_UNIQUE_VALUES_IN_LABELS) {\n console.warn(`Too many values for discrete legend (${info.values.length})`);\n return;\n }\n const aesData: Record<string, DotAesItem> = {};\n info.values.forEach(columnValue => {\n if (!aesData[columnValue]) {\n aesData[columnValue] = {...DEFAULT_DOT_AES} as DotAesItem;\n }\n info.usedAes.forEach(key => {\n if (key === 'dotFill' || key === 'lineColor') {\n aesData[columnValue].color = (info.aesMap(columnValue, key) ?? BLACK) as string;\n }\n if (key === 'dotShape') {\n aesData[columnValue].shape = (info.aesMap(columnValue,key) ?? '21') as PointShape;\n }\n if (key === 'dotSize') {\n aesData[columnValue].size = (info.aesMap(columnValue,key) ?? 3) as number;\n }\n });\n });\n\n const title = column.label ?? column.value;\n const scale = scaleOrdinal<DotAesItem>()\n .domain(info.values)\n .range(info.values.map(value => aesData[value]))\n .unknown(DEFAULT_DOT_AES);\n legendItems.push({...emptySizes, id: column.value, type: 'dots', title, scale, values:info.values, labels:info.labels});\n });\n\n layers.forEach(layer => {\n if (layer.type === 'dots' && isContinuousAes(layer.aes.dotFill)) {\n const {domain, range, columnName, type = 'linear'} = layer.aes.dotFill;\n const title = columnName.label ?? columnName.value;\n const colorScale = getContinuousColorScale(range, domain, 'linear') as ScaleLinear<string, string>; // always linear for legend - scale to render gradient, not for dots\n const tickPositionScale = (type === 'log' ? scaleSymlog<string, string>() : scaleLinear<string, string>())\n .domain(domain)\n // @ts-ignore\n .range([continuousHeight, 0]);\n const values = getContinuousLegendTicks(tickPositionScale, domain as [number, number]);\n legendItems.push({...emptySizes, id: 'dotFill', type: 'continuous', title, scale: colorScale, tickPositionScale, values});\n }\n if (layer.type === 'dots' && isContinuousAes(layer.aes.dotSize)) {\n legendItems.push(getSizeLegendItem(layer.aes.dotSize));\n }\n });\n\n // Dedicated curves section appears when at least one additional curve is active. Main curve layer\n // is the first entry when it's enabled. When grouping is active, line samples use a neutral color\n // (BLACK) — actual group colors live in the grouping legend; otherwise the curve's fixed lineColor\n // is used. InheritAes/continuous-mapping cases also render neutral (proper resolution is future work).\n if (additionalCurves && additionalCurves.curves.length > 0) {\n // Legend sample color: mirrors the curve's own `lineColor` when fixed (so a Fixed Red setting\n // shows a red sample), and falls back to neutral BLACK when the color inherits from grouping\n // (a single sample can't represent multiple group colors — actual group colors are shown in\n // the grouping's own color legend, per spec R19).\n const neutralColor = BLACK;\n const curveLegendValues: string[] = [];\n const curveLegendLabels: Record<string, string> = {};\n const curveLegendAes: Record<string, AesItem> = {};\n const curveLayer = layers.find(l => l.type === 'curve') as CurveLayer | undefined;\n if (curveLayer) {\n const label = yColumn.label ?? yColumn.value;\n const resolvedColor = typeof curveLayer.aes.lineColor === 'string'\n ? curveLayer.aes.lineColor\n : neutralColor;\n curveLegendValues.push(label);\n curveLegendLabels[label] = label;\n curveLegendAes[label] = {\n lineShape: curveLayer.aes.lineShape,\n lineColor: resolvedColor,\n };\n }\n for (const entry of additionalCurves.curves) {\n // Ensure labels are unique in the legend even if block authors repeat them\n let key = entry.label;\n let dedupeCounter = 1;\n while (curveLegendValues.includes(key)) {\n key = `${entry.label} (${++dedupeCounter})`;\n }\n const resolvedColor = typeof entry.lineColor === 'string'\n ? entry.lineColor\n : neutralColor;\n curveLegendValues.push(key);\n curveLegendLabels[key] = key;\n curveLegendAes[key] = {\n lineShape: entry.lineShape,\n lineColor: resolvedColor,\n };\n }\n if (curveLegendValues.length > 0) {\n const scale = scaleOrdinal<AesItem>()\n .domain(curveLegendValues)\n .range(curveLegendValues.map(v => curveLegendAes[v]))\n .unknown({});\n legendItems.push({\n ...emptySizes,\n id: 'additionalCurves',\n type: 'discreteMulti',\n title: 'Curves',\n scale,\n values: curveLegendValues,\n labels: curveLegendLabels,\n usedAes: { lineShape: true, lineColor: true, dotFill: false, dotShape: false, fillColor: false },\n });\n }\n }\n\n if (!legendItems.length) {\n this.legend = {width: 0, height: 0, items: []};\n return;\n }\n\n const items = arrangeLegendParts(legendItems, legendHeight, continuousHeight);\n\n const maxRightEdge = items.reduce((max, item) => Math.max(max, item.left + item.width), 0);\n const legendWidth = maxRightEdge + LEGEND_OFFSET;\n\n this.legend = {\n width: legendWidth,\n height: legendHeight,\n items,\n };\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: ScatterplotSettingsImpl['chartSettings'],\n facetSettings: ScatterplotSettingsImpl['facetSettings'],\n facetKeys: string[],\n facetLabels: string[][],\n groupedDots: GroupedDots,\n trendsData: TrendsData | null,\n keyColumn: ColumnName,\n onlyPositive: {x: boolean; y: boolean},\n legendInfo: ScatterplotLegendInfo,\n layersData: Record<string, ScatterplotLayerData[]>,\n grouping: ColumnName[],\n layers: ScatterplotLayer[],\n trend: ScatterplotSettingsImpl['trend'],\n discreteAxisDataX: DiscreteAxisData,\n discreteAxisDataY: DiscreteAxisData,\n onTooltipHintSwitch: (v:boolean) => void,\n additionalCurves: ScatterplotSettingsImpl['additionalCurves'],\n yColumn: ColumnName,\n ) {\n const {xAxis, yAxis, size, title, legend} = chartSettings;\n this.updateChartSizes(size);\n this.updateViewport(facetKeys, facetSettings, xAxis, yAxis, discreteAxisDataX, discreteAxisDataY, groupedDots, trendsData);\n this.createAxisLabels(facetKeys, xAxis, yAxis, discreteAxisDataX, discreteAxisDataY);\n this.updateCaptionsSize(facetKeys, xAxis, yAxis, onlyPositive.y);\n this.createFacetTitles(facetKeys, facetLabels);\n this.updateChartDimensions(facetKeys, facetSettings, xAxis, yAxis);\n this.updateLegendSize(legend, legendInfo, grouping, layers, additionalCurves, yColumn);\n this.createMainTitle(facetKeys, title);\n this.updateMargins(facetKeys);\n const component = (\n <DataFrameProvider dataFrame={dataFrame}>\n <ChartsGroup\n settingsId={settingsId}\n chartSettings={chartSettings}\n facetKeys={facetKeys}\n facetSettings={facetSettings}\n chartSizes={this.chartSizes}\n chartsDimensions={this.chartsDimensions}\n scales={this.scales}\n groupedDots={groupedDots}\n trendsData={trendsData}\n legendData={this.legend}\n columnsCount={this.columnsCount}\n margins={this.margins}\n keyColumn={keyColumn}\n mainTitle={this.mainTitle}\n facetTitles={this.facetTitles}\n captionsSizes={this.captionsSizes}\n onlyPositive={onlyPositive}\n layersData={layersData}\n aesGetters={createAesGetters(dataFrame, legendInfo, layers, trend, additionalCurves)}\n onTooltipHintSwitch={onTooltipHintSwitch}\n discreteAxesLabels={this.discreteAxesLabels}\n />\n </DataFrameProvider>\n );\n this.component = component;\n this.reactRoot?.render(component);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAS,EAAmB,GAAgC,GAA2C;AACnG,KAAI,MAAc,KAAA,EACd,QAAO;CACJ;EACH,IAAM,IAAS,EAAU,QAAQ,EAC3B,IAAQ,EAAU,OAAO,EACzB,IAAY,EAAa,QAAQ,EACjC,IAAW,EAAa,OAAO;AACrC,MACI,EAAO,WAAW,EAAU,UAC5B,EAAO,MAAM,GAAG,MAAQ,MAAM,EAAU,GAAK,IAC7C,EAAM,OAAO,EAAS,MAAM,EAAM,OAAO,EAAS,GAElD,QAAO;;AAGf,QAAO;;AAEX,SAAS,EAAkB,GAAe,GAAqB,GAAsB,GAAmB;CACpG,IAAM,IAAsD,EAAE;AAiB9D,QAhBI,IAAQ,MAAiB,IAAe,KACxC,EAAW,KAAK,QAAQ,EAExB,IAAQ,MAAiB,KACzB,EAAW,KAAK,OAAO,EAEvB,IAAQ,KACR,EAAW,KAAK,MAAM,GAGtB,KAAK,MAAM,IAAQ,KAAK,EAAa,KAAK,KACzC,KAAK,MAAM,IAAQ,KAAK,EAAa,KAAK,IAAY,KACnD,IAAQ,KAAgB,IAAc,KAAK,MAE/C,EAAW,KAAK,SAAS,EAEtB;;AAGX,SAAS,EACL,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACF;CACE,IAAM,IAAY,EAAM,UAAU,YAC5B,IAAY,EAAM,UAAU,YAE5B,IAAe,EAAe,SAAS,OAAO,IAAI,CAAC,GAAe,SAClE,IAAoB,EAAe,SAAS,OAAO,IAAI,EAAM,UAAU,IACvE,IAAiB,EAAe,SAAS,SAAS,IAAI,CAAC,GAAe,SACtE,IAAsB,EAAe,SAAS,SAAS,IAAI,EAAM,UAAU,IAE3E,IAAY,EAAM,eAAe,IAAI,IAAY,EAAc,+BAA+B,KAAiB,KAAkB,EAAc,qBAAqB,IACpK,KAAU,EAAM,YAAA,IAAiC,KAAA,GACjD,IAAa,IAAA,KAAiC,GAE9C,IAAY,EAAM,eAAe,IAAI,IAAY,EAAc,8BAA8B,KAAc,KAAiB,EAAc,qBAAqB,IAC/J,IAAS,EAAM,YAAA,IAAiC,GAChD,IAAa,IAAA,KAAmC,GAEhD,IAAmB,IAAY,IAAS,IAAA,GACxC,IAAqB,IAAY,IAAS,IAAA,GAE1C,IAAwB,KAAK,IAAI,GAAG,EAAoB,KAAI,MAAO,EAAY,GAAK,OAAO,CAAC;AAClG,QAAO;EACH,MAAM,IAAe,IAAA;EACrB,KAAK,MAA0B,IAAI,IAAA,KAA6B,IAAA;EAChE,QAAQ,IAAiB,IAAqB,IAAA;EAC9C,OAAO,IAAY,IAAA;EACtB;;AAIL,SAAS,EAAa,GAAqB,GAAe,GAA8B;CACpF,IAAM,IAAqB,EAAE;AAC7B,MAAK,IAAI,IAAI,GAAG,IAAI,GAAO,IACvB,GAAO,KAAK,EAAU,MAAM,IAAI,GAAU,IAAI,IAAW,EAAS,CAAC;AAEvE,QAAO;;AAGX,SAAS,EAAa,GAAa,GAAsB;CACrD,IAAM,IAAM,KAAK,MAAM,IAAM,EAAa;AAE1C,QAAO,CAAC,GADO,IAAM,IAAM,EACP;;AAGxB,SAAS,EACL,GACA,GACA,GACA,GACA,GACU;CACV,IAAM,IAAW,EAAO,MAAK,MAAK,EAAE,SAAS,OAAO,EAC9C,IAAa,EAAO,MAAK,MAAK,EAAE,SAAS,QAAQ;AAEvD,QAAO;EACH,UAAU,EAAgB,GAAW,GAAY,GAAU,IAAI,YAAY,EAAgB,OAAM,WAAW;EAC5G,UAAU,EAAgB,GAAW,GAAY,GAAU,IAAI,WAAW,EAAgB,OAAO,UAAU;EAC3G,SAAS,EAAgB,GAAW,GAAY,GAAU,IAAI,WAAW,EAAgB,MAAM,UAAU;EACzG,WAAW,EAAgB,GAAW,GAAY,GAAY,IAAI,aAAa,SAAS,YAAY;EACpG,WAAW,EAAgB,GAAW,GAAY,GAAY,IAAI,aAAA,WAAoB,YAAY;EAClG,YAAY,EAAgB,GAAW,GAAY,GAAO,SAAS,EAAgB,OAAO,YAAY;EACtG,gBAAgB,GAAO,aAAa;EACpC,2BAA2B,GAAkB,UAAU,EAAE,EAAE,KACtD,MAAU,EAAwB,GAAW,GAAY,EAAM,WAAW,YAAY,CAC1F;EACD,4BAA4B,GAAkB,UAAU,EAAE,EAAE,KACvD,MAAU,EAAwB,GAAW,GAAY,EAAM,OAAO,SAAS,EAAM,WAAW,YAAY,CAChH;EACJ;;AAGL,IAAM,IAAW,KAAK,IAAI,KAAK,KAAK,EAAE,EAChC,IAAiB;AAEvB,SAAS,EAAkB,GAAc,GAAmE;AAUxG,QATI,EAAK,UAAU,aACX,EAAK,mBAAmB,UACjB,IAEP,EAAK,mBAAmB,UACjB,IAAO,KAAY,IAAO,IAAI,IAAI,IAAiB,KAE9D,KAEG,KAAK,IAAI,GAAA,GAAiB;;AAGrC,IAAM,IAAN,MAAoB;CAChB,YAAyB;CACzB,aAAiC;CACjC,WAA+B;CAC/B,YAA2B,kBAAA,GAAA,EAAK,CAAA;CAChC,UAAmB;EACf,KAAA;EACA,QAAA;EACA,MAAA;EACA,OAAA;EACH;CACD,mBAAwD,EAAE;CAC1D,aAAyB;EACrB,YAAA;EACA,aAAA;EACA,aAAA;EACA,cAAA;EACA,YAAA;EACA,aAAA;EACH;CACD,eAAe;CACf,YAAY;CACZ,SAAuB;EACnB,GAAG,EAAC,MAAM,GAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,GAAA,IAAiB,CAAC,EAAC;EACjE,GAAG,EAAC,MAAM,GAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAA,KAAiB,EAAE,CAAC,EAAC;EACrE;CACD,gBAA+B;EAC3B,oBAAoB;EACpB,oBAAoB;EACpB,+BAA+B,EAAE;EACjC,gCAAgC,EAAE;EAClC,oBAAoB;EACpB,kBAAkB;EACrB;CACD,cAAwC,EAAE;CAC1C,YAAsB,EAAE;CACxB,qBAGI;EAAC,GAAG,EAAE;EAAE,GAAG,EAAE;EAAC;CAElB,SAAqB;EAAC,OAAO;EAAG,QAAQ;EAAG,OAAO,EAAE;EAAC;CAErD,QAAQ;AAOJ,EANI,KAAK,cAAc,KAAK,aACxB,KAAK,YAAY,YAAY,KAAK,SAAS,EAC3C,KAAK,aAAa,MAClB,KAAK,WAAW,OAGpB,iBAAiB;AAEb,GADA,KAAK,WAAW,SAAS,EACzB,KAAK,YAAY;IACnB;;CAGN,KAAK,GAAmB;AACpB,EAAI,KAAK,eAAe,SACpB,KAAK,aAAa,GAClB,KAAK,WAAW,SAAS,cAAc,MAAM,EAC7C,KAAK,WAAW,YAAY,KAAK,SAAS,EAC1C,KAAK,YAAY,EAAW,KAAK,SAAS;;CAIlD,iBAAiB,GAAwD;AAErE,EADA,KAAK,WAAW,aAAa,EAAK,OAClC,KAAK,WAAW,cAAc,EAAK;;CAGvC,sBACI,GACA,GACA,GACA,GACF;EACE,IAAM,EAAC,eAAY,mBAAe,KAAK,YACnC,IAAc,GACd,IAAa,GACX,IAAY,EAAa,GAAW,KAAK,WAAW,KAAK,aAAa;AAC5E,OAAK,mBAAmB,EAAU,QAAQ,GAA0C,GAAa,MAAU;GACvG,IAAM,CAAC,GAAY,KAAiB,EAAa,GAAO,KAAK,aAAa,EACpE,IAAiB,EAAkB,GAAO,EAAU,QAAQ,KAAK,cAAc,KAAK,UAAU,EAC9F,IAAU,EACZ,GACA,GACA,KAAK,eACL,EAAU,IACV,KAAK,aACL,GACA,GACA,GACA,MAAkB,KAAK,eAAe,GACtC,EACH,EAEK,IAAa,IAAa,EAAQ,OAAO,EAAQ,OACjD,IAAc,IAAc,EAAQ,MAAM,EAAQ;AAcxD,UAbA,EAAI,KAAO;IACP,MAAM;IACN,KAAK;IACL;IACA;IACA,OAAO;KAAC,OAAO;KAAY,QAAQ;KAAY;IAC/C,OAAO;KAAC,OAAO;KAAY,QAAQ;KAAY;IAClD,EACD,KAAe,GACX,MAAkB,KAAK,eAAe,MACtC,IAAc,GACd,KAAc,IAEX;KACR,EAAE,CAAC;EAEN,IAAM,IAAc,KAAK,IACrB,GAAG,EAAU,KAAI,MAAO,KAAK,iBAAiB,GAAK,MAAM,QAAQ,KAAK,iBAAiB,GAAK,KAAK,CACpG,EACK,IAAe,KAAK,IACtB,GAAG,EAAU,KAAI,MAAO,KAAK,iBAAiB,GAAK,MAAM,SAAS,KAAK,iBAAiB,GAAK,IAAI,CACpG;AAED,EADA,KAAK,WAAW,cAAc,GAC9B,KAAK,WAAW,eAAe;;CAGnC,eACI,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACF;EACE,IAAM,IAAa,EAAU,QACvB,IAAW,KAAK,IAAI,EAAc,SAAS,GAAY,EAAW,EAClE,IAAW,KAAK,IAAI,EAAc,SAAS,GAAY,EAAW;AAGxE,EADA,KAAK,eAAe,EAAc,QAAQ,KAAK,KAAK,IAAa,EAAS,GAAG,GAC7E,KAAK,YAAY,KAAK,KAAK,IAAa,KAAK,aAAa;EAE1D,IAAI,CAAC,GAAS,KAAW,CAAC,UAAU,UAAU,EAC1C,CAAC,GAAS,KAAW,CAAC,UAAU,UAAU,EACxC,IAAmB,EAAU,QAAQ,GAA6C,MAAQ;GAE5F,IAAM,EAAC,SAAM,SAAM,SAAM,YADR,EAAY;AAO7B,UALA,IAAU,KAAK,IAAI,GAAS,EAAK,EACjC,IAAU,KAAK,IAAI,GAAS,EAAK,EACjC,IAAU,KAAK,IAAI,GAAS,EAAK,EACjC,IAAU,KAAK,IAAI,GAAS,EAAK,EACjC,EAAI,KAAO;IAAC;IAAM;IAAM;IAAM;IAAK,EAC5B;KACR,EAAE,CAAC,EAEA,IAA+B,EAAE,EACjC,IAA+B,EAAE,EAEnC,IAAqB,IACrB,IAAqB;AACzB,IAAU,SAAQ,MAAO;GACrB,IAAI;AACJ,OAAI,CAAC,EAAiB,EAAM,CACxB,KAAS,GAA6B,CACjC,MAAM,CAAC,GAAG,KAAK,WAAW,WAAW,CAAC,CACtC,OAAO,EAAkB,QAAQ,EAAE,CAAC,CAAC,QAAQ,GAAI;QAEnD;AACH,QAAS,EAAM,UAAU,QAAQ,GAAU,GAAG,GAAa;IAC3D,IAAM,IAAU,EAAiB,IAC7B,IAAO,EAAM,aAAa,OAAO,EAAM,WAAW,GAAG,EAAc,UAAU,IAAU,EAAQ,MAC/F,IAAO,EAAM,aAAa,OAAO,EAAM,WAAW,GAAG,EAAc,UAAU,IAAU,EAAQ;AAEnG,QAAW,EAAM,mBAAmB,QAAa;KAC7C,IAAM,IAAS,EAAM;AACrB,SAAI,KAAU,KAAQ,KAAU,GAAM;MAClC,IAAM,IAAY,KAAK,IAAI,IAAS,GAAM,IAAO,EAAO;AAExD,MADA,IAAO,IAAS,GAChB,IAAO,IAAS;;;IAIxB,IAAM,IAAS,CAAC,GAAG,KAAK,WAAW,WAAW,EAExC,IAAQ,EACT,MAAM,CACN,OAAO,CAAC,GAAM,EAAK,CAAC,CACpB,MAAM,CAAC,EAAS,MAAM,KAAK,WAAW,aAAa,EAAS,MAAM,CAAC;AACxE,MACK,OAAO,CAAC,EAAM,OAAO,EAAE,EAAE,EAAM,OAAO,KAAK,WAAW,WAAW,CAAC,CAAC,CACnE,MAAM,EAAO,CACb,MAAM;;GAGf,IAAM,IAAY,KAAK,OAAO,EAAE;AAEhC,GADA,EAAW,KAAO,GAClB,MAA2C,EAAmB,GAAW,EAAO;IAClF;EAEF,IAAM,IAAqB,EAAU,QAAQ,GAA6C,OAEtF,EAAI,MADe,IAAa,EAAW,KAAO,EAAE,EAC9B,QACjB,GAAK,MAAU;GACZ,IAAM,IAAU,EAAM,UAAU,EAAM,UAAU,EAAW,GAAK,QAAQ,EAClE,IAAK,EAAM,YAAY,EAAQ,GAAa,EAC5C,IAAK,EAAM,YAAY,EAAQ,GAAa;AAGlD,UAFA,EAAI,OAAO,KAAK,IAAI,EAAI,MAAM,MAAM,EAAG,KAAK,GAAG,EAAI,OAAO,EAAG,MAAM,MAAM,EAAG,KAAK,GAAG,EAAI,OAAO,EAAG,KAAK,EACvG,EAAI,OAAO,KAAK,IAAI,EAAI,MAAM,MAAM,EAAG,MAAM,GAAG,EAAI,OAAO,EAAG,OAAO,MAAM,EAAG,MAAM,GAAG,EAAI,OAAO,EAAG,MAAM,EACpG;KAEX;GAAC,MAAM;GAAU,MAAM;GAAU,CACpC,EACD,IAAU,KAAK,IAAI,GAAS,EAAI,GAAK,KAAK,EAC1C,IAAU,KAAK,IAAI,GAAS,EAAI,GAAK,KAAK,EACnC,IACR,EAAE,CAAC;AA4CN,EA3CA,EAAU,SAAQ,MAAO;GACrB,IAAI;AACJ,OAAI,CAAC,EAAiB,EAAM,CACxB,KAAS,GAA6B,CACjC,MAAM,CAAC,KAAK,WAAW,aAAa,EAAE,CAAC,CACvC,OAAO,EAAkB,QAAQ,EAAE,CAAC,CACpC,QAAQ,GAAI;QACd;AACH,QAAS,EAAM,UAAU,QAAQ,GAAU,GAAG,GAAa;IAE3D,IAAM,IAAa,EAAiB,IAC9B,IAAe,EAAmB,IACpC,IAAO,EAAM,aAAa,OAAO,EAAM,WAAW,GAAG,EAAc,UAAU,IAAU,KAAK,IAAI,EAAW,MAAM,EAAa,KAAK,EACnI,IAAO,EAAM,aAAa,OAAO,EAAM,WAAW,GAAG,EAAc,UAAU,IAAU,KAAK,IAAI,EAAW,MAAM,EAAa,KAAK;AAEvI,QAAW,EAAM,mBAAmB,QAAa;KAC7C,IAAM,IAAS,EAAM;AACrB,SAAI,KAAU,KAAQ,KAAU,GAAM;MAClC,IAAM,IAAY,KAAK,IAAI,IAAS,GAAM,IAAO,EAAO;AAExD,MADA,IAAO,IAAS,GAChB,IAAO,IAAS;;;IAIxB,IAAM,IAAS,CAAC,KAAK,WAAW,aAAa,EAAE,EAEzC,IAAQ,EACT,MAAM,CACN,OAAO,CAAC,GAAM,EAAK,CAAC,CACpB,MAAM,CAAC,KAAK,WAAW,cAAc,EAAS,QAAQ,EAAS,IAAI,CAAC;AACzE,MACK,OAAO,CAAC,EAAM,OAAO,KAAK,WAAW,YAAY,EAAE,EAAM,OAAO,EAAE,CAAC,CAAC,CACpE,MAAM,EAAO,CACb,MAAM;;GAEf,IAAM,IAAY,KAAK,OAAO,EAAE;AAEhC,GADA,EAAW,KAAO,GAClB,MAA2C,EAAmB,GAAW,EAAO;IAClF,EAEE,MACA,KAAK,OAAO,IAAI,IAEhB,MACA,KAAK,OAAO,IAAI;;CAIxB,mBACI,GACA,GACA,GACA,GACF;EACE,IAAM,IAAe,IAAI,EAAa,mBAAmB;EACzD,SAAS,EAAgB,GAAiB;AACtC,UAAO,KAAK,IAAI,GAAG,EAAM,KAAI,MAAO,EAAa,aAAa,EAAI,CAAC,CAAC;;EAGxE,IAAI,IAAQ,GACR,IAAQ,GACR,IAAoC,EAAE,EACtC,IAAwC,EAAE,EAC1C,IAAgB,GAChB,IAAgB;AACpB,MAAI,EAAM,UAAU,YAAY;GAC5B,IAAM,IAAQ,EACV,GACA,KAAK,WACL,KAAK,cACL,EAAM,kBAAkB,UACxB,KAAK,mBAAmB,GACxB,YACA,KAAK,OAAO,EACf;AAED,GADA,IAAQ,EAAM,OACd,IAA2B,EAAM;QAEjC,KAAgB;AAGpB,MAAI,EAAM,UAAU,YAAY;GAC5B,IAAM,IAAQ,EACV,GACA,KAAK,WACL,KAAK,cACL,EAAM,kBAAkB,UACxB,KAAK,mBAAmB,GACxB,cACA,KAAK,OAAO,EACf;AAED,GADA,IAAQ,EAAM,OACd,IAA8B,EAAM;QAEpC,QAAO,OAAO,KAAK,OAAO,EAAE,CAAC,SAAQ,MAAS;GAC9C,IAAM,EAAC,UAAO,cAAU,EAAkB,GAAO,EAAa;AAC9D,OAAgB,KAAK,IAAI,GAAe,EAAgB,EAAM,IAAI,EAAO,CAAC,CAAC;IAC7E;AAGF,OAAK,gBAAgB;GACjB,oBAAoB,EAAM,eAAe,IAAI,EAAiB,GAAe,EAAM;GACnF,oBAAoB,EAAM,eAAe,IAAI,EAAiB,GAAe,EAAM;GACnF,+BAA+B;GAC/B,gCAAgC;GAChC,oBAAoB;GACpB,kBAAkB;GACrB;;CAGL,gBAAgB,GAAqB,GAA0D;EAC3F,IAAM,IAAa,KAAK,iBAAiB,EAAU,KAC7C,IAAY,KAAK,iBAAiB,EAAU,EAAU,SAAS;AAErE,OAAK,YAAY,EACb,EAAM,MACN,KAAK,WAAW,cAAc,EAAW,QAAQ,OAAO,EAAU,QAAQ,OAC1E,GACH;;CAGL,kBAAkB,GAAqB,GAAyB;AAC5D,OAAK,cAAc,EAAU,QAAQ,GAA+B,GAAK,OACjE,EAAY,GAAK,WAAW,KAAK,EAAY,GAAK,OAAO,SACzD,EAAI,KAAO,EAAE,GAEb,EAAI,KAAO,EAAiB,EAAY,GAAK,KAAK,KAAK,EAAE,KAAK,WAAW,YAAY,GAAG,EAErF,IACR,EAAE,CAAC;;CAGV,iBACI,GACA,GACA,GACA,GACA,GACF;AACE,OAAK,qBAAqB;GACtB,GAAG,EAAM,UAAU,aAAkB,EACjC,GACC,GAAgC,kBAAkB,UACnD,EAAkB,QAClB,IACA,YACA,KAAK,OAAO,EACf,GAP+B,EAAE;GAQlC,GAAG,EAAM,UAAU,aAAkB,EACjC,GACC,EAAgC,kBAAkB,UACnD,EAAkB,QAClB,IACA,cACA,KAAK,OAAO,EACf,GAP+B,EAAE;GAQrC;;CAGL,cAAc,GAAqB;EAC/B,IAAM,IAAA,KAAsC,KAAK,UAAU,QACrD,IAAc,IAAkB,IAAI,IAAA,KAAqC,GACzE,IAAa,KAAK,iBAAiB,EAAU,KAC7C,IAAY,KAAK,iBAAiB,EAAU,EAAU,SAAS;AAQrE,EAPA,KAAK,UAAU;GACX,KAAK,KAAK,IAAI,GAAA,GAAwB;GACtC,QAAQ,KAAK,IAAA,IAAgB,KAAK,cAAc,mBAAmB,EAAU,QAAQ,OAAO;GAC5F,MAAM,KAAK,IAAA,IAAgB,KAAK,cAAc,qBAAqB,EAAW,QAAQ,KAAK;GAC3F,OAAO,KAAK,OAAO,QAAA;GACtB,EACD,KAAK,WAAW,aAAa,KAAK,QAAQ,OAAO,KAAK,WAAW,cAAc,KAAK,QAAQ,OAC5F,KAAK,WAAW,cACZ,KAAK,QAAQ,MAAM,KAAK,IAAI,KAAK,WAAW,cAAc,KAAK,OAAO,OAAO,GAAG,KAAK,QAAQ;;CAGrG,iBACI,GACA,GACA,GACA,GACA,GACA,GACF;AACE,MAAI,CAAC,EAAO,MAAM;AACd,QAAK,SAAS;IAAC,OAAO;IAAG,QAAQ;IAAG,OAAO,EAAE;IAAC;AAC9C;;EAGJ,IAAM,IAA4B,EAAE,EAC9B,IAAa;GAAC,OAAM;GAAG,QAAO;GAAG,MAAK;GAAG,KAAK;GAAE,EAChD,IAAmB,KAAK,IAC1B,KAAK,IAAI,KAAK,WAAW,aAAA,IAAwC,EAAA,IAEpE,EACK,IAAe,KAAK,IAAI,KAAK,WAAW,aAAa,EAAiB;AAyD5E,MAxDA,EAAS,SAAQ,MAAU;GACvB,IAAM,IAAO,EAAW,EAAO;AAC/B,OAAI,EAAK,QAAQ,WAAW,KAAK,CAAC,EAAK,OACnC;AAEJ,OAAI,EAAK,OAAO,SAAA,KAA4C;AACxD,YAAQ,KAAK,wCAAwC,EAAK,OAAO,OAAO,GAAG;AAC3E;;GAEJ,IAAM,IAAsC,EAAE;AAC9C,KAAK,OAAO,SAAQ,MAAe;AAI/B,IAHK,EAAQ,OACT,EAAQ,KAAe,EAAC,GAAG,GAAgB,GAE/C,EAAK,QAAQ,SAAQ,MAAO;AAOxB,MANI,MAAQ,aAAa,MAAQ,iBAC7B,EAAQ,GAAa,QAAS,EAAK,OAAO,GAAa,EAAI,IAAA,YAE3D,MAAQ,eACR,EAAQ,GAAa,QAAS,EAAK,OAAO,GAAY,EAAI,IAAI,OAE9D,MAAQ,cACR,EAAQ,GAAa,OAAQ,EAAK,OAAO,GAAY,EAAI,IAAI;MAEnE;KACJ;GAEF,IAAM,IAAQ,EAAO,SAAS,EAAO,OAC/B,IAAQ,GAA0B,CACnC,OAAO,EAAK,OAAO,CACnB,MAAM,EAAK,OAAO,KAAI,MAAS,EAAQ,GAAO,CAAC,CAC/C,QAAQ,EAAgB;AAC7B,KAAY,KAAK;IAAC,GAAG;IAAY,IAAI,EAAO;IAAO,MAAM;IAAQ;IAAO;IAAO,QAAO,EAAK;IAAQ,QAAO,EAAK;IAAO,CAAC;IACzH,EAEF,EAAO,SAAQ,MAAS;AACpB,OAAI,EAAM,SAAS,UAAU,EAAgB,EAAM,IAAI,QAAQ,EAAE;IAC7D,IAAM,EAAC,WAAQ,UAAO,eAAY,UAAO,aAAY,EAAM,IAAI,SACzD,IAAQ,EAAW,SAAS,EAAW,OACvC,IAAa,EAAwB,GAAO,GAAQ,SAAS,EAC7D,KAAqB,MAAS,QAAQ,GAA6B,GAAG,GAA6B,EACpG,OAAO,EAAO,CAEd,MAAM,CAAC,GAAkB,EAAE,CAAC,EAC3B,IAAS,EAAyB,GAAmB,EAA2B;AACtF,MAAY,KAAK;KAAC,GAAG;KAAY,IAAI;KAAW,MAAM;KAAc;KAAO,OAAO;KAAY;KAAmB;KAAO,CAAC;;AAE7H,GAAI,EAAM,SAAS,UAAU,EAAgB,EAAM,IAAI,QAAQ,IAC3D,EAAY,KAAK,EAAkB,EAAM,IAAI,QAAQ,CAAC;IAE5D,EAME,KAAoB,EAAiB,OAAO,SAAS,GAAG;GAKxD,IAAM,IAAe,GACf,IAA8B,EAAE,EAChC,IAA4C,EAAE,EAC9C,IAA0C,EAAE,EAC5C,IAAa,EAAO,MAAK,MAAK,EAAE,SAAS,QAAQ;AACvD,OAAI,GAAY;IACZ,IAAM,IAAQ,EAAQ,SAAS,EAAQ,OACjC,IAAgB,OAAO,EAAW,IAAI,aAAc,WACpD,EAAW,IAAI,YACf;AAGN,IAFA,EAAkB,KAAK,EAAM,EAC7B,EAAkB,KAAS,GAC3B,EAAe,KAAS;KACpB,WAAW,EAAW,IAAI;KAC1B,WAAW;KACd;;AAEL,QAAK,IAAM,KAAS,EAAiB,QAAQ;IAEzC,IAAI,IAAM,EAAM,OACZ,IAAgB;AACpB,WAAO,EAAkB,SAAS,EAAI,EAClC,KAAM,GAAG,EAAM,MAAM,IAAI,EAAE,EAAc;IAE7C,IAAM,IAAgB,OAAO,EAAM,aAAc,WAC3C,EAAM,YACN;AAGN,IAFA,EAAkB,KAAK,EAAI,EAC3B,EAAkB,KAAO,GACzB,EAAe,KAAO;KAClB,WAAW,EAAM;KACjB,WAAW;KACd;;AAEL,OAAI,EAAkB,SAAS,GAAG;IAC9B,IAAM,IAAQ,GAAuB,CAChC,OAAO,EAAkB,CACzB,MAAM,EAAkB,KAAI,MAAK,EAAe,GAAG,CAAC,CACpD,QAAQ,EAAE,CAAC;AAChB,MAAY,KAAK;KACb,GAAG;KACH,IAAI;KACJ,MAAM;KACN,OAAO;KACP;KACA,QAAQ;KACR,QAAQ;KACR,SAAS;MAAE,WAAW;MAAM,WAAW;MAAM,SAAS;MAAO,UAAU;MAAO,WAAW;MAAO;KACnG,CAAC;;;AAIV,MAAI,CAAC,EAAY,QAAQ;AACrB,QAAK,SAAS;IAAC,OAAO;IAAG,QAAQ;IAAG,OAAO,EAAE;IAAC;AAC9C;;EAGJ,IAAM,IAAQ,EAAmB,GAAa,GAAc,EAAiB;AAK7E,OAAK,SAAS;GACV,OAJiB,EAAM,QAAQ,GAAK,MAAS,KAAK,IAAI,GAAK,EAAK,OAAO,EAAK,MAAM,EAAE,EAAE,GAAA;GAKtF,QAAQ;GACR;GACH;;CAGL,OACI,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACF;EACE,IAAM,EAAC,UAAO,UAAO,SAAM,UAAO,cAAU;AAS5C,EARA,KAAK,iBAAiB,EAAK,EAC3B,KAAK,eAAe,GAAW,GAAe,GAAO,GAAO,GAAmB,GAAmB,GAAa,EAAW,EAC1H,KAAK,iBAAiB,GAAW,GAAO,GAAO,GAAmB,EAAkB,EACpF,KAAK,mBAAmB,GAAW,GAAO,GAAO,EAAa,EAAE,EAChE,KAAK,kBAAkB,GAAW,EAAY,EAC9C,KAAK,sBAAsB,GAAW,GAAe,GAAO,EAAM,EAClE,KAAK,iBAAiB,GAAQ,GAAY,GAAU,GAAQ,GAAkB,EAAQ,EACtF,KAAK,gBAAgB,GAAW,EAAM,EACtC,KAAK,cAAc,EAAU;EAC7B,IAAM,IACF,kBAAC,GAAD;GAA8B;aAC1B,kBAAC,GAAD;IACgB;IACG;IACJ;IACI;IACf,YAAY,KAAK;IACjB,kBAAkB,KAAK;IACvB,QAAQ,KAAK;IACA;IACD;IACZ,YAAY,KAAK;IACjB,cAAc,KAAK;IACnB,SAAS,KAAK;IACH;IACX,WAAW,KAAK;IAChB,aAAa,KAAK;IAClB,eAAe,KAAK;IACN;IACF;IACZ,YAAY,EAAiB,GAAW,GAAY,GAAQ,GAAO,EAAiB;IAC/D;IACrB,oBAAoB,KAAK;IAC3B,CAAA;GACc,CAAA;AAGxB,EADA,KAAK,YAAY,GACjB,KAAK,WAAW,OAAO,EAAU;;CAGrC,YAAY,GAAiB;AACzB,OAAK,WAAW,OAAO,kBAAC,GAAD,EAAgB,YAAW,CAAA,CAAC"}
|
|
@@ -84,6 +84,7 @@ export declare class ScatterplotSettingsImpl implements SettingsInterface {
|
|
|
84
84
|
readonly trend: {
|
|
85
85
|
bounded: boolean;
|
|
86
86
|
color: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;
|
|
87
|
+
lineWidth: number;
|
|
87
88
|
} | null;
|
|
88
89
|
readonly additionalCurves: {
|
|
89
90
|
curves: (AdditionalCurveEntry & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScatterplotSettingsImpl.d.ts","sourceRoot":"","sources":["../../src/scatterplot/ScatterplotSettingsImpl.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ScatterplotSettingsImpl.d.ts","sourceRoot":"","sources":["../../src/scatterplot/ScatterplotSettingsImpl.ts"],"names":[],"mappings":"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"}
|
|
@@ -92,7 +92,8 @@ var i = class {
|
|
|
92
92
|
}
|
|
93
93
|
}, this.trend = e?.trend && this.chartSettings.xAxis.scale !== "discrete" && this.chartSettings.yAxis.scale !== "discrete" ? {
|
|
94
94
|
bounded: e.trend.bounded ?? !1,
|
|
95
|
-
color: e.trend.color ?? "#110529"
|
|
95
|
+
color: e.trend.color ?? "#110529",
|
|
96
|
+
lineWidth: e.trend.lineWidth ?? 1
|
|
96
97
|
} : null;
|
|
97
98
|
let o = [
|
|
98
99
|
"dashed",
|