@milaboratories/miplots4 1.0.178 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/bubble/BubbleSettingsImpl.d.ts +2 -0
  2. package/dist/bubble/BubbleSettingsImpl.d.ts.map +1 -1
  3. package/dist/bubble/BubbleSettingsImpl.js +3 -1
  4. package/dist/bubble/BubbleSettingsImpl.js.map +1 -1
  5. package/dist/bubble/getGroupedCellsData.d.ts +1 -1
  6. package/dist/bubble/getGroupedCellsData.d.ts.map +1 -1
  7. package/dist/bubble/getGroupedCellsData.js +30 -10
  8. package/dist/bubble/getGroupedCellsData.js.map +1 -1
  9. package/dist/bubble/index.d.ts.map +1 -1
  10. package/dist/bubble/index.js +3 -3
  11. package/dist/bubble/index.js.map +1 -1
  12. package/dist/heatmap/ChartRenderer.d.ts.map +1 -1
  13. package/dist/heatmap/ChartRenderer.js +26 -20
  14. package/dist/heatmap/ChartRenderer.js.map +1 -1
  15. package/dist/heatmap/HeatmapSettingsImpl.d.ts +2 -0
  16. package/dist/heatmap/HeatmapSettingsImpl.d.ts.map +1 -1
  17. package/dist/heatmap/HeatmapSettingsImpl.js +3 -1
  18. package/dist/heatmap/HeatmapSettingsImpl.js.map +1 -1
  19. package/dist/heatmap/fillCellsData.d.ts +22 -2
  20. package/dist/heatmap/fillCellsData.d.ts.map +1 -1
  21. package/dist/heatmap/fillCellsData.js +60 -47
  22. package/dist/heatmap/fillCellsData.js.map +1 -1
  23. package/dist/heatmap/getCells.d.ts +22 -1
  24. package/dist/heatmap/getCells.d.ts.map +1 -1
  25. package/dist/heatmap/getCells.js +23 -3
  26. package/dist/heatmap/getCells.js.map +1 -1
  27. package/dist/heatmap/getDendrograms.d.ts +5 -1
  28. package/dist/heatmap/getDendrograms.d.ts.map +1 -1
  29. package/dist/heatmap/getDendrograms.js +33 -11
  30. package/dist/heatmap/getDendrograms.js.map +1 -1
  31. package/dist/heatmap/index.d.ts.map +1 -1
  32. package/dist/heatmap/index.js +30 -6
  33. package/dist/heatmap/index.js.map +1 -1
  34. package/dist/scatterplot/ChartRenderer.d.ts +2 -2
  35. package/dist/scatterplot/ChartRenderer.d.ts.map +1 -1
  36. package/dist/scatterplot/ChartRenderer.js +155 -115
  37. package/dist/scatterplot/ChartRenderer.js.map +1 -1
  38. package/dist/scatterplot/ScatterplotSettingsImpl.d.ts +11 -1
  39. package/dist/scatterplot/ScatterplotSettingsImpl.d.ts.map +1 -1
  40. package/dist/scatterplot/ScatterplotSettingsImpl.js +20 -0
  41. package/dist/scatterplot/ScatterplotSettingsImpl.js.map +1 -1
  42. package/dist/scatterplot/components/ChartLayersData.d.ts +5 -0
  43. package/dist/scatterplot/components/ChartLayersData.d.ts.map +1 -1
  44. package/dist/scatterplot/components/ChartLayersData.js +115 -35
  45. package/dist/scatterplot/components/ChartLayersData.js.map +1 -1
  46. package/dist/scatterplot/components/types.d.ts +2 -0
  47. package/dist/scatterplot/components/types.d.ts.map +1 -1
  48. package/dist/scatterplot/getLayersData.d.ts +11 -2
  49. package/dist/scatterplot/getLayersData.d.ts.map +1 -1
  50. package/dist/scatterplot/getLayersData.js +36 -19
  51. package/dist/scatterplot/getLayersData.js.map +1 -1
  52. package/dist/scatterplot/index.d.ts.map +1 -1
  53. package/dist/scatterplot/index.js +51 -33
  54. package/dist/scatterplot/index.js.map +1 -1
  55. package/dist/scatterplot/linearRegression.js +1 -1
  56. package/dist/scatterplot/utils/createAesGetter.d.ts.map +1 -1
  57. package/dist/scatterplot/utils/createAesGetter.js +5 -3
  58. package/dist/scatterplot/utils/createAesGetter.js.map +1 -1
  59. package/dist/scatterplot/utils/createLegendInfo.d.ts +11 -2
  60. package/dist/scatterplot/utils/createLegendInfo.d.ts.map +1 -1
  61. package/dist/scatterplot/utils/createLegendInfo.js +21 -16
  62. package/dist/scatterplot/utils/createLegendInfo.js.map +1 -1
  63. package/dist/scatterplot-umap/ChartRenderer.d.ts +6 -6
  64. package/dist/scatterplot-umap/ChartRenderer.d.ts.map +1 -1
  65. package/dist/scatterplot-umap/ChartRenderer.js +99 -57
  66. package/dist/scatterplot-umap/ChartRenderer.js.map +1 -1
  67. package/dist/scatterplot-umap/SettingsImpl.d.ts +11 -1
  68. package/dist/scatterplot-umap/SettingsImpl.d.ts.map +1 -1
  69. package/dist/scatterplot-umap/SettingsImpl.js +21 -1
  70. package/dist/scatterplot-umap/SettingsImpl.js.map +1 -1
  71. package/dist/scatterplot-umap/components/LowerSVG.d.ts +3 -2
  72. package/dist/scatterplot-umap/components/LowerSVG.d.ts.map +1 -1
  73. package/dist/scatterplot-umap/components/LowerSVG.js +159 -108
  74. package/dist/scatterplot-umap/components/LowerSVG.js.map +1 -1
  75. package/dist/scatterplot-umap/components/SVGLayer.d.ts +1 -1
  76. package/dist/scatterplot-umap/components/SVGLayer.d.ts.map +1 -1
  77. package/dist/scatterplot-umap/components/SVGLayer.js +9 -8
  78. package/dist/scatterplot-umap/components/SVGLayer.js.map +1 -1
  79. package/dist/scatterplot-umap/index.d.ts +6 -1
  80. package/dist/scatterplot-umap/index.d.ts.map +1 -1
  81. package/dist/scatterplot-umap/index.js +65 -31
  82. package/dist/scatterplot-umap/index.js.map +1 -1
  83. package/dist/scatterplot-umap/types.d.ts +7 -0
  84. package/dist/scatterplot-umap/types.d.ts.map +1 -1
  85. package/dist/types/bubble.d.ts +6 -0
  86. package/dist/types/bubble.d.ts.map +1 -1
  87. package/dist/types/bubble.js +3 -1
  88. package/dist/types/bubble.js.map +1 -1
  89. package/dist/types/heatmap.d.ts +6 -0
  90. package/dist/types/heatmap.d.ts.map +1 -1
  91. package/dist/types/heatmap.js +2 -0
  92. package/dist/types/heatmap.js.map +1 -1
  93. package/dist/types/scatterplot-umap.d.ts +763 -87
  94. package/dist/types/scatterplot-umap.d.ts.map +1 -1
  95. package/dist/types/scatterplot-umap.js +19 -3
  96. package/dist/types/scatterplot-umap.js.map +1 -1
  97. package/dist/types/scatterplot.d.ts +1377 -44
  98. package/dist/types/scatterplot.d.ts.map +1 -1
  99. package/dist/types/scatterplot.js +27 -3
  100. package/dist/types/scatterplot.js.map +1 -1
  101. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/scatterplot-umap/ChartRenderer.tsx"],"sourcesContent":["import { chartCartesian } from '@d3fc/d3fc-chart';\nimport type { CartesianChart } from '@d3fc/d3fc-chart/src/cartesian';\nimport type { ScaleLinear } from 'd3-scale';\nimport { scaleLinear, scaleLog, scaleOrdinal, scaleSymlog } from 'd3-scale';\nimport { select } from 'd3-selection';\nimport type { D3ZoomEvent, ZoomBehavior, ZoomTransform } from 'd3-zoom';\nimport { zoom, zoomIdentity } from 'd3-zoom';\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 {\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 { splitTextByWidth } from '../discrete/utils';\nimport { DEFAULT_DOT_AES, MIN_MARGIN } from '../scatterplot/constants';\nimport { createAesGetter } from '../scatterplot/utils/createAesGetter';\nimport { getTicksAndFormat } from '../scatterplot/utils/getTicksAndFormat';\nimport type { Label } from '../scatterplot/utils/getVisibleLabels';\nimport { createLabelPositioner } from '../scatterplot/utils/getVisibleLabels';\nimport type { ColumnName, ScatterplotEventHandlers } from '../types';\nimport { isContinuousAes } from '../types';\nimport type { ScatterplotUmapLegendInfo } from '../types/scatterplot-umap';\nimport { getContinuousColorScale } from '../utils/getContinuousColorScale';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { SVGLayer } from './components/SVGLayer';\nimport { LEGEND_OFFSET, PADDINGS, TITLE_LINE } from './constants';\nimport type { CurveLayer, DotsLayer, ScatterplotUmapLayer, ScatterplotUmapSettingsImpl } from './SettingsImpl';\nimport type {\n AesGetters,\n CaptionsSizes,\n ChartScales, ChartSizes,\n Dot,\n DotsExtents,\n LassoControlsState,\n Margins,\n Polygon,\n SVGLayerProps,\n} from './types';\n// @ts-ignore\nimport { seriesSvgMulti, seriesWebglMulti, seriesWebglPoint } from '@d3fc/d3fc-series';\n// @ts-ignore\nimport { webglFillColor } from '@d3fc/d3fc-webgl';\n// @ts-ignore\nimport { pointer } from '@d3fc/d3fc-pointer';\nimport { polygonContains } from 'd3-polygon';\nimport KDBush from 'kdbush';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport { DataFrame } from '../DataFrame';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { GET_BLACK, getColorWithFakeOpacity, stringToNumberRgba } from './colors';\nimport { getSizeLegendItem } from '../utils/getSizeLegendItem';\n\nfunction convertDotRToSymbolSize(r:number) {\n return (r / 2.35) * (r / 2.35) * 64;\n}\n\nfunction isDotInsidePolygons(x:number, y:number, polygons: Polygon[]) {\n if (polygons.length === 0) {\n return true;\n }\n return polygons.some((p) => p.closed && p.points.length > 2 && polygonContains(p.points, [x, y]));\n}\n\nfunction getGettersFromLayers(\n dataFrame: DataFrame,\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers'],\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 return {\n dotFill: 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 lineType: createAesGetter(dataFrame, legendInfo, curveLayer?.aes.lineShape ?? 'solid', 'lineShape')\n };\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n canvasNode: HTMLElement | null = null;\n\n svgLayerElement: SVGElement | null = null;\n svgLayerComponent: ReactElement = (<></>);\n\n aesGetters: AesGetters = {\n dotSize: () => 2,\n dotFill: () => BLACK,\n lineType: () => 'solid'\n };\n\n tools: {\n webglChart: CartesianChart<unknown, unknown>;\n qt?: KDBush;\n fillColor: () => {\n value: (setter: (d: Dot) => [number, number, number, number]) => void;\n data: (setter: () => Dot[]) => void;\n };\n pointSeries: () => unknown;\n zoom: ZoomBehavior<Element, unknown>;\n } | null = null;\n\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\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 scales: ChartScales = {\n x: scaleLinear().domain([0, 10]).range([0, DEFAULT_WIDTH]),\n y: scaleLinear().domain([0, 10]).range([DEFAULT_HEIGHT, 0]),\n xOriginal: scaleLinear().domain([0, 10]).range([0, DEFAULT_WIDTH]),\n yOriginal: scaleLinear().domain([0, 10]).range([DEFAULT_HEIGHT, 0]),\n };\n\n polygons:Polygon[] = [];\n onPolygonUpdateOutside: ScatterplotEventHandlers['onPolygonUpdate'] = () => undefined;\n onTooltipHintSwitch: ScatterplotEventHandlers['onTooltipHintSwitch'] = () => undefined;\n onLassoControlsStateUpdate: ScatterplotEventHandlers['onLassoControlsStateUpdate'] = () => undefined;\n\n zoomTransform: ZoomTransform | null = null;\n zoomStateKey = '';\n selectedDot: Dot | null = null;\n captionsSizes: CaptionsSizes = {\n xAxisCaptionsWidth: 30,\n yAxisCaptionsWidth: 100,\n };\n mainTitle: string[] = []; // can be multiline\n legend: LegendData = {width: 0, height: 0, items: []};\n\n notCalculatedProps: Partial<SVGLayerProps> = {};\n\n allDots: Dot[] = [];\n visibleLabels: Label[] = [];\n dataFrame: DataFrame = new DataFrame('', {});\n\n clear() {\n if (this.parentNode && this.rootNode && this.canvasNode) {\n this.parentNode?.removeChild(this.rootNode);\n this.parentNode?.removeChild(this.canvasNode);\n this.parentNode = null;\n this.rootNode = null;\n this.canvasNode = null;\n this.svgLayerElement = null;\n this.tools = 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.canvasNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.parentNode.appendChild(this.canvasNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateChartSizes(size: ScatterplotUmapSettingsImpl['chartSettings']['size']) {\n if (size.width !== this.chartSizes.chartWidth || size.height !== this.chartSizes.chartHeight) {\n // NB: now chart sizes always change with one multiplier for width/height so qt stays without changes\n this.chartSizes.chartWidth = size.width;\n this.chartSizes.chartHeight = size.height;\n this.scales.x.range([0, this.chartSizes.chartWidth]);\n this.scales.y.range([this.chartSizes.chartHeight, 0]);\n }\n \n }\n\n updateViewport(\n xAxis: ScatterplotUmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotUmapSettingsImpl['chartSettings']['yAxis'],\n dotsExtents: DotsExtents,\n ) {\n const scaleX = xAxis.scale === 'log' ? scaleLog() : scaleLinear();\n\n let {minX, minY, maxX, maxY} = dotsExtents;\n if (xAxis.lowerValue !== undefined) {\n minX = Math.max(minX, xAxis.lowerValue);\n }\n if (xAxis.upperValue !== undefined) {\n maxX = Math.min(maxX, xAxis.upperValue);\n }\n if (yAxis.lowerValue !== undefined) {\n minY = Math.max(minY, yAxis.lowerValue);\n }\n if (yAxis.upperValue !== undefined) {\n maxY = Math.min(maxY, yAxis.upperValue);\n }\n if (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 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 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 // this.scales.x = scaleX;\n // this.scales.xOriginal = scaleX.copy();\n this.scales.x.domain(scaleX.domain());\n this.scales.xOriginal.domain(scaleX.domain());\n\n const scaleY = yAxis.scale === 'log' ? scaleLog() : scaleLinear();\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 // this.scales.y = scaleY;\n // this.scales.yOriginal = scaleY.copy();\n this.scales.y.domain(scaleY.domain());\n this.scales.yOriginal.domain(scaleY.domain());\n }\n\n updateCaptionsSize() {\n const textMeasurer = new TextMeasurer('600 14px Arial');\n\n function getMaxTickWidth(ticks: string[]) {\n return Math.max(...ticks.map(key => textMeasurer.getTextWidth(key)));\n }\n\n const {ticks, format} = getTicksAndFormat(this.scales.y, false);\n const maxYTick = getMaxTickWidth(ticks.map(format));\n\n this.captionsSizes = {\n xAxisCaptionsWidth: 20,\n yAxisCaptionsWidth: maxYTick,\n };\n }\n\n createMainTitle(title: ScatterplotUmapSettingsImpl['chartSettings']['title']) {\n this.mainTitle = splitTextByWidth(\n title.name,\n this.chartSizes.totalWidth - this.margins.left - this.margins.right,\n 20\n );\n }\n\n updateMargins(xAxis: ScatterplotUmapSettingsImpl['chartSettings']['xAxis'], yAxis: ScatterplotUmapSettingsImpl['chartSettings']['yAxis']) {\n const titleTextHeight = TITLE_LINE_HEIGHT * this.mainTitle.length;\n const titleHeight = titleTextHeight > 0 ? titleTextHeight + TITLE_MARGIN * 2 : 0;\n this.margins = {\n top: Math.max(titleHeight, MIN_MARGIN),\n bottom: MIN_MARGIN + (xAxis.hiddenLabels ? 0 : this.captionsSizes.xAxisCaptionsWidth) + TITLE_LINE,\n left: MIN_MARGIN + (yAxis.hiddenLabels ? 0 : this.captionsSizes.yAxisCaptionsWidth) + TITLE_LINE,\n right: this.legend.width + MIN_MARGIN,\n };\n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartHeight, this.legend.height) + this.margins.bottom;\n\n select(this.canvasNode)\n .style('width', this.chartSizes.chartWidth + 'px')\n .style('height', this.chartSizes.chartHeight + 'px')\n .style('top', this.margins.top + 'px')\n .style('left', this.margins.left + 'px');\n }\n\n updateLegendSize(\n legend: ScatterplotUmapSettingsImpl['chartSettings']['legend'],\n legendLabels: ScatterplotUmapLegendInfo,\n grouping: ColumnName[],\n layers: ScatterplotUmapLayer[]\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 = legendLabels[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(category => {\n if (!aesData[category]) {\n aesData[category] = {...DEFAULT_DOT_AES} as DotAesItem;\n }\n info.usedAes.forEach(key => {\n if (key === 'dotFill') {\n aesData[category].color = (info.aesMap(category, key) ?? BLACK) as string;\n }\n if (key === 'dotSize') {\n aesData[category].size = Number(info.aesMap(category, key) ?? 3);\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 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 if (!legendItems.length) {\n this.legend = {width: 0, height: 0, items: []};\n return;\n }\n\n const items = arrangeLegendParts(legendItems, legendHeight, continuousHeight);\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 initSettings(\n dots: Dot[],\n chartSettings: ScatterplotUmapSettingsImpl['chartSettings'],\n dotExtents: DotsExtents,\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers'],\n grouping: ColumnName[],\n onZoomChange: (v:boolean) => void,\n ) {\n const {xAxis, yAxis, size, title, legend} = chartSettings;\n this.updateChartSizes(size);\n this.updateViewport(xAxis, yAxis, dotExtents);\n this.updateCaptionsSize();\n this.updateLegendSize(legend, legendInfo, grouping, layers);\n this.createMainTitle(title);\n this.updateMargins(xAxis, yAxis);\n\n this.aesGetters = getGettersFromLayers(this.dataFrame, legendInfo, layers);\n\n const fillColor = webglFillColor()\n .data(dots)\n .value((d: Dot) => {\n const rgba = stringToNumberRgba(this.aesGetters.dotFill(d.idx));\n rgba[3] = !d.dimmed && isDotInsidePolygons(d.x, d.y, this.polygons) ? 1 : 0.4;\n return getColorWithFakeOpacity(rgba, rgba);\n });\n\n const pointSeries = seriesWebglPoint()\n .equals((a: Dot[], b: Dot[]) => a === b)\n .size((d: Dot) => convertDotRToSymbolSize(this.aesGetters.dotSize(d.idx)))\n .crossValue((d: Dot) => d.x)\n .mainValue((d: Dot) => d.y)\n .decorate((program: unknown) => fillColor(program));\n\n const z = zoom()\n .scaleExtent([0.1, 1000])\n .filter((e:MouseEvent) => {\n return e.type === 'wheel' || e.metaKey || e.ctrlKey;\n })\n .on('start', () => {\n this.selectedDot = null;\n })\n .on('zoom', (e: D3ZoomEvent<SVGElement, unknown>) => {\n const transform = e.transform;\n const x = transform.rescaleX(this.scales.xOriginal);\n const y = transform.rescaleY(this.scales.yOriginal);\n this.scales.x.domain(x.domain());\n this.scales.y.domain(y.domain());\n\n this.zoomTransform = transform;\n this.zoomStateKey = `${transform.x}_${transform.y}_${transform.k}`; // need it to update axes\n\n this.updateLabelsPosition(this.visibleLabels);\n this.renderSvgLayer();\n this.renderWebglLayer();\n }).on('end', () => {\n this.visibleLabels = this.computeLabels(this.allDots);\n this.renderSvgLayer();\n onZoomChange(true);\n });\n \n // @ts-ignore\n const p = pointer().on('point', ([coord]) => {\n let closestDatum;\n if (coord) {\n closestDatum = this.getClosestDot(coord.x, coord.y);\n }\n \n const needRedraw =\n (this.selectedDot && !closestDatum) ||\n (!this.selectedDot && closestDatum) ||\n this.selectedDot?.idx !== closestDatum?.idx;\n\n this.selectedDot = closestDatum ?? null;\n\n if (needRedraw) {\n this.renderSvgLayer();\n }\n });\n\n const webglChart = chartCartesian({\n xScale: this.scales.x,\n yScale: this.scales.y,\n })\n .xAxisHeight(() => '0') // removing build-in axes from chartCartesian\n .yAxisWidth(() => '0') // removing build-in axes from chartCartesian\n .svgPlotArea(seriesSvgMulti())\n .webglPlotArea(\n // only render the point series on the WebGL layer\n seriesWebglMulti()\n .series([pointSeries])\n .mapping((d: unknown) => d)\n )\n .decorate(selection => {\n const s = selection.enter();\n if (s && !this.svgLayerElement) {\n s.style('grid-template-columns', '0 auto 1fr auto 0'); // removing build-in axes from chartCartesian\n s.style('grid-template-rows', '0 auto 1fr auto 0'); // removing build-in axes from chartCartesian\n this.svgLayerElement = s.select('.svg-plot-area.plot-area svg').node() as SVGElement;\n }\n s.select('.svg-plot-area.plot-area').attr('class', 'svg-plot-area plot-area miplots-scatterplot-plot-area')\n \n // @ts-ignore\n .call(z)\n .call(p);\n });\n\n this.tools = {\n webglChart,\n zoom: z,\n fillColor,\n pointSeries,\n };\n\n select(this.canvasNode)\n .datum(dots)\n .style('position', 'absolute')\n .style('width', this.chartSizes.chartWidth + 'px')\n .style('height', this.chartSizes.chartHeight + 'px')\n .style('top', this.margins.top + 'px')\n .style('left', this.margins.left + 'px');\n this.onPolygonUpdate(this.polygons);\n }\n\n resetZoom(\n xAxis: ScatterplotUmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotUmapSettingsImpl['chartSettings']['yAxis'],\n dotsExtents?: DotsExtents\n ) {\n if (!this.tools?.zoom || !dotsExtents) {\n return;\n }\n this.updateViewport(xAxis, yAxis, dotsExtents);\n select('.miplots-scatterplot-plot-area').call((this.tools.zoom.transform as (selection: unknown, transform: unknown) => void), zoomIdentity);\n }\n\n updateAes(\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers']\n ) {\n if (this.tools === null) {\n return;\n }\n this.aesGetters = getGettersFromLayers(this.dataFrame, legendInfo, layers);\n \n // @ts-ignore\n this.tools.fillColor.value((d: Dot) => {\n const colorGetter = this.aesGetters.dotFill ?? GET_BLACK;\n const rgba = stringToNumberRgba(colorGetter(d.idx));\n rgba[3] = !d.dimmed && isDotInsidePolygons(d.x, d.y, this.polygons) ? 1 : 0.4;\n return getColorWithFakeOpacity(rgba, rgba);\n });\n }\n\n updatePointSize(\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers']\n ) {\n if (this.tools === null) {\n return;\n }\n this.updateAes(legendInfo, layers);\n // TODO: try remove array copy\n select(this.canvasNode).datum([...this.allDots]);\n // @ts-ignore\n this.tools.pointSeries.size((d: Dot) => convertDotRToSymbolSize(this.aesGetters.dotSize(d.idx)));\n }\n\n updateByLasso() {\n if (this.tools === null) {\n return;\n }\n \n // @ts-ignore\n this.tools?.fillColor.value((d: Dot) => {\n const colorGetter = this.aesGetters.dotFill ?? GET_BLACK;\n const rgba = stringToNumberRgba(colorGetter(d.idx));\n rgba[3] = !d.dimmed && isDotInsidePolygons(d.x, d.y, this.polygons) ? 1 : 0.4;\n return getColorWithFakeOpacity(rgba, rgba);\n });\n this.renderWebglLayer();\n }\n\n createQuadtree(dots: Dot[]): KDBush {\n const tree = new KDBush(dots.length, 512);\n\n for (let i = 0; i < dots.length; i++) {\n tree.add(dots[i].x, dots[i].y);\n } \n\n return tree.finish();\n }\n\n getClosestDot(_x: number, _y: number): Dot | null {\n const tree = this.tools?.qt;\n if (!tree) return null;\n const dots = this.allDots;\n const x = this.scales.x.invert(_x);\n const y = this.scales.y.invert(_y);\n const radius = 1 / (this.zoomTransform?.k || 1);\n const minX = x - radius;\n const maxX = x + radius;\n const minY = y - radius;\n const maxY = y + radius;\n\n const indexes = tree.range(minX, minY, maxX, maxY);\n const closest = indexes.reduce((closest, idx: number) => {\n const dot = dots[idx];\n const dX = this.scales.x(dot.x) - _x;\n const dY = this.scales.y(dot.y) - _y;\n const distance = Math.hypot(dX, dY);\n if (closest === null || distance < closest.distance) {\n closest.index = idx;\n closest.distance = distance;\n }\n return closest;\n }, {\n index: -1,\n distance: Infinity\n });\n return indexes.length === 0 || closest.index === -1 ? null : dots[closest.index];\n }\n\n updateDots(dots: Dot[]) {\n if (this.tools === null) {\n return;\n }\n select(this.canvasNode).datum(dots);\n \n // @ts-ignore\n this.tools.fillColor.data(dots);\n this.tools.qt = this.createQuadtree(dots);\n this.allDots = dots;\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: ScatterplotUmapSettingsImpl['chartSettings'],\n keyColumn: ColumnName | null,\n dots: Dot[],\n dotExtents: DotsExtents,\n dotsByGrouping: Record<string, Dot[]>,\n layers: ScatterplotUmapSettingsImpl['layers'],\n legendInfo: ScatterplotUmapLegendInfo,\n grouping: ColumnName[],\n onPolygonUpdateOutside: ScatterplotEventHandlers['onPolygonUpdate'],\n onTooltipHintSwitch: (v:boolean) => void,\n onLassoControlsStateUpdate: (v:LassoControlsState) => void,\n onZoomChange: (v:boolean) => void,\n ) {\n this.dataFrame = dataFrame;\n const sizesChanged = chartSettings.size.width !== this.chartSizes.chartWidth || chartSettings.size.height !== this.chartSizes.chartHeight; \n if (this.tools === null) {\n this.initSettings(\n dots,\n chartSettings,\n dotExtents,\n legendInfo,\n layers,\n grouping,\n onZoomChange\n ); \n } else {\n const {title, legend, size} = chartSettings;\n this.updateChartSizes(size);\n this.updateLegendSize(legend, legendInfo, grouping, layers);\n this.createMainTitle(title);\n this.updateMargins(chartSettings.xAxis, chartSettings.yAxis);\n this.updateAes(legendInfo, layers);\n }\n\n this.onPolygonUpdateOutside = onPolygonUpdateOutside;\n this.onTooltipHintSwitch = onTooltipHintSwitch;\n this.onLassoControlsStateUpdate = onLassoControlsStateUpdate;\n\n if (this.allDots !== dots) {\n this.updateDots(dots);\n this.visibleLabels = this.computeLabels(dots);\n this.onPolygonUpdate(this.polygons);\n } else if (sizesChanged) {\n this.visibleLabels = this.computeLabels(dots);\n }\n\n this.notCalculatedProps = {\n settingsId,\n chartSettings,\n keyColumn,\n dotsByGrouping,\n layers\n };\n\n this.renderWebglLayer();\n this.renderSvgLayer();\n }\n\n renderWebglLayer() {\n if (this.tools?.webglChart) {\n select(this.canvasNode).call(this.tools?.webglChart);\n }\n }\n\n onPolygonUpdate = (p:Polygon[]) => {\n this.polygons = p;\n this.updateByLasso();\n const filteredDotsIndexes = this.allDots\n .filter(d => isDotInsidePolygons(d.x, d.y, this.polygons))\n .map(d => d.idx);\n this.onPolygonUpdateOutside(filteredDotsIndexes, p);\n };\n\n renderSvgLayer() {\n const props = {\n settingsId: this.notCalculatedProps.settingsId,\n chartSettings: this.notCalculatedProps.chartSettings,\n keyColumn: this.notCalculatedProps.keyColumn,\n dotsByGrouping: this.notCalculatedProps.dotsByGrouping,\n layers: this.notCalculatedProps.layers,\n chartSizes: this.chartSizes,\n scales: this.scales,\n margins: this.margins,\n mainTitle: this.mainTitle,\n captionsSizes: this.captionsSizes,\n container: this.svgLayerElement,\n zoomStateKey: this.zoomStateKey,\n selectedDot: this.selectedDot,\n aesGetters: this.aesGetters,\n legendData: this.legend,\n labels: this.visibleLabels,\n defaultPolygons: this.polygons,\n onPolygonUpdate: this.onPolygonUpdate,\n onTooltipHintSwitch: this.onTooltipHintSwitch,\n onLassoControlsStateUpdate: this.onLassoControlsStateUpdate,\n } as SVGLayerProps;\n this.svgLayerComponent = (\n <DataFrameProvider dataFrame={this.dataFrame}>\n <SVGLayer {...props} />\n </DataFrameProvider>\n );\n this.reactRoot?.render(this.svgLayerComponent);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n\n private computeLabels(dots: Dot[]) {\n const textMeasurer = new TextMeasurer('16px Manrope');\n const getPosition = createLabelPositioner(this.chartSizes.chartWidth, this.chartSizes.chartHeight);\n const labels = [];\n\n for (let i = 0; i < dots.length; i++) {\n const dot = dots[i];\n if (dot.label == null) {\n continue;\n }\n const name = String(dot.label);\n const metrics = textMeasurer.getTextMetrics(name);\n const x = this.scales.x(dot.x);\n const y = this.scales.y(dot.y);\n const w = metrics.width;\n const h = (metrics.actualBoundingBoxAscent) + (metrics.actualBoundingBoxDescent);\n const p = 10;\n const position = getPosition(x, y, w, h, p);\n if (!position) {\n continue;\n }\n\n labels.push({\n x,\n y,\n dot,\n name,\n width: w,\n height: h,\n padding: p,\n xPosition: position[0],\n yPosition: position[1],\n } satisfies Label);\n }\n\n return labels;\n }\n\n private updateLabelsPosition(labels: Label[]) {\n for (let i = 0; i < labels.length; i++) {\n const label = labels[i];\n label.x = this.scales.x(label.dot.x as number);\n label.y = this.scales.y(label.dot.y as number);\n }\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ChartRenderer.js","names":[],"sources":["../../src/scatterplot-umap/ChartRenderer.tsx"],"sourcesContent":["import { chartCartesian } from '@d3fc/d3fc-chart';\nimport type { CartesianChart } from '@d3fc/d3fc-chart/src/cartesian';\nimport type { ScaleLinear } from 'd3-scale';\nimport { scaleLinear, scaleLog, scaleOrdinal, scaleSymlog } from 'd3-scale';\nimport { select } from 'd3-selection';\nimport type { D3ZoomEvent, ZoomBehavior, ZoomTransform } from 'd3-zoom';\nimport { zoom, zoomIdentity } from 'd3-zoom';\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 {\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 { splitTextByWidth } from '../discrete/utils';\nimport { DEFAULT_DOT_AES, MIN_MARGIN } from '../scatterplot/constants';\nimport { createAesGetter } from '../scatterplot/utils/createAesGetter';\nimport { getTicksAndFormat } from '../scatterplot/utils/getTicksAndFormat';\nimport type { Label } from '../scatterplot/utils/getVisibleLabels';\nimport { createLabelPositioner } from '../scatterplot/utils/getVisibleLabels';\nimport type { AesItem, ColumnName, ScatterplotEventHandlers } from '../types';\nimport { isContinuousAes } from '../types';\nimport type { ScatterplotUmapLegendInfo } from '../types/scatterplot-umap';\nimport { getContinuousColorScale } from '../utils/getContinuousColorScale';\nimport { getContinuousLegendTicks } from '../utils/getContinuousLegendTicks';\nimport { TextMeasurer } from '../utils/TextMeasurer/TextMeasurer';\nimport { SVGLayer } from './components/SVGLayer';\nimport { LEGEND_OFFSET, PADDINGS, TITLE_LINE } from './constants';\nimport type { CurveLayer, DotsLayer, ScatterplotUmapLayer, ScatterplotUmapSettingsImpl } from './SettingsImpl';\nimport type {\n AdditionalCurveRenderData,\n AesGetters,\n CaptionsSizes,\n ChartScales, ChartSizes,\n Dot,\n DotsExtents,\n LassoControlsState,\n Margins,\n Polygon,\n SVGLayerProps,\n} from './types';\n// @ts-ignore\nimport { seriesSvgMulti, seriesWebglMulti, seriesWebglPoint } from '@d3fc/d3fc-series';\n// @ts-ignore\nimport { webglFillColor } from '@d3fc/d3fc-webgl';\n// @ts-ignore\nimport { pointer } from '@d3fc/d3fc-pointer';\nimport { polygonContains } from 'd3-polygon';\nimport KDBush from 'kdbush';\nimport { DataFrameProvider } from '../common/useDataFrame';\nimport { DataFrame } from '../DataFrame';\nimport { arrangeLegendParts } from '../utils/arrangeLegendParts';\nimport { GET_BLACK, getColorWithFakeOpacity, stringToNumberRgba } from './colors';\nimport { getSizeLegendItem } from '../utils/getSizeLegendItem';\n\nfunction convertDotRToSymbolSize(r:number) {\n return (r / 2.35) * (r / 2.35) * 64;\n}\n\nfunction isDotInsidePolygons(x:number, y:number, polygons: Polygon[]) {\n if (polygons.length === 0) {\n return true;\n }\n return polygons.some((p) => p.closed && p.points.length > 2 && polygonContains(p.points, [x, y]));\n}\n\nfunction getGettersFromLayers(\n dataFrame: DataFrame,\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers'],\n additionalCurves: ScatterplotUmapSettingsImpl['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 return {\n dotFill: 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 lineType: createAesGetter(dataFrame, legendInfo, curveLayer?.aes.lineShape ?? 'solid', 'lineShape'),\n additionalCurveLineColor: (additionalCurves?.curves ?? []).map(\n (entry) => createAesGetter<string>(dataFrame, legendInfo, entry.lineColor, 'lineColor'),\n ),\n };\n}\n\nclass ChartRenderer {\n reactRoot: Root | null = null;\n parentNode: HTMLElement | null = null;\n rootNode: HTMLElement | null = null;\n canvasNode: HTMLElement | null = null;\n\n svgLayerElement: SVGElement | null = null;\n svgLayerComponent: ReactElement = (<></>);\n\n aesGetters: AesGetters = {\n dotSize: () => 2,\n dotFill: () => BLACK,\n lineType: () => 'solid',\n additionalCurveLineColor: [],\n };\n\n tools: {\n webglChart: CartesianChart<unknown, unknown>;\n qt?: KDBush;\n fillColor: () => {\n value: (setter: (d: Dot) => [number, number, number, number]) => void;\n data: (setter: () => Dot[]) => void;\n };\n pointSeries: () => unknown;\n zoom: ZoomBehavior<Element, unknown>;\n } | null = null;\n\n margins: Margins = {\n top: MIN_MARGIN,\n bottom: MIN_MARGIN,\n left: MIN_MARGIN,\n right: MIN_MARGIN,\n };\n chartSizes: ChartSizes = {\n chartWidth: DEFAULT_WIDTH, // width of single chart\n chartHeight: DEFAULT_HEIGHT, // height of single chart\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 scales: ChartScales = {\n x: scaleLinear().domain([0, 10]).range([0, DEFAULT_WIDTH]),\n y: scaleLinear().domain([0, 10]).range([DEFAULT_HEIGHT, 0]),\n xOriginal: scaleLinear().domain([0, 10]).range([0, DEFAULT_WIDTH]),\n yOriginal: scaleLinear().domain([0, 10]).range([DEFAULT_HEIGHT, 0]),\n };\n\n polygons:Polygon[] = [];\n onPolygonUpdateOutside: ScatterplotEventHandlers['onPolygonUpdate'] = () => undefined;\n onTooltipHintSwitch: ScatterplotEventHandlers['onTooltipHintSwitch'] = () => undefined;\n onLassoControlsStateUpdate: ScatterplotEventHandlers['onLassoControlsStateUpdate'] = () => undefined;\n\n zoomTransform: ZoomTransform | null = null;\n zoomStateKey = '';\n selectedDot: Dot | null = null;\n captionsSizes: CaptionsSizes = {\n xAxisCaptionsWidth: 30,\n yAxisCaptionsWidth: 100,\n };\n mainTitle: string[] = []; // can be multiline\n legend: LegendData = {width: 0, height: 0, items: []};\n\n notCalculatedProps: Partial<SVGLayerProps> = {};\n\n allDots: Dot[] = [];\n visibleLabels: Label[] = [];\n dataFrame: DataFrame = new DataFrame('', {});\n\n clear() {\n if (this.parentNode && this.rootNode && this.canvasNode) {\n this.parentNode?.removeChild(this.rootNode);\n this.parentNode?.removeChild(this.canvasNode);\n this.parentNode = null;\n this.rootNode = null;\n this.canvasNode = null;\n this.svgLayerElement = null;\n this.tools = 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.canvasNode = document.createElement('div');\n this.parentNode.appendChild(this.rootNode);\n this.parentNode.appendChild(this.canvasNode);\n this.reactRoot = createRoot(this.rootNode);\n }\n }\n\n updateChartSizes(size: ScatterplotUmapSettingsImpl['chartSettings']['size']) {\n if (size.width !== this.chartSizes.chartWidth || size.height !== this.chartSizes.chartHeight) {\n // NB: now chart sizes always change with one multiplier for width/height so qt stays without changes\n this.chartSizes.chartWidth = size.width;\n this.chartSizes.chartHeight = size.height;\n this.scales.x.range([0, this.chartSizes.chartWidth]);\n this.scales.y.range([this.chartSizes.chartHeight, 0]);\n }\n \n }\n\n updateViewport(\n xAxis: ScatterplotUmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotUmapSettingsImpl['chartSettings']['yAxis'],\n dotsExtents: DotsExtents,\n ) {\n const scaleX = xAxis.scale === 'log' ? scaleLog() : scaleLinear();\n\n let {minX, minY, maxX, maxY} = dotsExtents;\n if (xAxis.lowerValue !== undefined) {\n minX = Math.max(minX, xAxis.lowerValue);\n }\n if (xAxis.upperValue !== undefined) {\n maxX = Math.min(maxX, xAxis.upperValue);\n }\n if (yAxis.lowerValue !== undefined) {\n minY = Math.max(minY, yAxis.lowerValue);\n }\n if (yAxis.upperValue !== undefined) {\n maxY = Math.min(maxY, yAxis.upperValue);\n }\n if (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 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 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 // this.scales.x = scaleX;\n // this.scales.xOriginal = scaleX.copy();\n this.scales.x.domain(scaleX.domain());\n this.scales.xOriginal.domain(scaleX.domain());\n\n const scaleY = yAxis.scale === 'log' ? scaleLog() : scaleLinear();\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 // this.scales.y = scaleY;\n // this.scales.yOriginal = scaleY.copy();\n this.scales.y.domain(scaleY.domain());\n this.scales.yOriginal.domain(scaleY.domain());\n }\n\n updateCaptionsSize() {\n const textMeasurer = new TextMeasurer('600 14px Arial');\n\n function getMaxTickWidth(ticks: string[]) {\n return Math.max(...ticks.map(key => textMeasurer.getTextWidth(key)));\n }\n\n const {ticks, format} = getTicksAndFormat(this.scales.y, false);\n const maxYTick = getMaxTickWidth(ticks.map(format));\n\n this.captionsSizes = {\n xAxisCaptionsWidth: 20,\n yAxisCaptionsWidth: maxYTick,\n };\n }\n\n createMainTitle(title: ScatterplotUmapSettingsImpl['chartSettings']['title']) {\n this.mainTitle = splitTextByWidth(\n title.name,\n this.chartSizes.totalWidth - this.margins.left - this.margins.right,\n 20\n );\n }\n\n updateMargins(xAxis: ScatterplotUmapSettingsImpl['chartSettings']['xAxis'], yAxis: ScatterplotUmapSettingsImpl['chartSettings']['yAxis']) {\n const titleTextHeight = TITLE_LINE_HEIGHT * this.mainTitle.length;\n const titleHeight = titleTextHeight > 0 ? titleTextHeight + TITLE_MARGIN * 2 : 0;\n this.margins = {\n top: Math.max(titleHeight, MIN_MARGIN),\n bottom: MIN_MARGIN + (xAxis.hiddenLabels ? 0 : this.captionsSizes.xAxisCaptionsWidth) + TITLE_LINE,\n left: MIN_MARGIN + (yAxis.hiddenLabels ? 0 : this.captionsSizes.yAxisCaptionsWidth) + TITLE_LINE,\n right: this.legend.width + MIN_MARGIN,\n };\n this.chartSizes.totalWidth = this.margins.left + this.chartSizes.chartWidth + this.margins.right;\n this.chartSizes.totalHeight =\n this.margins.top + Math.max(this.chartSizes.chartHeight, this.legend.height) + this.margins.bottom;\n\n select(this.canvasNode)\n .style('width', this.chartSizes.chartWidth + 'px')\n .style('height', this.chartSizes.chartHeight + 'px')\n .style('top', this.margins.top + 'px')\n .style('left', this.margins.left + 'px');\n }\n\n updateLegendSize(\n legend: ScatterplotUmapSettingsImpl['chartSettings']['legend'],\n legendLabels: ScatterplotUmapLegendInfo,\n grouping: ColumnName[],\n layers: ScatterplotUmapLayer[],\n additionalCurves: ScatterplotUmapSettingsImpl['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 = legendLabels[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(category => {\n if (!aesData[category]) {\n aesData[category] = {...DEFAULT_DOT_AES} as DotAesItem;\n }\n info.usedAes.forEach(key => {\n if (key === 'dotFill') {\n aesData[category].color = (info.aesMap(category, key) ?? BLACK) as string;\n }\n if (key === 'dotSize') {\n aesData[category].size = Number(info.aesMap(category, key) ?? 3);\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 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 legend section — parallel implementation to scatterplot's updateLegendSize.\n // UMAP has no per-entry trend.\n if (additionalCurves && additionalCurves.curves.length > 0) {\n // Legend sample color mirrors the curve's own `lineColor` when fixed; falls back to neutral\n // BLACK only when the color inherits from grouping (a single sample can't represent multiple\n // group colors — actual group colors appear in the grouping's own color legend, per 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] = { lineShape: curveLayer.aes.lineShape, lineColor: resolvedColor };\n }\n for (const entry of additionalCurves.curves) {\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] = { lineShape: entry.lineShape, lineColor: resolvedColor };\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 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 initSettings(\n dots: Dot[],\n chartSettings: ScatterplotUmapSettingsImpl['chartSettings'],\n dotExtents: DotsExtents,\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers'],\n grouping: ColumnName[],\n onZoomChange: (v:boolean) => void,\n additionalCurves: ScatterplotUmapSettingsImpl['additionalCurves'],\n yColumn: ColumnName,\n ) {\n const {xAxis, yAxis, size, title, legend} = chartSettings;\n this.updateChartSizes(size);\n this.updateViewport(xAxis, yAxis, dotExtents);\n this.updateCaptionsSize();\n this.updateLegendSize(legend, legendInfo, grouping, layers, additionalCurves, yColumn);\n this.createMainTitle(title);\n this.updateMargins(xAxis, yAxis);\n\n this.aesGetters = getGettersFromLayers(this.dataFrame, legendInfo, layers, additionalCurves);\n\n const fillColor = webglFillColor()\n .data(dots)\n .value((d: Dot) => {\n const rgba = stringToNumberRgba(this.aesGetters.dotFill(d.idx));\n rgba[3] = !d.dimmed && isDotInsidePolygons(d.x, d.y, this.polygons) ? 1 : 0.4;\n return getColorWithFakeOpacity(rgba, rgba);\n });\n\n const pointSeries = seriesWebglPoint()\n .equals((a: Dot[], b: Dot[]) => a === b)\n .size((d: Dot) => convertDotRToSymbolSize(this.aesGetters.dotSize(d.idx)))\n .crossValue((d: Dot) => d.x)\n .mainValue((d: Dot) => d.y)\n .decorate((program: unknown) => fillColor(program));\n\n const z = zoom()\n .scaleExtent([0.1, 1000])\n .filter((e:MouseEvent) => {\n return e.type === 'wheel' || e.metaKey || e.ctrlKey;\n })\n .on('start', () => {\n this.selectedDot = null;\n })\n .on('zoom', (e: D3ZoomEvent<SVGElement, unknown>) => {\n const transform = e.transform;\n const x = transform.rescaleX(this.scales.xOriginal);\n const y = transform.rescaleY(this.scales.yOriginal);\n this.scales.x.domain(x.domain());\n this.scales.y.domain(y.domain());\n\n this.zoomTransform = transform;\n this.zoomStateKey = `${transform.x}_${transform.y}_${transform.k}`; // need it to update axes\n\n this.updateLabelsPosition(this.visibleLabels);\n this.renderSvgLayer();\n this.renderWebglLayer();\n }).on('end', () => {\n this.visibleLabels = this.computeLabels(this.allDots);\n this.renderSvgLayer();\n onZoomChange(true);\n });\n \n // @ts-ignore\n const p = pointer().on('point', ([coord]) => {\n let closestDatum;\n if (coord) {\n closestDatum = this.getClosestDot(coord.x, coord.y);\n }\n \n const needRedraw =\n (this.selectedDot && !closestDatum) ||\n (!this.selectedDot && closestDatum) ||\n this.selectedDot?.idx !== closestDatum?.idx;\n\n this.selectedDot = closestDatum ?? null;\n\n if (needRedraw) {\n this.renderSvgLayer();\n }\n });\n\n const webglChart = chartCartesian({\n xScale: this.scales.x,\n yScale: this.scales.y,\n })\n .xAxisHeight(() => '0') // removing build-in axes from chartCartesian\n .yAxisWidth(() => '0') // removing build-in axes from chartCartesian\n .svgPlotArea(seriesSvgMulti())\n .webglPlotArea(\n // only render the point series on the WebGL layer\n seriesWebglMulti()\n .series([pointSeries])\n .mapping((d: unknown) => d)\n )\n .decorate(selection => {\n const s = selection.enter();\n if (s && !this.svgLayerElement) {\n s.style('grid-template-columns', '0 auto 1fr auto 0'); // removing build-in axes from chartCartesian\n s.style('grid-template-rows', '0 auto 1fr auto 0'); // removing build-in axes from chartCartesian\n this.svgLayerElement = s.select('.svg-plot-area.plot-area svg').node() as SVGElement;\n }\n s.select('.svg-plot-area.plot-area').attr('class', 'svg-plot-area plot-area miplots-scatterplot-plot-area')\n \n // @ts-ignore\n .call(z)\n .call(p);\n });\n\n this.tools = {\n webglChart,\n zoom: z,\n fillColor,\n pointSeries,\n };\n\n select(this.canvasNode)\n .datum(dots)\n .style('position', 'absolute')\n .style('width', this.chartSizes.chartWidth + 'px')\n .style('height', this.chartSizes.chartHeight + 'px')\n .style('top', this.margins.top + 'px')\n .style('left', this.margins.left + 'px');\n this.onPolygonUpdate(this.polygons);\n }\n\n resetZoom(\n xAxis: ScatterplotUmapSettingsImpl['chartSettings']['xAxis'],\n yAxis: ScatterplotUmapSettingsImpl['chartSettings']['yAxis'],\n dotsExtents?: DotsExtents\n ) {\n if (!this.tools?.zoom || !dotsExtents) {\n return;\n }\n this.updateViewport(xAxis, yAxis, dotsExtents);\n select('.miplots-scatterplot-plot-area').call((this.tools.zoom.transform as (selection: unknown, transform: unknown) => void), zoomIdentity);\n }\n\n updateAes(\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers'],\n additionalCurves: ScatterplotUmapSettingsImpl['additionalCurves']\n ) {\n if (this.tools === null) {\n return;\n }\n this.aesGetters = getGettersFromLayers(this.dataFrame, legendInfo, layers, additionalCurves);\n \n // @ts-ignore\n this.tools.fillColor.value((d: Dot) => {\n const colorGetter = this.aesGetters.dotFill ?? GET_BLACK;\n const rgba = stringToNumberRgba(colorGetter(d.idx));\n rgba[3] = !d.dimmed && isDotInsidePolygons(d.x, d.y, this.polygons) ? 1 : 0.4;\n return getColorWithFakeOpacity(rgba, rgba);\n });\n }\n\n updatePointSize(\n legendInfo: ScatterplotUmapLegendInfo,\n layers: ScatterplotUmapSettingsImpl['layers'],\n additionalCurves: ScatterplotUmapSettingsImpl['additionalCurves']\n ) {\n if (this.tools === null) {\n return;\n }\n this.updateAes(legendInfo, layers, additionalCurves);\n // TODO: try remove array copy\n select(this.canvasNode).datum([...this.allDots]);\n // @ts-ignore\n this.tools.pointSeries.size((d: Dot) => convertDotRToSymbolSize(this.aesGetters.dotSize(d.idx)));\n }\n\n updateByLasso() {\n if (this.tools === null) {\n return;\n }\n \n // @ts-ignore\n this.tools?.fillColor.value((d: Dot) => {\n const colorGetter = this.aesGetters.dotFill ?? GET_BLACK;\n const rgba = stringToNumberRgba(colorGetter(d.idx));\n rgba[3] = !d.dimmed && isDotInsidePolygons(d.x, d.y, this.polygons) ? 1 : 0.4;\n return getColorWithFakeOpacity(rgba, rgba);\n });\n this.renderWebglLayer();\n }\n\n createQuadtree(dots: Dot[]): KDBush {\n const tree = new KDBush(dots.length, 512);\n\n for (let i = 0; i < dots.length; i++) {\n tree.add(dots[i].x, dots[i].y);\n } \n\n return tree.finish();\n }\n\n getClosestDot(_x: number, _y: number): Dot | null {\n const tree = this.tools?.qt;\n if (!tree) return null;\n const dots = this.allDots;\n const x = this.scales.x.invert(_x);\n const y = this.scales.y.invert(_y);\n const radius = 1 / (this.zoomTransform?.k || 1);\n const minX = x - radius;\n const maxX = x + radius;\n const minY = y - radius;\n const maxY = y + radius;\n\n const indexes = tree.range(minX, minY, maxX, maxY);\n const closest = indexes.reduce((closest, idx: number) => {\n const dot = dots[idx];\n const dX = this.scales.x(dot.x) - _x;\n const dY = this.scales.y(dot.y) - _y;\n const distance = Math.hypot(dX, dY);\n if (closest === null || distance < closest.distance) {\n closest.index = idx;\n closest.distance = distance;\n }\n return closest;\n }, {\n index: -1,\n distance: Infinity\n });\n return indexes.length === 0 || closest.index === -1 ? null : dots[closest.index];\n }\n\n updateDots(dots: Dot[]) {\n if (this.tools === null) {\n return;\n }\n select(this.canvasNode).datum(dots);\n \n // @ts-ignore\n this.tools.fillColor.data(dots);\n this.tools.qt = this.createQuadtree(dots);\n this.allDots = dots;\n }\n\n render(\n dataFrame: DataFrame,\n settingsId: string,\n chartSettings: ScatterplotUmapSettingsImpl['chartSettings'],\n keyColumn: ColumnName | null,\n dots: Dot[],\n dotExtents: DotsExtents,\n dotsByGrouping: Record<string, Dot[]>,\n layers: ScatterplotUmapSettingsImpl['layers'],\n legendInfo: ScatterplotUmapLegendInfo,\n grouping: ColumnName[],\n onPolygonUpdateOutside: ScatterplotEventHandlers['onPolygonUpdate'],\n onTooltipHintSwitch: (v:boolean) => void,\n onLassoControlsStateUpdate: (v:LassoControlsState) => void,\n onZoomChange: (v:boolean) => void,\n additionalCurves: AdditionalCurveRenderData[] = [],\n additionalCurvesSettings: ScatterplotUmapSettingsImpl['additionalCurves'] = null,\n yColumn: ColumnName,\n ) {\n this.dataFrame = dataFrame;\n const sizesChanged = chartSettings.size.width !== this.chartSizes.chartWidth || chartSettings.size.height !== this.chartSizes.chartHeight;\n if (this.tools === null) {\n this.initSettings(\n dots,\n chartSettings,\n dotExtents,\n legendInfo,\n layers,\n grouping,\n onZoomChange,\n additionalCurvesSettings,\n yColumn,\n );\n } else {\n const {title, legend, size} = chartSettings;\n this.updateChartSizes(size);\n this.updateLegendSize(legend, legendInfo, grouping, layers, additionalCurvesSettings, yColumn);\n this.createMainTitle(title);\n this.updateMargins(chartSettings.xAxis, chartSettings.yAxis);\n this.updateAes(legendInfo, layers, additionalCurvesSettings);\n }\n\n this.onPolygonUpdateOutside = onPolygonUpdateOutside;\n this.onTooltipHintSwitch = onTooltipHintSwitch;\n this.onLassoControlsStateUpdate = onLassoControlsStateUpdate;\n\n if (this.allDots !== dots) {\n this.updateDots(dots);\n this.visibleLabels = this.computeLabels(dots);\n this.onPolygonUpdate(this.polygons);\n } else if (sizesChanged) {\n this.visibleLabels = this.computeLabels(dots);\n }\n\n this.notCalculatedProps = {\n settingsId,\n chartSettings,\n keyColumn,\n dotsByGrouping,\n layers,\n additionalCurves,\n };\n\n this.renderWebglLayer();\n this.renderSvgLayer();\n }\n\n renderWebglLayer() {\n if (this.tools?.webglChart) {\n select(this.canvasNode).call(this.tools?.webglChart);\n }\n }\n\n onPolygonUpdate = (p:Polygon[]) => {\n this.polygons = p;\n this.updateByLasso();\n const filteredDotsIndexes = this.allDots\n .filter(d => isDotInsidePolygons(d.x, d.y, this.polygons))\n .map(d => d.idx);\n this.onPolygonUpdateOutside(filteredDotsIndexes, p);\n };\n\n renderSvgLayer() {\n const props = {\n settingsId: this.notCalculatedProps.settingsId,\n chartSettings: this.notCalculatedProps.chartSettings,\n keyColumn: this.notCalculatedProps.keyColumn,\n dotsByGrouping: this.notCalculatedProps.dotsByGrouping,\n layers: this.notCalculatedProps.layers,\n additionalCurves: this.notCalculatedProps.additionalCurves ?? [],\n chartSizes: this.chartSizes,\n scales: this.scales,\n margins: this.margins,\n mainTitle: this.mainTitle,\n captionsSizes: this.captionsSizes,\n container: this.svgLayerElement,\n zoomStateKey: this.zoomStateKey,\n selectedDot: this.selectedDot,\n aesGetters: this.aesGetters,\n legendData: this.legend,\n labels: this.visibleLabels,\n defaultPolygons: this.polygons,\n onPolygonUpdate: this.onPolygonUpdate,\n onTooltipHintSwitch: this.onTooltipHintSwitch,\n onLassoControlsStateUpdate: this.onLassoControlsStateUpdate,\n } as SVGLayerProps;\n this.svgLayerComponent = (\n <DataFrameProvider dataFrame={this.dataFrame}>\n <SVGLayer {...props} />\n </DataFrameProvider>\n );\n this.reactRoot?.render(this.svgLayerComponent);\n }\n\n renderError(message: string) {\n this.reactRoot?.render(<Error message={message} />);\n }\n\n private computeLabels(dots: Dot[]) {\n const textMeasurer = new TextMeasurer('16px Manrope');\n const getPosition = createLabelPositioner(this.chartSizes.chartWidth, this.chartSizes.chartHeight);\n const labels = [];\n\n for (let i = 0; i < dots.length; i++) {\n const dot = dots[i];\n if (dot.label == null) {\n continue;\n }\n const name = String(dot.label);\n const metrics = textMeasurer.getTextMetrics(name);\n const x = this.scales.x(dot.x);\n const y = this.scales.y(dot.y);\n const w = metrics.width;\n const h = (metrics.actualBoundingBoxAscent) + (metrics.actualBoundingBoxDescent);\n const p = 10;\n const position = getPosition(x, y, w, h, p);\n if (!position) {\n continue;\n }\n\n labels.push({\n x,\n y,\n dot,\n name,\n width: w,\n height: h,\n padding: p,\n xPosition: position[0],\n yPosition: position[1],\n } satisfies Label);\n }\n\n return labels;\n }\n\n private updateLabelsPosition(labels: Label[]) {\n for (let i = 0; i < labels.length; i++) {\n const label = labels[i];\n label.x = this.scales.x(label.dot.x as number);\n label.y = this.scales.y(label.dot.y as number);\n }\n }\n}\n\nexport default ChartRenderer;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { AxisSettingsContinuous, ColumnName, ContinuousAesFromColumn, DataValue, FrameType, LegendPosition, LineShape, SettingsInterface, TitlePosition, AesRecord, InheritAesScatterplot, PointShape } from '../types';
2
- import { CurveUmapLayer as OuterCurveLayer, DotsUmapLayer as OuterDotsLayer, ScatterplotUmapSettings } from '../types/scatterplot-umap';
2
+ import { AdditionalCurveUmapEntry, CurveUmapLayer as OuterCurveLayer, DotsUmapLayer as OuterDotsLayer, ScatterplotUmapSettings } from '../types/scatterplot-umap';
3
3
  export declare class DotsLayer {
4
4
  readonly type = "dots";
5
5
  readonly aes: {
@@ -63,6 +63,16 @@ export declare class ScatterplotUmapSettingsImpl implements SettingsInterface {
63
63
  content?: ColumnName[];
64
64
  };
65
65
  };
66
+ readonly additionalCurves: {
67
+ curves: (AdditionalCurveUmapEntry & {
68
+ lineShape: LineShape;
69
+ lineWidth: number;
70
+ lineColor: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;
71
+ opacity: number;
72
+ showDots: boolean;
73
+ })[];
74
+ smoothing: boolean;
75
+ } | null;
66
76
  readonly layers: ScatterplotUmapLayer[];
67
77
  constructor(settings: ScatterplotUmapSettings);
68
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsImpl.d.ts","sourceRoot":"","sources":["../../src/scatterplot-umap/SettingsImpl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SettingsImpl.d.ts","sourceRoot":"","sources":["../../src/scatterplot-umap/SettingsImpl.ts"],"names":[],"mappings":"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"}
@@ -40,6 +40,7 @@ var r = class {
40
40
  label;
41
41
  highlight;
42
42
  chartSettings;
43
+ additionalCurves;
43
44
  layers;
44
45
  constructor(e) {
45
46
  t.parse(e), this.id = n.uniqueId("settings"), this.keyColumn = e.keyColumn ?? null, this.x = e.x, this.y = e.y, this.grouping = e.grouping ?? [], this.label = e.label ?? null, this.highlight = e.highlight ?? null, this.chartSettings = {
@@ -77,7 +78,26 @@ var r = class {
77
78
  ...e.tooltips,
78
79
  show: e.tooltips?.show !== !1 && (e.tooltips?.content ?? []).length > 0
79
80
  }
80
- }, this.layers = e.layers.map((e) => {
81
+ };
82
+ let a = [
83
+ "dashed",
84
+ "dotted",
85
+ "dotdash",
86
+ "longdash",
87
+ "twodash",
88
+ "solid"
89
+ ];
90
+ this.additionalCurves = e.additionalCurves && e.additionalCurves.curves.length > 0 ? {
91
+ curves: e.additionalCurves.curves.map((e, t) => ({
92
+ ...e,
93
+ lineShape: e.lineShape ?? a[t % a.length],
94
+ lineWidth: e.lineWidth ?? 1,
95
+ lineColor: e.lineColor ?? "#110529",
96
+ opacity: e.opacity ?? 1,
97
+ showDots: e.showDots ?? !1
98
+ })),
99
+ smoothing: e.additionalCurves.smoothing ?? !1
100
+ } : null, this.layers = e.layers.map((e) => {
81
101
  if (e.type === "dots") return new r(e);
82
102
  if (e.type === "curve") return new i(e);
83
103
  throw Error("Unknown layer type");
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsImpl.js","names":[],"sources":["../../src/scatterplot-umap/SettingsImpl.ts"],"sourcesContent":["import lodash from 'lodash';\nimport { BLACK, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../constants';\nimport type {\n AxisSettingsContinuous,\n ColumnName,\n ContinuousAesFromColumn,\n DataValue,\n FrameType,\n LegendPosition,\n LineShape,\n SettingsInterface,\n TitlePosition\n} from '../types';\nimport {type AesRecord, type InheritAesScatterplot, type PointShape} from '../types';\nimport type {\n CurveUmapLayer as OuterCurveLayer,\n DotsUmapLayer as OuterDotsLayer,\n ScatterplotUmapSettings\n} from '../types/scatterplot-umap';\nimport { ScatterplotUmapSettingsSchema } from '../types/scatterplot-umap';\n\nexport class DotsLayer {\n readonly type = 'dots';\n readonly aes: {\n dotFill: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;\n dotShape: PointShape | InheritAesScatterplot;\n dotSize: number | ContinuousAesFromColumn<number>;\n opacity: number;\n } = {\n dotFill: BLACK,\n dotShape: '21',\n dotSize: 3,\n opacity: 1,\n };\n constructor(layer: OuterDotsLayer) {\n this.aes = {\n ...this.aes,\n ...layer.aes,\n };\n }\n}\nexport class CurveLayer {\n readonly type = 'curve';\n readonly smoothing: boolean;\n readonly aes: {\n lineColor: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;\n lineWidth: number;\n lineShape: LineShape;\n opacity: number;\n } = {\n lineColor: BLACK,\n lineWidth: 1,\n lineShape: 'solid',\n opacity: 1,\n };\n\n constructor(layer: OuterCurveLayer) {\n this.smoothing = layer.smoothing ?? false;\n this.aes = {\n ...this.aes,\n ...layer.aes,\n };\n }\n}\n\nexport type ScatterplotUmapLayer = DotsLayer | CurveLayer;\n\nexport class ScatterplotUmapSettingsImpl implements SettingsInterface {\n readonly id: string;\n readonly type = 'scatterplot-umap';\n readonly keyColumn: ColumnName | null;\n readonly x: ColumnName;\n readonly y: ColumnName;\n readonly grouping: {\n columnName: ColumnName;\n order?: DataValue[];\n inheritedAes?: AesRecord;\n }[];\n readonly label: ColumnName | null;\n readonly highlight: ColumnName | null;\n readonly chartSettings: {\n readonly size: {width: number; height: number};\n readonly title: {name: string; show: boolean; position: TitlePosition};\n readonly yAxis: AxisSettingsContinuous & {title: string | ColumnName};\n readonly xAxis: AxisSettingsContinuous & {title: string | ColumnName};\n readonly frame: {type: FrameType};\n readonly legend: {show: boolean; position: LegendPosition};\n readonly tooltips: {show: boolean; content?: ColumnName[]};\n };\n readonly layers: ScatterplotUmapLayer[];\n\n constructor(settings: ScatterplotUmapSettings) {\n ScatterplotUmapSettingsSchema.parse(settings);\n this.id = lodash.uniqueId('settings');\n this.keyColumn = settings.keyColumn ?? null;\n this.x = settings.x;\n this.y = settings.y;\n this.grouping = settings.grouping ?? [];\n this.label = settings.label ?? null;\n this.highlight = settings.highlight ?? null;\n this.chartSettings = {\n size: {\n width: settings?.size?.width ?? DEFAULT_WIDTH,\n height: settings?.size?.height ?? DEFAULT_HEIGHT,\n },\n title: {\n position: 'center',\n show: true,\n ...settings.title,\n name: settings.title?.name ?? 'Chart',\n },\n yAxis: {\n title: settings.y.label ?? settings.y.value,\n scale: 'linear',\n showGrid: true,\n showTicks: true,\n ...settings.yAxis,\n },\n xAxis: {\n title: settings.x.label ?? settings.x.value,\n scale: 'linear',\n showGrid: true,\n showTicks: true,\n ...settings.xAxis,\n },\n frame: {type: settings.frame?.type ?? 'full'},\n legend: {\n show: true,\n position: 'right',\n ...settings.legend,\n },\n tooltips: {\n ...settings.tooltips,\n show: !(settings.tooltips?.show === false) && (settings.tooltips?.content ?? []).length > 0,\n },\n };\n\n this.layers = settings.layers\n .map(layer => {\n if (layer.type === 'dots') {\n return new DotsLayer(layer);\n } else if (layer.type === 'curve') {\n return new CurveLayer(layer);\n } else {\n throw new Error('Unknown layer type');\n }\n })\n .filter(Boolean) as ScatterplotUmapLayer[];\n }\n}\n"],"mappings":";;;AAqBA,IAAa,IAAb,MAAuB;CACnB,OAAgB;CAChB,MAKI;EACA,SAAS;EACT,UAAU;EACV,SAAS;EACT,SAAS;EACZ;CACD,YAAY,GAAuB;AAC/B,OAAK,MAAM;GACP,GAAG,KAAK;GACR,GAAG,EAAM;GACZ;;GAGI,IAAb,MAAwB;CACpB,OAAgB;CAChB;CACA,MAKI;EACA,WAAW;EACX,WAAW;EACX,WAAW;EACX,SAAS;EACZ;CAED,YAAY,GAAwB;AAEhC,EADA,KAAK,YAAY,EAAM,aAAa,IACpC,KAAK,MAAM;GACP,GAAG,KAAK;GACR,GAAG,EAAM;GACZ;;GAMI,IAAb,MAAsE;CAClE;CACA,OAAgB;CAChB;CACA;CACA;CACA;CAKA;CACA;CACA;CASA;CAEA,YAAY,GAAmC;AA8C3C,EA7CA,EAA8B,MAAM,EAAS,EAC7C,KAAK,KAAK,EAAO,SAAS,WAAW,EACrC,KAAK,YAAY,EAAS,aAAa,MACvC,KAAK,IAAI,EAAS,GAClB,KAAK,IAAI,EAAS,GAClB,KAAK,WAAW,EAAS,YAAY,EAAE,EACvC,KAAK,QAAQ,EAAS,SAAS,MAC/B,KAAK,YAAY,EAAS,aAAa,MACvC,KAAK,gBAAgB;GACjB,MAAM;IACF,OAAO,GAAU,MAAM,SAAA;IACvB,QAAQ,GAAU,MAAM,UAAA;IAC3B;GACD,OAAO;IACH,UAAU;IACV,MAAM;IACN,GAAG,EAAS;IACZ,MAAM,EAAS,OAAO,QAAQ;IACjC;GACD,OAAO;IACH,OAAO,EAAS,EAAE,SAAS,EAAS,EAAE;IACtC,OAAO;IACP,UAAU;IACV,WAAW;IACX,GAAG,EAAS;IACf;GACD,OAAO;IACH,OAAO,EAAS,EAAE,SAAS,EAAS,EAAE;IACtC,OAAO;IACP,UAAU;IACV,WAAW;IACX,GAAG,EAAS;IACf;GACD,OAAO,EAAC,MAAM,EAAS,OAAO,QAAQ,QAAO;GAC7C,QAAQ;IACJ,MAAM;IACN,UAAU;IACV,GAAG,EAAS;IACf;GACD,UAAU;IACN,GAAG,EAAS;IACZ,MAAQ,EAAS,UAAU,SAAS,OAAW,EAAS,UAAU,WAAW,EAAE,EAAE,SAAS;IAC7F;GACJ,EAED,KAAK,SAAS,EAAS,OAClB,KAAI,MAAS;AACV,OAAI,EAAM,SAAS,OACf,QAAO,IAAI,EAAU,EAAM;OACpB,EAAM,SAAS,QACtB,QAAO,IAAI,EAAW,EAAM;AAE5B,SAAU,MAAM,qBAAqB;IAE3C,CACD,OAAO,QAAQ"}
1
+ {"version":3,"file":"SettingsImpl.js","names":[],"sources":["../../src/scatterplot-umap/SettingsImpl.ts"],"sourcesContent":["import lodash from 'lodash';\nimport { BLACK, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../constants';\nimport type {\n AxisSettingsContinuous,\n ColumnName,\n ContinuousAesFromColumn,\n DataValue,\n FrameType,\n LegendPosition,\n LineShape,\n SettingsInterface,\n TitlePosition\n} from '../types';\nimport {type AesRecord, type InheritAesScatterplot, type PointShape} from '../types';\nimport type {\n AdditionalCurveUmapEntry,\n CurveUmapLayer as OuterCurveLayer,\n DotsUmapLayer as OuterDotsLayer,\n ScatterplotUmapSettings\n} from '../types/scatterplot-umap';\nimport { ScatterplotUmapSettingsSchema } from '../types/scatterplot-umap';\n\nexport class DotsLayer {\n readonly type = 'dots';\n readonly aes: {\n dotFill: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;\n dotShape: PointShape | InheritAesScatterplot;\n dotSize: number | ContinuousAesFromColumn<number>;\n opacity: number;\n } = {\n dotFill: BLACK,\n dotShape: '21',\n dotSize: 3,\n opacity: 1,\n };\n constructor(layer: OuterDotsLayer) {\n this.aes = {\n ...this.aes,\n ...layer.aes,\n };\n }\n}\nexport class CurveLayer {\n readonly type = 'curve';\n readonly smoothing: boolean;\n readonly aes: {\n lineColor: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;\n lineWidth: number;\n lineShape: LineShape;\n opacity: number;\n } = {\n lineColor: BLACK,\n lineWidth: 1,\n lineShape: 'solid',\n opacity: 1,\n };\n\n constructor(layer: OuterCurveLayer) {\n this.smoothing = layer.smoothing ?? false;\n this.aes = {\n ...this.aes,\n ...layer.aes,\n };\n }\n}\n\nexport type ScatterplotUmapLayer = DotsLayer | CurveLayer;\n\nexport class ScatterplotUmapSettingsImpl implements SettingsInterface {\n readonly id: string;\n readonly type = 'scatterplot-umap';\n readonly keyColumn: ColumnName | null;\n readonly x: ColumnName;\n readonly y: ColumnName;\n readonly grouping: {\n columnName: ColumnName;\n order?: DataValue[];\n inheritedAes?: AesRecord;\n }[];\n readonly label: ColumnName | null;\n readonly highlight: ColumnName | null;\n readonly chartSettings: {\n readonly size: {width: number; height: number};\n readonly title: {name: string; show: boolean; position: TitlePosition};\n readonly yAxis: AxisSettingsContinuous & {title: string | ColumnName};\n readonly xAxis: AxisSettingsContinuous & {title: string | ColumnName};\n readonly frame: {type: FrameType};\n readonly legend: {show: boolean; position: LegendPosition};\n readonly tooltips: {show: boolean; content?: ColumnName[]};\n };\n readonly additionalCurves: {\n curves: (AdditionalCurveUmapEntry & {\n lineShape: LineShape;\n lineWidth: number;\n lineColor: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;\n opacity: number;\n showDots: boolean;\n })[];\n smoothing: boolean;\n } | null;\n\n readonly layers: ScatterplotUmapLayer[];\n\n constructor(settings: ScatterplotUmapSettings) {\n ScatterplotUmapSettingsSchema.parse(settings);\n this.id = lodash.uniqueId('settings');\n this.keyColumn = settings.keyColumn ?? null;\n this.x = settings.x;\n this.y = settings.y;\n this.grouping = settings.grouping ?? [];\n this.label = settings.label ?? null;\n this.highlight = settings.highlight ?? null;\n this.chartSettings = {\n size: {\n width: settings?.size?.width ?? DEFAULT_WIDTH,\n height: settings?.size?.height ?? DEFAULT_HEIGHT,\n },\n title: {\n position: 'center',\n show: true,\n ...settings.title,\n name: settings.title?.name ?? 'Chart',\n },\n yAxis: {\n title: settings.y.label ?? settings.y.value,\n scale: 'linear',\n showGrid: true,\n showTicks: true,\n ...settings.yAxis,\n },\n xAxis: {\n title: settings.x.label ?? settings.x.value,\n scale: 'linear',\n showGrid: true,\n showTicks: true,\n ...settings.xAxis,\n },\n frame: {type: settings.frame?.type ?? 'full'},\n legend: {\n show: true,\n position: 'right',\n ...settings.legend,\n },\n tooltips: {\n ...settings.tooltips,\n show: !(settings.tooltips?.show === false) && (settings.tooltips?.content ?? []).length > 0,\n },\n };\n\n // Identical to scatterplot; UMAP entries lack `trend`.\n const DEFAULT_LINE_SHAPES: LineShape[] = ['dashed', 'dotted', 'dotdash', 'longdash', 'twodash', 'solid'];\n this.additionalCurves = settings.additionalCurves && settings.additionalCurves.curves.length > 0\n ? {\n curves: settings.additionalCurves.curves.map((entry, idx) => ({\n ...entry,\n lineShape: entry.lineShape ?? DEFAULT_LINE_SHAPES[idx % DEFAULT_LINE_SHAPES.length],\n lineWidth: entry.lineWidth ?? 1,\n lineColor: entry.lineColor ?? BLACK,\n opacity: entry.opacity ?? 1,\n showDots: entry.showDots ?? false,\n })),\n smoothing: settings.additionalCurves.smoothing ?? false,\n }\n : null;\n\n this.layers = settings.layers\n .map(layer => {\n if (layer.type === 'dots') {\n return new DotsLayer(layer);\n } else if (layer.type === 'curve') {\n return new CurveLayer(layer);\n } else {\n throw new Error('Unknown layer type');\n }\n })\n .filter(Boolean) as ScatterplotUmapLayer[];\n }\n}\n"],"mappings":";;;AAsBA,IAAa,IAAb,MAAuB;CACnB,OAAgB;CAChB,MAKI;EACA,SAAS;EACT,UAAU;EACV,SAAS;EACT,SAAS;EACZ;CACD,YAAY,GAAuB;AAC/B,OAAK,MAAM;GACP,GAAG,KAAK;GACR,GAAG,EAAM;GACZ;;GAGI,IAAb,MAAwB;CACpB,OAAgB;CAChB;CACA,MAKI;EACA,WAAW;EACX,WAAW;EACX,WAAW;EACX,SAAS;EACZ;CAED,YAAY,GAAwB;AAEhC,EADA,KAAK,YAAY,EAAM,aAAa,IACpC,KAAK,MAAM;GACP,GAAG,KAAK;GACR,GAAG,EAAM;GACZ;;GAMI,IAAb,MAAsE;CAClE;CACA,OAAgB;CAChB;CACA;CACA;CACA;CAKA;CACA;CACA;CASA;CAWA;CAEA,YAAY,GAAmC;AAS3C,EARA,EAA8B,MAAM,EAAS,EAC7C,KAAK,KAAK,EAAO,SAAS,WAAW,EACrC,KAAK,YAAY,EAAS,aAAa,MACvC,KAAK,IAAI,EAAS,GAClB,KAAK,IAAI,EAAS,GAClB,KAAK,WAAW,EAAS,YAAY,EAAE,EACvC,KAAK,QAAQ,EAAS,SAAS,MAC/B,KAAK,YAAY,EAAS,aAAa,MACvC,KAAK,gBAAgB;GACjB,MAAM;IACF,OAAO,GAAU,MAAM,SAAA;IACvB,QAAQ,GAAU,MAAM,UAAA;IAC3B;GACD,OAAO;IACH,UAAU;IACV,MAAM;IACN,GAAG,EAAS;IACZ,MAAM,EAAS,OAAO,QAAQ;IACjC;GACD,OAAO;IACH,OAAO,EAAS,EAAE,SAAS,EAAS,EAAE;IACtC,OAAO;IACP,UAAU;IACV,WAAW;IACX,GAAG,EAAS;IACf;GACD,OAAO;IACH,OAAO,EAAS,EAAE,SAAS,EAAS,EAAE;IACtC,OAAO;IACP,UAAU;IACV,WAAW;IACX,GAAG,EAAS;IACf;GACD,OAAO,EAAC,MAAM,EAAS,OAAO,QAAQ,QAAO;GAC7C,QAAQ;IACJ,MAAM;IACN,UAAU;IACV,GAAG,EAAS;IACf;GACD,UAAU;IACN,GAAG,EAAS;IACZ,MAAQ,EAAS,UAAU,SAAS,OAAW,EAAS,UAAU,WAAW,EAAE,EAAE,SAAS;IAC7F;GACJ;EAGD,IAAM,IAAmC;GAAC;GAAU;GAAU;GAAW;GAAY;GAAW;GAAQ;AAexG,EAdA,KAAK,mBAAmB,EAAS,oBAAoB,EAAS,iBAAiB,OAAO,SAAS,IACzF;GACI,QAAQ,EAAS,iBAAiB,OAAO,KAAK,GAAO,OAAS;IAC1D,GAAG;IACH,WAAW,EAAM,aAAa,EAAoB,IAAM,EAAoB;IAC5E,WAAW,EAAM,aAAa;IAC9B,WAAW,EAAM,aAAA;IACjB,SAAS,EAAM,WAAW;IAC1B,UAAU,EAAM,YAAY;IAC/B,EAAE;GACH,WAAW,EAAS,iBAAiB,aAAa;GACrD,GACD,MAEN,KAAK,SAAS,EAAS,OAClB,KAAI,MAAS;AACV,OAAI,EAAM,SAAS,OACf,QAAO,IAAI,EAAU,EAAM;OACpB,EAAM,SAAS,QACtB,QAAO,IAAI,EAAW,EAAM;AAE5B,SAAU,MAAM,qBAAqB;IAE3C,CACD,OAAO,QAAQ"}
@@ -3,8 +3,8 @@ import { TooltipsData } from '../../common/Tooltip';
3
3
  import { LegendData } from '../../common/types';
4
4
  import { ColumnName } from '../../types';
5
5
  import { ScatterplotUmapSettingsImpl } from '../SettingsImpl';
6
- import { CaptionsSizes, ChartScales, ChartSizes, Dot, DotInfo, Margins, SVGLayerProps } from '../types';
7
- declare function LowerSvg({ scales, chartSettings, mainTitle, keyColumn: _, margins, chartSizes, container, zoomStateKey, legendData, dotsByGrouping, layers, aesGetters, tooltipData }: {
6
+ import { AdditionalCurveRenderData, CaptionsSizes, ChartScales, ChartSizes, Dot, DotInfo, Margins, SVGLayerProps } from '../types';
7
+ declare function LowerSvg({ scales, chartSettings, mainTitle, keyColumn: _, margins, chartSizes, container, zoomStateKey, legendData, dotsByGrouping, layers, additionalCurves, aesGetters, tooltipData }: {
8
8
  aesGetters: SVGLayerProps['aesGetters'];
9
9
  scales: ChartScales;
10
10
  chartSettings: ScatterplotUmapSettingsImpl['chartSettings'];
@@ -19,6 +19,7 @@ declare function LowerSvg({ scales, chartSettings, mainTitle, keyColumn: _, marg
19
19
  legendData: LegendData;
20
20
  dotsByGrouping: Record<string, Dot[]>;
21
21
  layers: ScatterplotUmapSettingsImpl['layers'];
22
+ additionalCurves: AdditionalCurveRenderData[];
22
23
  tooltipData: TooltipsData<DotInfo>;
23
24
  }): import("react/jsx-runtime").JSX.Element | null;
24
25
  declare const _default: React.MemoExoticComponent<typeof LowerSvg>;
@@ -1 +1 @@
1
- {"version":3,"file":"LowerSVG.d.ts","sourceRoot":"","sources":["../../../src/scatterplot-umap/components/LowerSVG.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAoB7G,iBAAS,QAAQ,CAAC,EACd,MAAM,EACN,aAAa,EACb,SAAS,EACT,SAAS,EAAE,CAAC,EACZ,OAAO,EACP,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,cAAc,EACd,MAAM,EACN,UAAU,EACV,WAAW,EACd,EAAE;IACC,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,2BAA2B,CAAC,eAAe,CAAC,CAAC;IAC5D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC9C,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;CACtC,kDAgKA;;AAED,wBAAoC"}
1
+ {"version":3,"file":"LowerSVG.d.ts","sourceRoot":"","sources":["../../../src/scatterplot-umap/components/LowerSVG.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,KAAK,EAAE,yBAAyB,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA4FxI,iBAAS,QAAQ,CAAC,EACd,MAAM,EACN,aAAa,EACb,SAAS,EACT,SAAS,EAAE,CAAC,EACZ,OAAO,EACP,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,cAAc,EACd,MAAM,EACN,gBAAgB,EAChB,UAAU,EACV,WAAW,EACd,EAAE;IACC,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,2BAA2B,CAAC,eAAe,CAAC,CAAC;IAC5D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC9C,gBAAgB,EAAE,yBAAyB,EAAE,CAAC;IAC9C,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;CACtC,kDA4JA;;AAED,wBAAoC"}