@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.
- package/dist/bubble/BubbleSettingsImpl.d.ts +2 -0
- package/dist/bubble/BubbleSettingsImpl.d.ts.map +1 -1
- package/dist/bubble/BubbleSettingsImpl.js +3 -1
- package/dist/bubble/BubbleSettingsImpl.js.map +1 -1
- package/dist/bubble/getGroupedCellsData.d.ts +1 -1
- package/dist/bubble/getGroupedCellsData.d.ts.map +1 -1
- package/dist/bubble/getGroupedCellsData.js +30 -10
- package/dist/bubble/getGroupedCellsData.js.map +1 -1
- package/dist/bubble/index.d.ts.map +1 -1
- package/dist/bubble/index.js +3 -3
- package/dist/bubble/index.js.map +1 -1
- package/dist/heatmap/ChartRenderer.d.ts.map +1 -1
- package/dist/heatmap/ChartRenderer.js +26 -20
- package/dist/heatmap/ChartRenderer.js.map +1 -1
- package/dist/heatmap/HeatmapSettingsImpl.d.ts +2 -0
- package/dist/heatmap/HeatmapSettingsImpl.d.ts.map +1 -1
- package/dist/heatmap/HeatmapSettingsImpl.js +3 -1
- package/dist/heatmap/HeatmapSettingsImpl.js.map +1 -1
- package/dist/heatmap/fillCellsData.d.ts +22 -2
- package/dist/heatmap/fillCellsData.d.ts.map +1 -1
- package/dist/heatmap/fillCellsData.js +60 -47
- package/dist/heatmap/fillCellsData.js.map +1 -1
- package/dist/heatmap/getCells.d.ts +22 -1
- package/dist/heatmap/getCells.d.ts.map +1 -1
- package/dist/heatmap/getCells.js +23 -3
- package/dist/heatmap/getCells.js.map +1 -1
- package/dist/heatmap/getDendrograms.d.ts +5 -1
- package/dist/heatmap/getDendrograms.d.ts.map +1 -1
- package/dist/heatmap/getDendrograms.js +33 -11
- package/dist/heatmap/getDendrograms.js.map +1 -1
- package/dist/heatmap/index.d.ts.map +1 -1
- package/dist/heatmap/index.js +30 -6
- package/dist/heatmap/index.js.map +1 -1
- package/dist/scatterplot/ChartRenderer.d.ts +2 -2
- package/dist/scatterplot/ChartRenderer.d.ts.map +1 -1
- package/dist/scatterplot/ChartRenderer.js +155 -115
- package/dist/scatterplot/ChartRenderer.js.map +1 -1
- package/dist/scatterplot/ScatterplotSettingsImpl.d.ts +11 -1
- package/dist/scatterplot/ScatterplotSettingsImpl.d.ts.map +1 -1
- package/dist/scatterplot/ScatterplotSettingsImpl.js +20 -0
- package/dist/scatterplot/ScatterplotSettingsImpl.js.map +1 -1
- package/dist/scatterplot/components/ChartLayersData.d.ts +5 -0
- package/dist/scatterplot/components/ChartLayersData.d.ts.map +1 -1
- package/dist/scatterplot/components/ChartLayersData.js +115 -35
- package/dist/scatterplot/components/ChartLayersData.js.map +1 -1
- package/dist/scatterplot/components/types.d.ts +2 -0
- package/dist/scatterplot/components/types.d.ts.map +1 -1
- package/dist/scatterplot/getLayersData.d.ts +11 -2
- package/dist/scatterplot/getLayersData.d.ts.map +1 -1
- package/dist/scatterplot/getLayersData.js +36 -19
- package/dist/scatterplot/getLayersData.js.map +1 -1
- package/dist/scatterplot/index.d.ts.map +1 -1
- package/dist/scatterplot/index.js +51 -33
- package/dist/scatterplot/index.js.map +1 -1
- package/dist/scatterplot/linearRegression.js +1 -1
- package/dist/scatterplot/utils/createAesGetter.d.ts.map +1 -1
- package/dist/scatterplot/utils/createAesGetter.js +5 -3
- package/dist/scatterplot/utils/createAesGetter.js.map +1 -1
- package/dist/scatterplot/utils/createLegendInfo.d.ts +11 -2
- package/dist/scatterplot/utils/createLegendInfo.d.ts.map +1 -1
- package/dist/scatterplot/utils/createLegendInfo.js +21 -16
- package/dist/scatterplot/utils/createLegendInfo.js.map +1 -1
- package/dist/scatterplot-umap/ChartRenderer.d.ts +6 -6
- package/dist/scatterplot-umap/ChartRenderer.d.ts.map +1 -1
- package/dist/scatterplot-umap/ChartRenderer.js +99 -57
- package/dist/scatterplot-umap/ChartRenderer.js.map +1 -1
- package/dist/scatterplot-umap/SettingsImpl.d.ts +11 -1
- package/dist/scatterplot-umap/SettingsImpl.d.ts.map +1 -1
- package/dist/scatterplot-umap/SettingsImpl.js +21 -1
- package/dist/scatterplot-umap/SettingsImpl.js.map +1 -1
- package/dist/scatterplot-umap/components/LowerSVG.d.ts +3 -2
- package/dist/scatterplot-umap/components/LowerSVG.d.ts.map +1 -1
- package/dist/scatterplot-umap/components/LowerSVG.js +159 -108
- package/dist/scatterplot-umap/components/LowerSVG.js.map +1 -1
- package/dist/scatterplot-umap/components/SVGLayer.d.ts +1 -1
- package/dist/scatterplot-umap/components/SVGLayer.d.ts.map +1 -1
- package/dist/scatterplot-umap/components/SVGLayer.js +9 -8
- package/dist/scatterplot-umap/components/SVGLayer.js.map +1 -1
- package/dist/scatterplot-umap/index.d.ts +6 -1
- package/dist/scatterplot-umap/index.d.ts.map +1 -1
- package/dist/scatterplot-umap/index.js +65 -31
- package/dist/scatterplot-umap/index.js.map +1 -1
- package/dist/scatterplot-umap/types.d.ts +7 -0
- package/dist/scatterplot-umap/types.d.ts.map +1 -1
- package/dist/types/bubble.d.ts +6 -0
- package/dist/types/bubble.d.ts.map +1 -1
- package/dist/types/bubble.js +3 -1
- package/dist/types/bubble.js.map +1 -1
- package/dist/types/heatmap.d.ts +6 -0
- package/dist/types/heatmap.d.ts.map +1 -1
- package/dist/types/heatmap.js +2 -0
- package/dist/types/heatmap.js.map +1 -1
- package/dist/types/scatterplot-umap.d.ts +763 -87
- package/dist/types/scatterplot-umap.d.ts.map +1 -1
- package/dist/types/scatterplot-umap.js +19 -3
- package/dist/types/scatterplot-umap.js.map +1 -1
- package/dist/types/scatterplot.d.ts +1377 -44
- package/dist/types/scatterplot.d.ts.map +1 -1
- package/dist/types/scatterplot.js +27 -3
- package/dist/types/scatterplot.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartLayersData.js","names":[],"sources":["../../../src/scatterplot/components/ChartLayersData.tsx"],"sourcesContent":["import { curveBasis, line } from 'd3-shape';\nimport { memo, useMemo, useState } from 'react';\nimport { getLineShape } from '../../utils/getLineShape';\nimport { getPointShape } from '../../utils/getPointShape';\nimport { TextMeasurer } from '../../utils/TextMeasurer/TextMeasurer';\nimport type { Dot, GroupedDots } from '../dots';\nimport type { ScatterplotLayerData } from '../getLayersData';\nimport type { Label } from '../utils/getVisibleLabels';\nimport { createLabelPositioner, getLabelMinX, getLabelMinY } from '../utils/getVisibleLabels';\nimport type {\n AesGetters,\n ChartScales\n} from './types';\nconst LABEL_OFFSET = 3;\n\ninterface Props {\n width: number;\n height: number;\n scales: ChartScales;\n dotsData: GroupedDots[keyof GroupedDots];\n layersData: ScatterplotLayerData[];\n aesGetters: AesGetters;\n onMouseEnterDot?: (dot: Dot) => void;\n onMouseLeaveDot?: (dot: Dot) => void;\n}\n\ntype PointValue = { valueOf(): number; } & string;\n\nexport const ChartLayersData = memo(({\n width,\n height,\n scales,\n dotsData,\n layersData,\n aesGetters,\n onMouseEnterDot,\n onMouseLeaveDot,\n}: Props) => {\n return layersData.map((layer, idx) => {\n if (layer.type === 'dots') {\n return <ChartLayerDots\n key={layer.type + idx}\n width={width}\n height={height}\n scales={scales}\n dotsData={dotsData}\n layersData={layersData}\n aesGetters={aesGetters}\n onMouseEnterDot={onMouseEnterDot}\n onMouseLeaveDot={onMouseLeaveDot}\n />;\n }\n\n if (layer.type === 'curve') {\n return <ChartCurveLayer\n key={layer.type + idx}\n layer={layer}\n scales={scales}\n aesGetters={aesGetters}\n />;\n }\n });\n});\n\nexport const ChartLayerDots = memo(({\n width,\n height,\n scales,\n dotsData,\n layersData,\n aesGetters,\n onMouseEnterDot,\n onMouseLeaveDot,\n}: Props) => {\n const {dots} = dotsData;\n\n const [activeDot, setActiveDot] = useState<Dot | null>(null);\n const hasLayerDots = useMemo(() => layersData.findIndex(layer => layer.type === 'dots') !== -1, [layersData]);\n \n const labels = useMemo<Label[]>(() =>{\n if (!hasLayerDots) return [];\n return computeLabels(\n dots,\n scales,\n width,\n height,\n aesGetters,\n );\n }, [dots, scales.x, scales.y, width, height, aesGetters, hasLayerDots]);\n\n return (\n <g>\n <ChartDots\n scales={scales}\n dotsData={dotsData}\n aesGetters={aesGetters}\n onMouseEnter={onMouseEnterDot}\n onMouseLeave={onMouseLeaveDot}\n />\n <ChartLabels\n labels={labels}\n onMouseEnter={dot => setActiveDot(dot)}\n onMouseLeave={() => setActiveDot(null)}\n />\n {activeDot && (\n <g\n key=\"activeDot\"\n transform={`translate(${scales.x(activeDot.x as PointValue)},${scales.y(activeDot.y as PointValue) as number})`}\n >\n {getPointShape(\n aesGetters.dotShape(activeDot.idx),\n aesGetters.dotSize(activeDot.idx) + 1,\n 'white',\n 'white'\n )}\n {getPointShape(\n aesGetters.dotShape(activeDot.idx),\n aesGetters.dotSize(activeDot.idx),\n aesGetters.dotColor(activeDot.idx)\n )}\n </g>\n )}\n </g>\n );\n});\n\nexport const ChartCurveLayer = memo(({\n layer,\n scales,\n aesGetters,\n}: {\n layer: ScatterplotLayerData;\n scales: ChartScales;\n aesGetters: AesGetters;\n}) => {\n if (layer.type === 'curve' && !layer.info.smoothing) {\n return layer.geoms.map((curve, idx) => (\n <g key={idx}>\n <polyline\n points={curve.dots.map(d => `${scales.x(d.x as PointValue) as number},${scales.y(d.y as PointValue) as number}`).join(' ')}\n fill=\"none\"\n stroke={aesGetters.lineColor(curve.dots[0].idx)}\n strokeWidth={layer.info.aes.lineWidth}\n strokeDasharray={getLineShape(layer.info.aes.lineShape)}\n />\n </g>\n ));\n }\n\n if (layer.type === 'curve' && layer.info.smoothing) {\n return layer.geoms.map((curve, idx) => (\n <g key={idx}>\n <path\n d={\n line<Dot>()\n .curve(curveBasis)\n .x((d: Dot) => scales.x(d.x as PointValue) as number)\n .y((d: Dot) => scales.y(d.y as PointValue) as number)(curve.dots) ?? ''\n }\n fill=\"none\"\n stroke={aesGetters.lineColor(curve.dots[0].idx)}\n strokeWidth={layer.info.aes.lineWidth}\n strokeDasharray={getLineShape(layer.info.aes.lineShape)}\n />\n </g>\n ));\n }\n});\n\nexport const ChartDots = memo(({\n scales,\n dotsData,\n aesGetters,\n onMouseEnter,\n onMouseLeave,\n}: Pick<Props, 'scales' | 'dotsData' | 'aesGetters'> & {\n onMouseEnter?: (dot: Dot) => void;\n onMouseLeave?: (dot: Dot) => void;\n}) => {\n const {dots} = dotsData;\n\n return (<>\n {dots.map((dot, idx) => {\n return <ChartDot\n key={idx}\n dot={dot}\n scales={scales}\n aesGetters={aesGetters}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />;\n })}\n </>);\n});\n\nexport const ChartDot = (({\n dot,\n scales,\n aesGetters,\n onMouseEnter,\n onMouseLeave,\n}: {\n dot: Dot;\n scales: ChartScales;\n aesGetters: AesGetters;\n onMouseEnter?: (dot: Dot) => void;\n onMouseLeave?: (dot: Dot) => void;\n}) => {\n return (<g\n transform={`translate(${scales.x(dot.x as PointValue)},${scales.y(dot.y as PointValue)})`}\n opacity={dot.dimmed ? 0.3 : 1}\n onMouseOver={() => onMouseEnter?.(dot)}\n onMouseLeave={() => onMouseLeave?.(dot)}\n >\n {getPointShape(\n aesGetters.dotShape(dot.idx),\n aesGetters.dotSize(dot.idx),\n aesGetters.dotColor(dot.idx)\n )}\n </g>);\n});\n\nexport const ChartLabels = memo(({\n labels,\n onMouseEnter,\n onMouseLeave,\n}: {\n labels: Label[];\n onMouseEnter: (dot: Dot ) => void;\n onMouseLeave: (dot: Dot ) => void;\n}) => {\n return (<>\n {labels.map((label, idx) => {\n const {name, height, width} = label;\n return (\n <g key={idx} transform={`translate(${getLabelMinX(label)},${getLabelMinY(label)})`}>\n <rect\n x=\"0\"\n y=\"0\"\n width={width}\n height={height}\n fill=\"transparent\"\n stroke=\"none\"\n onMouseEnter={() => onMouseEnter(label.dot)}\n onMouseLeave={() => onMouseLeave(label.dot)}\n />\n <text\n x={0}\n y={height / 2}\n stroke=\"white\"\n strokeWidth={2}\n paintOrder=\"stroke\"\n style={{pointerEvents: 'none'}}\n fontFamily=\"Manrope\"\n fontSize=\"16px\"\n dominantBaseline=\"middle\"\n >\n {name}\n </text>\n </g>\n );\n })}\n </>);\n});\n\nfunction computeLabels(dots: Dot[], scales: ChartScales, chartWidth: number, chartHeight: number, aesGetters: AesGetters): Label[] {\n const textMeasurer = new TextMeasurer('16px Manrope');\n const getPosition = createLabelPositioner(chartWidth, chartHeight);\n const labels: Label[] = [];\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 = scales.x(dot.x as PointValue);\n const y = scales.y(dot.y as PointValue);\n const w = metrics.width;\n const h = (metrics.actualBoundingBoxAscent) + (metrics.actualBoundingBoxDescent);\n const p = aesGetters.dotSize(dot.idx) + LABEL_OFFSET;\n const position = getPosition(x as number, y as number, w, h, p);\n if (!position) {\n continue;\n }\n\n labels.push({\n x: x as number,\n y: y as number,\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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChartLayersData.js","names":[],"sources":["../../../src/scatterplot/components/ChartLayersData.tsx"],"sourcesContent":["import { curveBasis, line } from 'd3-shape';\nimport { memo, useMemo, useState } from 'react';\nimport { getLineShape } from '../../utils/getLineShape';\nimport { getPointShape } from '../../utils/getPointShape';\nimport { TextMeasurer } from '../../utils/TextMeasurer/TextMeasurer';\nimport type { Dot, GroupedDots } from '../dots';\nimport type { AdditionalCurveLayerData, ScatterplotLayerData } from '../getLayersData';\nimport { linearRegression } from '../linearRegression';\nimport type { Label } from '../utils/getVisibleLabels';\nimport { createLabelPositioner, getLabelMinX, getLabelMinY } from '../utils/getVisibleLabels';\nimport type {\n AesGetters,\n ChartScales\n} from './types';\nconst LABEL_OFFSET = 3;\n\ninterface Props {\n width: number;\n height: number;\n scales: ChartScales;\n dotsData: GroupedDots[keyof GroupedDots];\n layersData: ScatterplotLayerData[];\n aesGetters: AesGetters;\n onMouseEnterDot?: (dot: Dot) => void;\n onMouseLeaveDot?: (dot: Dot) => void;\n}\n\ntype PointValue = { valueOf(): number; } & string;\n\nexport const ChartLayersData = memo(({\n width,\n height,\n scales,\n dotsData,\n layersData,\n aesGetters,\n onMouseEnterDot,\n onMouseLeaveDot,\n}: Props) => {\n return layersData.map((layer, idx) => {\n if (layer.type === 'dots') {\n return <ChartLayerDots\n key={layer.type + idx}\n width={width}\n height={height}\n scales={scales}\n dotsData={dotsData}\n layersData={layersData}\n aesGetters={aesGetters}\n onMouseEnterDot={onMouseEnterDot}\n onMouseLeaveDot={onMouseLeaveDot}\n />;\n }\n\n if (layer.type === 'curve') {\n return <ChartCurveLayer\n key={layer.type + idx}\n layer={layer}\n scales={scales}\n aesGetters={aesGetters}\n />;\n }\n\n if (layer.type === 'additional-curve') {\n return <ChartAdditionalCurveLayer\n key={layer.type + idx}\n layer={layer}\n scales={scales}\n aesGetters={aesGetters}\n />;\n }\n });\n});\n\nexport const ChartLayerDots = memo(({\n width,\n height,\n scales,\n dotsData,\n layersData,\n aesGetters,\n onMouseEnterDot,\n onMouseLeaveDot,\n}: Props) => {\n const {dots} = dotsData;\n\n const [activeDot, setActiveDot] = useState<Dot | null>(null);\n const hasLayerDots = useMemo(() => layersData.findIndex(layer => layer.type === 'dots') !== -1, [layersData]);\n \n const labels = useMemo<Label[]>(() =>{\n if (!hasLayerDots) return [];\n return computeLabels(\n dots,\n scales,\n width,\n height,\n aesGetters,\n );\n }, [dots, scales.x, scales.y, width, height, aesGetters, hasLayerDots]);\n\n return (\n <g>\n <ChartDots\n scales={scales}\n dotsData={dotsData}\n aesGetters={aesGetters}\n onMouseEnter={onMouseEnterDot}\n onMouseLeave={onMouseLeaveDot}\n />\n <ChartLabels\n labels={labels}\n onMouseEnter={dot => setActiveDot(dot)}\n onMouseLeave={() => setActiveDot(null)}\n />\n {activeDot && (\n <g\n key=\"activeDot\"\n transform={`translate(${scales.x(activeDot.x as PointValue)},${scales.y(activeDot.y as PointValue) as number})`}\n >\n {getPointShape(\n aesGetters.dotShape(activeDot.idx),\n aesGetters.dotSize(activeDot.idx) + 1,\n 'white',\n 'white'\n )}\n {getPointShape(\n aesGetters.dotShape(activeDot.idx),\n aesGetters.dotSize(activeDot.idx),\n aesGetters.dotColor(activeDot.idx)\n )}\n </g>\n )}\n </g>\n );\n});\n\n// Renders a single additional-curve entry.\n//\n// Rendering precedence per geom:\n// - entry.trend set → linear-regression <line>\n// - smoothing → d3 curveBasis <path>\n// - otherwise → straight <polyline>\n// Dots (showDots) render independently so they remain visible even in trend mode. Opacity applies to the\n// whole geom (line + dots) via the parent <g>.\n//\n// Color resolution matches the primary curve layer: per-geom `aesGetters.additionalCurveLineColor[entryIdx]`\n// evaluated against the first dot's row index. Trend color uses `additionalCurveTrendColor[entryIdx]`, which\n// falls back to the entry's `lineColor` when `entry.trend.color` is absent.\nconst ADDITIONAL_CURVE_DOT_SHAPE = '21';\nconst ADDITIONAL_CURVE_DOT_SIZE = 3;\n\ntype CurveSubProps = {\n dots: Dot[];\n scales: ChartScales;\n stroke: string;\n strokeWidth: number;\n dash: string | undefined;\n};\n\nfunction AdditionalCurveTrendLine({\n dots, trend, scales, stroke, strokeWidth, dash, xDomain,\n}: CurveSubProps & {\n trend: NonNullable<AdditionalCurveLayerData['entry']['trend']>;\n xDomain: [number, number];\n}) {\n const numeric = dots\n .map(d => ({ x: Number(d.x), y: Number(d.y) }))\n .filter(d => Number.isFinite(d.x) && Number.isFinite(d.y));\n if (numeric.length < 2) return null;\n const [slope, intercept] = linearRegression(numeric);\n if (!Number.isFinite(slope) || !Number.isFinite(intercept)) return null;\n const [xMin, xMax] = trend.bounded\n ? [Math.min(...numeric.map(d => d.x)), Math.max(...numeric.map(d => d.x))]\n : xDomain;\n // scales.x on a continuous axis accepts `number`; cast via `unknown` is the established\n // escape for the string-or-number PointValue union in this file.\n const x1 = scales.x(xMin as unknown as PointValue) as number;\n const x2 = scales.x(xMax as unknown as PointValue) as number;\n const y1 = scales.y((slope * xMin + intercept) as unknown as PointValue) as number;\n const y2 = scales.y((slope * xMax + intercept) as unknown as PointValue) as number;\n return (\n <line x1={x1} y1={y1} x2={x2} y2={y2}\n stroke={stroke}\n strokeWidth={strokeWidth}\n strokeDasharray={dash}\n fill=\"none\"\n />\n );\n}\n\nfunction AdditionalCurveSmoothPath({ dots, scales, stroke, strokeWidth, dash }: CurveSubProps) {\n const d = line<Dot>()\n .curve(curveBasis)\n .x((dot: Dot) => scales.x(dot.x as PointValue) as number)\n .y((dot: Dot) => scales.y(dot.y as PointValue) as number)(dots) ?? '';\n return <path d={d} fill=\"none\" stroke={stroke} strokeWidth={strokeWidth} strokeDasharray={dash} />;\n}\n\nfunction AdditionalCurvePolyline({ dots, scales, stroke, strokeWidth, dash }: CurveSubProps) {\n const points = dots\n .map(d => `${scales.x(d.x as PointValue) as number},${scales.y(d.y as PointValue) as number}`)\n .join(' ');\n return <polyline points={points} fill=\"none\" stroke={stroke} strokeWidth={strokeWidth} strokeDasharray={dash} />;\n}\n\nfunction AdditionalCurveDots({ dots, scales, stroke }: { dots: Dot[]; scales: ChartScales; stroke: string }) {\n return <>\n {dots.map((dot, idx) => (\n <g key={idx}\n transform={`translate(${scales.x(dot.x as PointValue) as number},${scales.y(dot.y as PointValue) as number})`}\n >\n {getPointShape(ADDITIONAL_CURVE_DOT_SHAPE, ADDITIONAL_CURVE_DOT_SIZE, stroke)}\n </g>\n ))}\n </>;\n}\n\nexport const ChartAdditionalCurveLayer = memo(({\n layer,\n scales,\n aesGetters,\n}: {\n layer: ScatterplotLayerData;\n scales: ChartScales;\n aesGetters: AesGetters;\n}) => {\n if (layer.type !== 'additional-curve') return null;\n const { entry, entryIdx, smoothing } = layer;\n const lineColorGetter = aesGetters.additionalCurveLineColor[entryIdx];\n const trendColorGetter = aesGetters.additionalCurveTrendColor[entryIdx];\n const dash = getLineShape(entry.lineShape);\n const xDomain = scales.x.domain() as [number, number];\n\n return layer.geoms.map((curve, idx) => {\n const firstDotIdx = curve.dots[0].idx;\n const stroke = lineColorGetter(firstDotIdx);\n const lineElement = entry.trend\n ? <AdditionalCurveTrendLine\n dots={curve.dots}\n trend={entry.trend}\n scales={scales}\n stroke={trendColorGetter(firstDotIdx)}\n strokeWidth={entry.lineWidth}\n dash={dash}\n xDomain={xDomain}\n />\n : smoothing\n ? <AdditionalCurveSmoothPath dots={curve.dots} scales={scales} stroke={stroke} strokeWidth={entry.lineWidth} dash={dash} />\n : <AdditionalCurvePolyline dots={curve.dots} scales={scales} stroke={stroke} strokeWidth={entry.lineWidth} dash={dash} />;\n\n return (\n <g key={idx} opacity={entry.opacity}>\n {lineElement}\n {entry.showDots && <AdditionalCurveDots dots={curve.dots} scales={scales} stroke={stroke} />}\n </g>\n );\n });\n});\n\nexport const ChartCurveLayer = memo(({\n layer,\n scales,\n aesGetters,\n}: {\n layer: ScatterplotLayerData;\n scales: ChartScales;\n aesGetters: AesGetters;\n}) => {\n if (layer.type === 'curve' && !layer.info.smoothing) {\n return layer.geoms.map((curve, idx) => (\n <g key={idx}>\n <polyline\n points={curve.dots.map(d => `${scales.x(d.x as PointValue) as number},${scales.y(d.y as PointValue) as number}`).join(' ')}\n fill=\"none\"\n stroke={aesGetters.lineColor(curve.dots[0].idx)}\n strokeWidth={layer.info.aes.lineWidth}\n strokeDasharray={getLineShape(layer.info.aes.lineShape)}\n />\n </g>\n ));\n }\n\n if (layer.type === 'curve' && layer.info.smoothing) {\n return layer.geoms.map((curve, idx) => (\n <g key={idx}>\n <path\n d={\n line<Dot>()\n .curve(curveBasis)\n .x((d: Dot) => scales.x(d.x as PointValue) as number)\n .y((d: Dot) => scales.y(d.y as PointValue) as number)(curve.dots) ?? ''\n }\n fill=\"none\"\n stroke={aesGetters.lineColor(curve.dots[0].idx)}\n strokeWidth={layer.info.aes.lineWidth}\n strokeDasharray={getLineShape(layer.info.aes.lineShape)}\n />\n </g>\n ));\n }\n});\n\nexport const ChartDots = memo(({\n scales,\n dotsData,\n aesGetters,\n onMouseEnter,\n onMouseLeave,\n}: Pick<Props, 'scales' | 'dotsData' | 'aesGetters'> & {\n onMouseEnter?: (dot: Dot) => void;\n onMouseLeave?: (dot: Dot) => void;\n}) => {\n const {dots} = dotsData;\n\n return (<>\n {dots.map((dot, idx) => {\n return <ChartDot\n key={idx}\n dot={dot}\n scales={scales}\n aesGetters={aesGetters}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />;\n })}\n </>);\n});\n\nexport const ChartDot = (({\n dot,\n scales,\n aesGetters,\n onMouseEnter,\n onMouseLeave,\n}: {\n dot: Dot;\n scales: ChartScales;\n aesGetters: AesGetters;\n onMouseEnter?: (dot: Dot) => void;\n onMouseLeave?: (dot: Dot) => void;\n}) => {\n return (<g\n transform={`translate(${scales.x(dot.x as PointValue)},${scales.y(dot.y as PointValue)})`}\n opacity={dot.dimmed ? 0.3 : 1}\n onMouseOver={() => onMouseEnter?.(dot)}\n onMouseLeave={() => onMouseLeave?.(dot)}\n >\n {getPointShape(\n aesGetters.dotShape(dot.idx),\n aesGetters.dotSize(dot.idx),\n aesGetters.dotColor(dot.idx)\n )}\n </g>);\n});\n\nexport const ChartLabels = memo(({\n labels,\n onMouseEnter,\n onMouseLeave,\n}: {\n labels: Label[];\n onMouseEnter: (dot: Dot ) => void;\n onMouseLeave: (dot: Dot ) => void;\n}) => {\n return (<>\n {labels.map((label, idx) => {\n const {name, height, width} = label;\n return (\n <g key={idx} transform={`translate(${getLabelMinX(label)},${getLabelMinY(label)})`}>\n <rect\n x=\"0\"\n y=\"0\"\n width={width}\n height={height}\n fill=\"transparent\"\n stroke=\"none\"\n onMouseEnter={() => onMouseEnter(label.dot)}\n onMouseLeave={() => onMouseLeave(label.dot)}\n />\n <text\n x={0}\n y={height / 2}\n stroke=\"white\"\n strokeWidth={2}\n paintOrder=\"stroke\"\n style={{pointerEvents: 'none'}}\n fontFamily=\"Manrope\"\n fontSize=\"16px\"\n dominantBaseline=\"middle\"\n >\n {name}\n </text>\n </g>\n );\n })}\n </>);\n});\n\nfunction computeLabels(dots: Dot[], scales: ChartScales, chartWidth: number, chartHeight: number, aesGetters: AesGetters): Label[] {\n const textMeasurer = new TextMeasurer('16px Manrope');\n const getPosition = createLabelPositioner(chartWidth, chartHeight);\n const labels: Label[] = [];\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 = scales.x(dot.x as PointValue);\n const y = scales.y(dot.y as PointValue);\n const w = metrics.width;\n const h = (metrics.actualBoundingBoxAscent) + (metrics.actualBoundingBoxDescent);\n const p = aesGetters.dotSize(dot.idx) + LABEL_OFFSET;\n const position = getPosition(x as number, y as number, w, h, p);\n if (!position) {\n continue;\n }\n\n labels.push({\n x: x as number,\n y: y as number,\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"],"mappings":";;;;;;;;AAcA,IAAM,IAAe;AAerB,MAAa,IAAkB,GAAM,EACjC,UACA,WACA,WACA,aACA,eACA,eACA,oBACA,yBAEO,EAAW,KAAK,GAAO,MAAQ;AAClC,KAAI,EAAM,SAAS,OACf,QAAO,kBAAC,GAAD;EAEI;EACC;EACA;EACE;EACE;EACA;EACK;EACA;EACnB,EATO,EAAM,OAAO,EASpB;AAGN,KAAI,EAAM,SAAS,QACf,QAAO,kBAAC,GAAD;EAEI;EACC;EACI;EACd,EAJO,EAAM,OAAO,EAIpB;AAGN,KAAI,EAAM,SAAS,mBACf,QAAO,kBAAC,GAAD;EAEI;EACC;EACI;EACd,EAJO,EAAM,OAAO,EAIpB;EAER,CACJ,EAEW,IAAiB,GAAM,EAChC,UACA,WACA,WACA,aACA,eACA,eACA,oBACA,yBACS;CACT,IAAM,EAAC,YAAQ,GAET,CAAC,GAAW,KAAgB,EAAqB,KAAK,EACtD,IAAe,QAAc,EAAW,WAAU,MAAS,EAAM,SAAS,OAAO,KAAK,IAAI,CAAC,EAAW,CAAC,EAEvG,IAAS,QACN,IACE,EACH,GACA,GACA,GACA,GACA,EACH,GAPyB,EAAE,EAQ7B;EAAC;EAAM,EAAO;EAAG,EAAO;EAAG;EAAO;EAAQ;EAAY;EAAa,CAAC;AAEvE,QACI,kBAAC,KAAD,EAAA,UAAA;EACI,kBAAC,GAAD;GACY;GACE;GACE;GACZ,cAAc;GACd,cAAc;GAChB,CAAA;EACF,kBAAC,GAAD;GACY;GACR,eAAc,MAAO,EAAa,EAAI;GACtC,oBAAoB,EAAa,KAAK;GACxC,CAAA;EACD,KACG,kBAAC,KAAD;GAEI,WAAW,aAAa,EAAO,EAAE,EAAU,EAAgB,CAAC,GAAG,EAAO,EAAE,EAAU,EAAgB,CAAW;aAFjH,CAIK,EACG,EAAW,SAAS,EAAU,IAAI,EAClC,EAAW,QAAQ,EAAU,IAAI,GAAG,GACpC,SACA,QACH,EACA,EACG,EAAW,SAAS,EAAU,IAAI,EAClC,EAAW,QAAQ,EAAU,IAAI,EACjC,EAAW,SAAS,EAAU,IAAI,CACrC,CACD;KAdI,YAcJ;EAER,EAAA,CAAA;EAEV;AAcF,IAAM,IAA6B,MAC7B,IAA4B;AAUlC,SAAS,EAAyB,EAC9B,SAAM,UAAO,WAAQ,WAAQ,gBAAa,SAAM,cAIjD;CACC,IAAM,IAAU,EACX,KAAI,OAAM;EAAE,GAAG,OAAO,EAAE,EAAE;EAAE,GAAG,OAAO,EAAE,EAAE;EAAE,EAAE,CAC9C,QAAO,MAAK,OAAO,SAAS,EAAE,EAAE,IAAI,OAAO,SAAS,EAAE,EAAE,CAAC;AAC9D,KAAI,EAAQ,SAAS,EAAG,QAAO;CAC/B,IAAM,CAAC,GAAO,KAAa,EAAiB,EAAQ;AACpD,KAAI,CAAC,OAAO,SAAS,EAAM,IAAI,CAAC,OAAO,SAAS,EAAU,CAAE,QAAO;CACnE,IAAM,CAAC,GAAM,KAAQ,EAAM,UACrB,CAAC,KAAK,IAAI,GAAG,EAAQ,KAAI,MAAK,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,GAAG,EAAQ,KAAI,MAAK,EAAE,EAAE,CAAC,CAAC,GACxE,GAGA,IAAK,EAAO,EAAE,EAA8B,EAC5C,IAAK,EAAO,EAAE,EAA8B;AAGlD,QACI,kBAAC,QAAD;EAAU;EAAQ,IAHX,EAAO,EAAG,IAAQ,IAAO,EAAoC;EAG1C;EAAQ,IAF3B,EAAO,EAAG,IAAQ,IAAO,EAAoC;EAGxD;EACK;EACb,iBAAiB;EACjB,MAAK;EACP,CAAA;;AAIV,SAAS,EAA0B,EAAE,SAAM,WAAQ,WAAQ,gBAAa,WAAuB;AAK3F,QAAO,kBAAC,QAAD;EAAS,GAJN,GAAW,CAChB,MAAM,EAAW,CACjB,GAAG,MAAa,EAAO,EAAE,EAAI,EAAgB,CAAW,CACxD,GAAG,MAAa,EAAO,EAAE,EAAI,EAAgB,CAAW,CAAC,EAAK,IAAI;EACpD,MAAK;EAAe;EAAqB;EAAa,iBAAiB;EAAQ,CAAA;;AAGtG,SAAS,EAAwB,EAAE,SAAM,WAAQ,WAAQ,gBAAa,WAAuB;AAIzF,QAAO,kBAAC,YAAD;EAAkB,QAHV,EACV,KAAI,MAAK,GAAG,EAAO,EAAE,EAAE,EAAgB,CAAW,GAAG,EAAO,EAAE,EAAE,EAAgB,GAAa,CAC7F,KAAK,IAAI;EACmB,MAAK;EAAe;EAAqB;EAAa,iBAAiB;EAAQ,CAAA;;AAGpH,SAAS,EAAoB,EAAE,SAAM,WAAQ,aAAgE;AACzG,QAAO,kBAAA,GAAA,EAAA,UACF,EAAK,KAAK,GAAK,MACZ,kBAAC,KAAD;EACI,WAAW,aAAa,EAAO,EAAE,EAAI,EAAgB,CAAW,GAAG,EAAO,EAAE,EAAI,EAAgB,CAAW;YAE1G,EAAc,GAA4B,GAA2B,EAAO;EAC7E,EAJI,EAIJ,CACN,EACH,CAAA;;AAGP,MAAa,IAA4B,GAAM,EAC3C,UACA,WACA,oBAKE;AACF,KAAI,EAAM,SAAS,mBAAoB,QAAO;CAC9C,IAAM,EAAE,UAAO,aAAU,iBAAc,GACjC,IAAkB,EAAW,yBAAyB,IACtD,IAAmB,EAAW,0BAA0B,IACxD,IAAO,EAAa,EAAM,UAAU,EACpC,IAAU,EAAO,EAAE,QAAQ;AAEjC,QAAO,EAAM,MAAM,KAAK,GAAO,MAAQ;EACnC,IAAM,IAAc,EAAM,KAAK,GAAG,KAC5B,IAAS,EAAgB,EAAY,EACrC,IAAc,EAAM,QACpB,kBAAC,GAAD;GACE,MAAM,EAAM;GACZ,OAAO,EAAM;GACL;GACR,QAAQ,EAAiB,EAAY;GACrC,aAAa,EAAM;GACb;GACG;GACX,CAAA,GAEI,EADJ,IACK,IACA,GADD;GAA2B,MAAM,EAAM;GAAc;GAAgB;GAAQ,aAAa,EAAM;GAAiB;GAAQ,CACF;AAEjI,SACI,kBAAC,KAAD;GAAa,SAAS,EAAM;aAA5B,CACK,GACA,EAAM,YAAY,kBAAC,GAAD;IAAqB,MAAM,EAAM;IAAc;IAAgB;IAAU,CAAA,CAC5F;KAHI,EAGJ;GAEV;EACJ,EAEW,IAAkB,GAAM,EACjC,UACA,WACA,oBAKE;AACF,KAAI,EAAM,SAAS,WAAW,CAAC,EAAM,KAAK,UACtC,QAAO,EAAM,MAAM,KAAK,GAAO,MAC3B,kBAAC,KAAD,EAAA,UACI,kBAAC,YAAD;EACI,QAAQ,EAAM,KAAK,KAAI,MAAK,GAAG,EAAO,EAAE,EAAE,EAAgB,CAAW,GAAG,EAAO,EAAE,EAAE,EAAgB,GAAa,CAAC,KAAK,IAAI;EAC1H,MAAK;EACL,QAAQ,EAAW,UAAU,EAAM,KAAK,GAAG,IAAI;EAC/C,aAAa,EAAM,KAAK,IAAI;EAC5B,iBAAiB,EAAa,EAAM,KAAK,IAAI,UAAU;EACzD,CAAA,EACF,EARI,EAQJ,CACN;AAGN,KAAI,EAAM,SAAS,WAAW,EAAM,KAAK,UACrC,QAAO,EAAM,MAAM,KAAK,GAAO,MAC3B,kBAAC,KAAD,EAAA,UACI,kBAAC,QAAD;EACI,GACI,GAAW,CACN,MAAM,EAAW,CACjB,GAAG,MAAW,EAAO,EAAE,EAAE,EAAgB,CAAW,CACpD,GAAG,MAAW,EAAO,EAAE,EAAE,EAAgB,CAAW,CAAC,EAAM,KAAK,IAAI;EAE7E,MAAK;EACL,QAAQ,EAAW,UAAU,EAAM,KAAK,GAAG,IAAI;EAC/C,aAAa,EAAM,KAAK,IAAI;EAC5B,iBAAiB,EAAa,EAAM,KAAK,IAAI,UAAU;EACzD,CAAA,EACF,EAbI,EAaJ,CACN;EAER,EAEW,IAAY,GAAM,EAC3B,WACA,aACA,eACA,iBACA,sBAIE;CACF,IAAM,EAAC,YAAQ;AAEf,QAAQ,kBAAA,GAAA,EAAA,UACH,EAAK,KAAK,GAAK,MACL,kBAAC,GAAD;EAEE;EACG;EACI;EACE;EACA;EAChB,EANO,EAMP,CACJ,EACH,CAAA;EACL,EAEW,MAAa,EACtB,QACA,WACA,eACA,iBACA,sBAQQ,kBAAC,KAAD;CACJ,WAAW,aAAa,EAAO,EAAE,EAAI,EAAgB,CAAC,GAAG,EAAO,EAAE,EAAI,EAAgB,CAAC;CACvF,SAAS,EAAI,SAAS,KAAM;CAC5B,mBAAmB,IAAe,EAAI;CACtC,oBAAoB,IAAe,EAAI;WAEtC,EACG,EAAW,SAAS,EAAI,IAAI,EAC5B,EAAW,QAAQ,EAAI,IAAI,EAC3B,EAAW,SAAS,EAAI,IAAI,CAC/B;CACD,CAAA,GAGK,IAAc,GAAM,EAC7B,WACA,iBACA,sBAMQ,kBAAA,GAAA,EAAA,UACH,EAAO,KAAK,GAAO,MAAQ;CACxB,IAAM,EAAC,SAAM,WAAS,aAAS;AAC/B,QACI,kBAAC,KAAD;EAAa,WAAW,aAAa,EAAa,EAAM,CAAC,GAAG,EAAa,EAAM,CAAC;YAAhF,CACI,kBAAC,QAAD;GACI,GAAE;GACF,GAAE;GACK;GACC;GACR,MAAK;GACL,QAAO;GACP,oBAAoB,EAAa,EAAM,IAAI;GAC3C,oBAAoB,EAAa,EAAM,IAAI;GAC7C,CAAA,EACF,kBAAC,QAAD;GACI,GAAG;GACH,GAAG,IAAS;GACZ,QAAO;GACP,aAAa;GACb,YAAW;GACX,OAAO,EAAC,eAAe,QAAO;GAC9B,YAAW;GACX,UAAS;GACT,kBAAiB;aAEhB;GACE,CAAA,CACP;IAxBI,EAwBJ;EAEV,EACH,CAAA,CACL;AAEF,SAAS,EAAc,GAAa,GAAqB,GAAoB,GAAqB,GAAiC;CAC/H,IAAM,IAAe,IAAI,EAAa,eAAe,EAC/C,IAAc,EAAsB,GAAY,EAAY,EAC5D,IAAkB,EAAE;AAE1B,MAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;EAClC,IAAM,IAAM,EAAK;AACjB,MAAI,EAAI,SAAS,KACb;EAEJ,IAAM,IAAO,OAAO,EAAI,MAAM,EACxB,IAAU,EAAa,eAAe,EAAK,EAC3C,IAAI,EAAO,EAAE,EAAI,EAAgB,EACjC,IAAI,EAAO,EAAE,EAAI,EAAgB,EACjC,IAAI,EAAQ,OACZ,IAAK,EAAQ,0BAA4B,EAAQ,0BACjD,IAAI,EAAW,QAAQ,EAAI,IAAI,GAAG,GAClC,IAAW,EAAY,GAAa,GAAa,GAAG,GAAG,EAAE;AAC1D,OAIL,EAAO,KAAK;GACL;GACA;GACH;GACA;GACA,OAAO;GACP,QAAQ;GACR,SAAS;GACT,WAAW,EAAS;GACpB,WAAW,EAAS;GACvB,CAAiB;;AAGtB,QAAO"}
|
|
@@ -59,6 +59,8 @@ export type AesGetters = {
|
|
|
59
59
|
lineShape: (rowIndex: number) => LineShape;
|
|
60
60
|
lineColor: (rowIndex: number) => string;
|
|
61
61
|
trendColor: (rowIndex: number) => string;
|
|
62
|
+
additionalCurveLineColor: ((rowIndex: number) => string)[];
|
|
63
|
+
additionalCurveTrendColor: ((rowIndex: number) => string)[];
|
|
62
64
|
};
|
|
63
65
|
export type DiscreteAxisData = {
|
|
64
66
|
keys: (string | number)[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/scatterplot/components/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,OAAO;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC1F,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;AACxD,MAAM,WAAW,WAAW;IACxB,CAAC,EAAE,YAAY,GAAG,aAAa,CAAC;IAChC,CAAC,EAAE,YAAY,GAAG,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAEzB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAChE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QACH,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,EAAE;QACH,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,cAAc,EAAE,CAAC,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;CAC3D;AAED,MAAM,WAAW,aAAa;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,6BAA6B,EAAE,MAAM,EAAE,CAAC;IACxC,8BAA8B,EAAE,MAAM,EAAE,CAAC;IACzC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnF,MAAM,MAAM,UAAU,GAAG;IACrB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAAU,CAAC;IAC3C,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS,CAAC;IAC3C,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/scatterplot/components/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,15 @@ export type CurveLayerData = {
|
|
|
16
16
|
info: CurveLayer;
|
|
17
17
|
geoms: CurveData[];
|
|
18
18
|
};
|
|
19
|
-
|
|
20
|
-
export
|
|
19
|
+
type AdditionalCurveEntryNormalized = NonNullable<ScatterplotSettingsImpl['additionalCurves']>['curves'][number];
|
|
20
|
+
export type AdditionalCurveLayerData = {
|
|
21
|
+
type: 'additional-curve';
|
|
22
|
+
entry: AdditionalCurveEntryNormalized;
|
|
23
|
+
entryIdx: number;
|
|
24
|
+
smoothing: boolean;
|
|
25
|
+
geoms: CurveData[];
|
|
26
|
+
};
|
|
27
|
+
export type ScatterplotLayerData = DotsLayerData | CurveLayerData | AdditionalCurveLayerData;
|
|
28
|
+
export declare function getLayersData(dataFrame: DataFrame, layers: ScatterplotLayer[], facetKeys: string[], dotsByFacets: GroupedDots, categoryGroupingCombinations: string[][], grouping: ColumnName[], axisX: ScatterplotSettingsImpl['chartSettings']['xAxis'], discreteAxisDataX: DiscreteAxisData, additionalCurves: ScatterplotSettingsImpl['additionalCurves']): Record<string, ScatterplotLayerData[]>;
|
|
29
|
+
export {};
|
|
21
30
|
//# sourceMappingURL=getLayersData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLayersData.d.ts","sourceRoot":"","sources":["../../src/scatterplot/getLayersData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEhG,MAAM,MAAM,aAAa,GAAI;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACpB,IAAI,EAAE,GAAG,EAAE,CAAC;CACf,CAAA;AACD,MAAM,MAAM,cAAc,GAAI;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"getLayersData.d.ts","sourceRoot":"","sources":["../../src/scatterplot/getLayersData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEhG,MAAM,MAAM,aAAa,GAAI;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACpB,IAAI,EAAE,GAAG,EAAE,CAAC;CACf,CAAA;AACD,MAAM,MAAM,cAAc,GAAI;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAA;CACrB,CAAA;AAID,KAAK,8BAA8B,GAAG,WAAW,CAAC,uBAAuB,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AACjH,MAAM,MAAM,wBAAwB,GAAG;IACnC,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,8BAA8B,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,cAAc,GAAG,wBAAwB,CAAC;AAsB7F,wBAAgB,aAAa,CACzB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,gBAAgB,EAAE,EAC1B,SAAS,EAAE,MAAM,EAAE,EACnB,YAAY,EAAE,WAAW,EACzB,4BAA4B,EAAE,MAAM,EAAE,EAAE,EACxC,QAAQ,EAAE,UAAU,EAAE,EACtB,KAAK,EAAE,uBAAuB,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,EACxD,iBAAiB,EAAE,gBAAgB,EACnC,gBAAgB,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,GAC9D,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAkExC"}
|
|
@@ -9,25 +9,42 @@ function t(e, t, n) {
|
|
|
9
9
|
}), e.sort();
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
function n(n, r, i, a, o, s, c, l) {
|
|
13
|
-
return i.reduce((i,
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
function n(n, r, i, a, o, s, c, l, u) {
|
|
13
|
+
return i.reduce((i, d) => {
|
|
14
|
+
let f = a[d].dots, p = r.map((r) => r.type === "curve" ? {
|
|
15
|
+
type: "curve",
|
|
16
|
+
info: r,
|
|
17
|
+
geoms: o.map((e) => {
|
|
18
|
+
let r = f.filter((t) => s.every((r, i) => String(n.getColumnValue(r.value, t.idx)) === e[i]));
|
|
19
|
+
return t(r, c, l), { dots: r };
|
|
20
|
+
}).filter((e) => e.dots.length > 0)
|
|
21
|
+
} : r.type === "dots" ? {
|
|
22
|
+
type: "dots",
|
|
23
|
+
info: r,
|
|
24
|
+
geoms: f
|
|
25
|
+
} : (e(r, "Unknown scatterplot layer type"), null));
|
|
26
|
+
if (u) for (let [e, r] of u.curves.entries()) {
|
|
27
|
+
let i = r.columnName.value, a = o.map((e) => {
|
|
28
|
+
let r = [];
|
|
29
|
+
for (let t of f) {
|
|
30
|
+
if (!s.every((r, i) => String(n.getColumnValue(r.value, t.idx)) === e[i])) continue;
|
|
31
|
+
let a = n.getColumnValue(i, t.idx);
|
|
32
|
+
a !== null && (typeof a == "number" && !Number.isFinite(a) || r.push({
|
|
33
|
+
...t,
|
|
34
|
+
y: a
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
return t(r, c, l), { dots: r };
|
|
38
|
+
}).filter((e) => e.dots.length > 0);
|
|
39
|
+
p.push({
|
|
40
|
+
type: "additional-curve",
|
|
41
|
+
entry: r,
|
|
42
|
+
entryIdx: e,
|
|
43
|
+
smoothing: u.smoothing,
|
|
44
|
+
geoms: a
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return i[d] = p, i;
|
|
31
48
|
}, {});
|
|
32
49
|
}
|
|
33
50
|
export { n as getLayersData };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLayersData.js","names":[],"sources":["../../src/scatterplot/getLayersData.ts"],"sourcesContent":["import type { DataFrame } from '../DataFrame';\nimport type { ColumnName, ScatterplotLayer } from '../types';\nimport { exhaustive } from '../utils';\nimport type { DiscreteAxisData } from './components/types';\nimport type { Dot, GroupedDots } from './dots';\nimport type { CurveLayer, DotsLayer, ScatterplotSettingsImpl } from './ScatterplotSettingsImpl';\n\nexport type DotsLayerData = {\n type: 'dots',\n info: DotsLayer,\n geoms: Dot[]\n}\n\nexport type CurveData = {\n dots: Dot[],\n}\nexport type CurveLayerData = {\n type: 'curve',\n info: CurveLayer,\n geoms: CurveData[]\n}\n\nexport type ScatterplotLayerData = DotsLayerData | CurveLayerData;\n\nfunction sortDotsForCurve(dots:Dot[], axisX: ScatterplotSettingsImpl['chartSettings']['xAxis'], discreteAxisDataX: DiscreteAxisData) {\n if (axisX.scale !== 'discrete') {\n dots.sort((d1, d2) => (d1.x as number) - (d2.x as number));\n } else {\n const weightsByColumnByOrder = discreteAxisDataX.keys.reduce((res, key, idx) => {\n res[key] = discreteAxisDataX.keys.length - idx;\n return res;\n }, {} as Record<string, number>);\n\n dots.sort((d1, d2) => {\n const aWeight = weightsByColumnByOrder[d1.x];\n const bWeight = weightsByColumnByOrder[d2.x];\n if (aWeight !== bWeight) {\n return aWeight - bWeight;\n }\n return 0;\n });\n dots.sort();\n }\n}\nexport function getLayersData(\n dataFrame: DataFrame,\n layers: ScatterplotLayer[],\n facetKeys: string[],\n dotsByFacets: GroupedDots,\n categoryGroupingCombinations: string[][],\n grouping: ColumnName[],\n axisX: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n discreteAxisDataX: DiscreteAxisData,\n): Record<string, ScatterplotLayerData[]> {\n return facetKeys.reduce((res:Record<string, ScatterplotLayerData[]>, key) => {\n const facetDots = dotsByFacets[key].dots;\n
|
|
1
|
+
{"version":3,"file":"getLayersData.js","names":[],"sources":["../../src/scatterplot/getLayersData.ts"],"sourcesContent":["import type { DataFrame } from '../DataFrame';\nimport type { ColumnName, ScatterplotLayer } from '../types';\nimport { exhaustive } from '../utils';\nimport type { DiscreteAxisData } from './components/types';\nimport type { Dot, GroupedDots } from './dots';\nimport type { CurveLayer, DotsLayer, ScatterplotSettingsImpl } from './ScatterplotSettingsImpl';\n\nexport type DotsLayerData = {\n type: 'dots',\n info: DotsLayer,\n geoms: Dot[]\n}\n\nexport type CurveData = {\n dots: Dot[],\n}\nexport type CurveLayerData = {\n type: 'curve',\n info: CurveLayer,\n geoms: CurveData[]\n}\n\n// Renders an additional-curve overlay (spec `additionalCurves.curves[i]`). Each entry carries its own\n// aesthetics; `geoms` holds per-grouping dots sourced from the entry's column, sharing x with primary data.\ntype AdditionalCurveEntryNormalized = NonNullable<ScatterplotSettingsImpl['additionalCurves']>['curves'][number];\nexport type AdditionalCurveLayerData = {\n type: 'additional-curve',\n entry: AdditionalCurveEntryNormalized,\n entryIdx: number,\n smoothing: boolean,\n geoms: CurveData[]\n}\n\nexport type ScatterplotLayerData = DotsLayerData | CurveLayerData | AdditionalCurveLayerData;\n\nfunction sortDotsForCurve(dots:Dot[], axisX: ScatterplotSettingsImpl['chartSettings']['xAxis'], discreteAxisDataX: DiscreteAxisData) {\n if (axisX.scale !== 'discrete') {\n dots.sort((d1, d2) => (d1.x as number) - (d2.x as number));\n } else {\n const weightsByColumnByOrder = discreteAxisDataX.keys.reduce((res, key, idx) => {\n res[key] = discreteAxisDataX.keys.length - idx;\n return res;\n }, {} as Record<string, number>);\n\n dots.sort((d1, d2) => {\n const aWeight = weightsByColumnByOrder[d1.x];\n const bWeight = weightsByColumnByOrder[d2.x];\n if (aWeight !== bWeight) {\n return aWeight - bWeight;\n }\n return 0;\n });\n dots.sort();\n }\n}\nexport function getLayersData(\n dataFrame: DataFrame,\n layers: ScatterplotLayer[],\n facetKeys: string[],\n dotsByFacets: GroupedDots,\n categoryGroupingCombinations: string[][],\n grouping: ColumnName[],\n axisX: ScatterplotSettingsImpl['chartSettings']['xAxis'],\n discreteAxisDataX: DiscreteAxisData,\n additionalCurves: ScatterplotSettingsImpl['additionalCurves'],\n): Record<string, ScatterplotLayerData[]> {\n return facetKeys.reduce((res:Record<string, ScatterplotLayerData[]>, key) => {\n const facetDots = dotsByFacets[key].dots;\n const layerData: ScatterplotLayerData[] = layers.map(layer => {\n if (layer.type === 'curve') {\n return {\n type: 'curve',\n info: layer,\n geoms: categoryGroupingCombinations.map(values => {\n const dots = facetDots.filter(dot =>\n grouping.every((column, idx) => String(dataFrame.getColumnValue(column.value, dot.idx)) === values[idx])\n );\n sortDotsForCurve(dots, axisX, discreteAxisDataX);\n return {dots};\n }).filter(item => item.dots.length > 0)\n } as CurveLayerData;\n }\n if (layer.type === 'dots') {\n return {\n type: 'dots',\n info: layer,\n geoms: facetDots,\n } as DotsLayerData;\n }\n exhaustive(layer, 'Unknown scatterplot layer type');\n return null as never;\n });\n\n // additionalCurves: per entry, build per-group polylines sourced from entry.columnName (y).\n // Dots share primary x; y comes from the overlay column. Null values drop from the group;\n // groups that end up empty are filtered out.\n if (additionalCurves) {\n for (const [entryIdx, entry] of additionalCurves.curves.entries()) {\n const overlayColumn = entry.columnName.value;\n const geoms = categoryGroupingCombinations\n .map((values) => {\n const dots: Dot[] = [];\n for (const dot of facetDots) {\n const groupingOk = grouping.every(\n (column, idx) => String(dataFrame.getColumnValue(column.value, dot.idx)) === values[idx],\n );\n if (!groupingOk) continue;\n const overlayY = dataFrame.getColumnValue(overlayColumn, dot.idx);\n // Drop null and non-finite values (NaN, ±Infinity) — they'd propagate into d3 scales\n // and emit `NaN` SVG coords. Matches UMAP's filter in scatterplot-umap/index.ts _updateData.\n if (overlayY === null) continue;\n if (typeof overlayY === 'number' && !Number.isFinite(overlayY)) continue;\n dots.push({ ...dot, y: overlayY as string | number });\n }\n sortDotsForCurve(dots, axisX, discreteAxisDataX);\n return { dots };\n })\n .filter((item) => item.dots.length > 0);\n layerData.push({\n type: 'additional-curve',\n entry,\n entryIdx,\n smoothing: additionalCurves.smoothing,\n geoms,\n });\n }\n }\n\n res[key] = layerData;\n return res;\n }, {});\n}\n"],"mappings":";AAmCA,SAAS,EAAiB,GAAY,GAA0D,GAAqC;AACjI,KAAI,EAAM,UAAU,WAChB,GAAK,MAAM,GAAI,MAAQ,EAAG,IAAgB,EAAG,EAAa;MACvD;EACH,IAAM,IAAyB,EAAkB,KAAK,QAAQ,GAAK,GAAK,OACpE,EAAI,KAAO,EAAkB,KAAK,SAAS,GACpC,IACR,EAAE,CAA2B;AAUhC,EARA,EAAK,MAAM,GAAI,MAAO;GAClB,IAAM,IAAU,EAAuB,EAAG,IACpC,IAAU,EAAuB,EAAG;AAI1C,UAHI,MAAY,IAGT,IAFI,IAAU;IAGvB,EACF,EAAK,MAAM;;;AAGnB,SAAgB,EACZ,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACsC;AACtC,QAAO,EAAU,QAAQ,GAA4C,MAAQ;EACzE,IAAM,IAAY,EAAa,GAAK,MAC9B,IAAoC,EAAO,KAAI,MAC7C,EAAM,SAAS,UACR;GACH,MAAM;GACN,MAAM;GACN,OAAO,EAA6B,KAAI,MAAU;IAC9C,IAAM,IAAO,EAAU,QAAO,MAC1B,EAAS,OAAO,GAAQ,MAAQ,OAAO,EAAU,eAAe,EAAO,OAAO,EAAI,IAAI,CAAC,KAAK,EAAO,GAAK,CAC3G;AAED,WADA,EAAiB,GAAM,GAAO,EAAkB,EACzC,EAAC,SAAK;KACf,CAAC,QAAO,MAAQ,EAAK,KAAK,SAAS,EAAE;GAC1C,GAED,EAAM,SAAS,SACR;GACH,MAAM;GACN,MAAM;GACN,OAAO;GACV,IAEL,EAAW,GAAO,iCAAiC,EAC5C,MACT;AAKF,MAAI,EACA,MAAK,IAAM,CAAC,GAAU,MAAU,EAAiB,OAAO,SAAS,EAAE;GAC/D,IAAM,IAAgB,EAAM,WAAW,OACjC,IAAQ,EACT,KAAK,MAAW;IACb,IAAM,IAAc,EAAE;AACtB,SAAK,IAAM,KAAO,GAAW;AAIzB,SAAI,CAHe,EAAS,OACvB,GAAQ,MAAQ,OAAO,EAAU,eAAe,EAAO,OAAO,EAAI,IAAI,CAAC,KAAK,EAAO,GACvF,CACgB;KACjB,IAAM,IAAW,EAAU,eAAe,GAAe,EAAI,IAAI;AAG7D,WAAa,SACb,OAAO,KAAa,YAAY,CAAC,OAAO,SAAS,EAAS,IAC9D,EAAK,KAAK;MAAE,GAAG;MAAK,GAAG;MAA6B,CAAC;;AAGzD,WADA,EAAiB,GAAM,GAAO,EAAkB,EACzC,EAAE,SAAM;KACjB,CACD,QAAQ,MAAS,EAAK,KAAK,SAAS,EAAE;AAC3C,KAAU,KAAK;IACX,MAAM;IACN;IACA;IACA,WAAW,EAAiB;IAC5B;IACH,CAAC;;AAKV,SADA,EAAI,KAAO,GACJ;IACR,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scatterplot/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,KAAK,SAAS,EAA6B,MAAM,cAAc,CAAC;AAEzE,OAAO,EAUH,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAC3B,MAAM,UAAU,CAAC;AAIlB,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA6B3D,qBAAa,gBAAiB,SAAQ,aAAa;IAC/C,QAAQ,EAAE,uBAAuB,CAAC;IAClC,aAAa,EAAE,aAAa,CAAC;IAE7B,mBAAmB,EAAE,CAAC,CAAC,EAAC,OAAO,KAAK,IAAI,CAAmB;IAC3D,cAAc,EAAE;QACZ,YAAY,EAAE;YAAC,CAAC,EAAE,OAAO,CAAC;YAAC,CAAC,EAAE,OAAO,CAAA;SAAC,CAAC;QACvC,YAAY,EAAE,WAAW,CAAC;QAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;QAC9B,YAAY,EAAE,qBAAqB,CAAC;QACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACnD,iBAAiB,EAAE,gBAAgB,CAAC;QACpC,iBAAiB,EAAE,gBAAgB,CAAC;KACvC,GAAG,IAAI,CAAQ;gBAEJ,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,aAAa,CAAC,EAAC,wBAAwB;IAUnG,KAAK,CAAC,IAAI,EAAE,WAAW;IAiBvB,OAAO;IAIP,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB;IA4BpE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAIhD,MAAM,IAAI,MAAM;IAKhB,mCAAmC,CAAC,YAAY,EAAE,uBAAuB,EAAE,QAAQ,EAAE,uBAAuB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scatterplot/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,KAAK,SAAS,EAA6B,MAAM,cAAc,CAAC;AAEzE,OAAO,EAUH,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAC3B,MAAM,UAAU,CAAC;AAIlB,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA6B3D,qBAAa,gBAAiB,SAAQ,aAAa;IAC/C,QAAQ,EAAE,uBAAuB,CAAC;IAClC,aAAa,EAAE,aAAa,CAAC;IAE7B,mBAAmB,EAAE,CAAC,CAAC,EAAC,OAAO,KAAK,IAAI,CAAmB;IAC3D,cAAc,EAAE;QACZ,YAAY,EAAE;YAAC,CAAC,EAAE,OAAO,CAAC;YAAC,CAAC,EAAE,OAAO,CAAA;SAAC,CAAC;QACvC,YAAY,EAAE,WAAW,CAAC;QAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;QAC9B,YAAY,EAAE,qBAAqB,CAAC;QACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACnD,iBAAiB,EAAE,gBAAgB,CAAC;QACpC,iBAAiB,EAAE,gBAAgB,CAAC;KACvC,GAAG,IAAI,CAAQ;gBAEJ,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB,EAAE,aAAa,CAAC,EAAC,wBAAwB;IAUnG,KAAK,CAAC,IAAI,EAAE,WAAW;IAiBvB,OAAO;IAIP,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,mBAAmB;IA4BpE,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAIhD,MAAM,IAAI,MAAM;IAKhB,mCAAmC,CAAC,YAAY,EAAE,uBAAuB,EAAE,QAAQ,EAAE,uBAAuB;IA8B5G,+BAA+B,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS;IAUpE,WAAW;IA8DX,gBAAgB;IA0FhB,YAAY;CA8Bf"}
|
|
@@ -6,10 +6,10 @@ import { getFacetStringKey as i } from "../discrete/utils/getFacetStringKey.js";
|
|
|
6
6
|
import { arraysAreDifferent as a } from "../utils/arraysAreDifferent.js";
|
|
7
7
|
import { getFacetLabels as o } from "../discrete/utils/getFacetLabels.js";
|
|
8
8
|
import { getKeysCombinations as s } from "../utils/getKeysCombination.js";
|
|
9
|
-
import c from "./
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
9
|
+
import { getRegressionData as c } from "./linearRegression.js";
|
|
10
|
+
import l from "./ChartRenderer.js";
|
|
11
|
+
import { getDots as u } from "./dots.js";
|
|
12
|
+
import { getLayersData as d } from "./getLayersData.js";
|
|
13
13
|
import { ScatterplotSettingsImpl as f } from "./ScatterplotSettingsImpl.js";
|
|
14
14
|
import { addPalettesToAesMapping as p, createLegendInfo as m } from "./utils/createLegendInfo.js";
|
|
15
15
|
import { intersection as h } from "lodash";
|
|
@@ -43,7 +43,7 @@ var b = class extends e {
|
|
|
43
43
|
onTooltipHintSwitch = () => void 0;
|
|
44
44
|
calculatedData = null;
|
|
45
45
|
constructor(e, t, n) {
|
|
46
|
-
super(e, t), this.chartRenderer = new
|
|
46
|
+
super(e, t), this.chartRenderer = new l(), this.settings = new f(t), n && (this.onTooltipHintSwitch = n.onTooltipHintSwitch);
|
|
47
47
|
}
|
|
48
48
|
mount(e) {
|
|
49
49
|
try {
|
|
@@ -70,46 +70,58 @@ var b = class extends e {
|
|
|
70
70
|
return this._updateChart(), g(this.chartRenderer.component);
|
|
71
71
|
}
|
|
72
72
|
_needUpdateCalculatedDataBySettings(e, t) {
|
|
73
|
-
|
|
73
|
+
let n = e.additionalCurves?.curves ?? [], r = t.additionalCurves?.curves ?? [];
|
|
74
|
+
return a(e.facetSettings?.order ?? [], t.facetSettings?.order ?? []) || e.facetBy.some((e, n) => e.value !== t.facetBy[n]?.value) || e.grouping.length !== t.grouping.length || a(e.grouping.map((e) => e.columnName.value), t.grouping.map((e) => e.columnName.value)) || a(e.grouping.map((e) => e.columnName.nullValueLabel), t.grouping.map((e) => e.columnName.nullValueLabel)) || e.grouping.some((e, n) => a(e.order, t.grouping?.[n].order)) || a(e.facetSettings?.order ?? [], t.facetSettings?.order ?? []) || a(e.chartSettings.xAxis.keys, t.chartSettings.xAxis.keys) || a(e.chartSettings.yAxis.keys, t.chartSettings.yAxis.keys) || (e.label?.value || t.label?.value) && e.label?.value !== t.label?.value || e.layers.length !== t.layers.length || e.layers.some((e, n) => e.type !== t.layers[n].type) || !!e.trend != !!t.trend || n.length !== r.length || a(n.map((e) => e.columnName.value), r.map((e) => e.columnName.value)) || n.some((e, t) => !!e.trend != !!r[t]?.trend);
|
|
74
75
|
}
|
|
75
76
|
_needUpdateCalculatedDataByData(e, t) {
|
|
76
77
|
let n = Object.keys(e.data), r = Object.keys(t.data);
|
|
77
78
|
return e.id !== t.id || n.length !== r.length || n.some((n) => e.data[n].length !== t.data[n]?.length);
|
|
78
79
|
}
|
|
79
80
|
_updateData() {
|
|
80
|
-
let { x: e, y: t, facetBy: n, grouping: a, dotSize:
|
|
81
|
-
if (
|
|
82
|
-
let e =
|
|
83
|
-
|
|
81
|
+
let { x: e, y: t, facetBy: n, grouping: a, dotSize: l, dotShape: f, trend: p, layers: g, label: _, highlight: b, chartSettings: x, facetSettings: S, additionalCurves: C } = this.settings, w = s(n.map((e) => y(this.data, e)));
|
|
82
|
+
if (w.length === 0 && (w = [[r]]), S?.order?.length) {
|
|
83
|
+
let e = w.map(i);
|
|
84
|
+
w = h(S.order, e).map((e) => w.find((t) => i(t) === e)).filter((e) => e != null);
|
|
84
85
|
}
|
|
85
|
-
let
|
|
86
|
-
this.data.setGrouping(
|
|
87
|
-
let
|
|
86
|
+
let T = n.length ? n.map((e) => e.value) : [null], E = n.length ? T.map((e, t) => [...new Set(w.map((e) => e[t]))]) : [void 0];
|
|
87
|
+
this.data.setGrouping(T, E);
|
|
88
|
+
let D = {
|
|
88
89
|
x: this.data.getColumn(e.value).every((e) => e === null || !(Number(e) < 0)),
|
|
89
90
|
y: this.data.getColumn(t.value).every((e) => e === null || !(Number(e) < 0))
|
|
90
|
-
},
|
|
91
|
+
}, O = a.map((e) => e.columnName), k = u(this.data, w, e, t, _, b, a, x.xAxis, x.yAxis, g.find((e) => e.type === "dots")), A = w.map(i), j = a.map(({ columnName: e }) => this.data.getColumnCategories(e.value, !1)).filter((e) => e.length > 0), M = j.length ? s(j) : [["null"]], N = c(this.data, k, A, M, O, p), P = v(this.data, x.xAxis, e), F = v(this.data, x.yAxis, t), I = [
|
|
91
92
|
...a,
|
|
92
|
-
...
|
|
93
|
+
...l,
|
|
93
94
|
...f
|
|
94
|
-
],
|
|
95
|
+
], L = m(this.data, I, g, C), R = d(this.data, g, A, k, M, O, x.xAxis, P, C);
|
|
95
96
|
this.calculatedData = {
|
|
96
|
-
onlyPositive:
|
|
97
|
-
dotsByFacets:
|
|
98
|
-
facetKeys:
|
|
99
|
-
facetLabels: o(this.data, n,
|
|
100
|
-
trendsData:
|
|
101
|
-
legendLabels:
|
|
102
|
-
layersData:
|
|
103
|
-
discreteAxisDataX:
|
|
104
|
-
discreteAxisDataY:
|
|
97
|
+
onlyPositive: D,
|
|
98
|
+
dotsByFacets: k,
|
|
99
|
+
facetKeys: A,
|
|
100
|
+
facetLabels: o(this.data, n, A, w),
|
|
101
|
+
trendsData: N,
|
|
102
|
+
legendLabels: L,
|
|
103
|
+
layersData: R,
|
|
104
|
+
discreteAxisDataX: P,
|
|
105
|
+
discreteAxisDataY: F
|
|
105
106
|
};
|
|
106
107
|
}
|
|
107
108
|
_updateAesInData() {
|
|
108
109
|
let e = this.calculatedData;
|
|
109
110
|
if (!e) return;
|
|
110
|
-
let { grouping: t, trend: n, layers: r, dotSize: i, dotShape: a } = this.settings, { facetKeys:
|
|
111
|
-
|
|
112
|
-
for (let n = 0; n < r.length; n++)
|
|
111
|
+
let { grouping: t, trend: n, layers: r, dotSize: i, dotShape: a, additionalCurves: o } = this.settings, { facetKeys: s, trendsData: c } = e;
|
|
112
|
+
s.forEach((t) => {
|
|
113
|
+
for (let n = 0; n < r.length; n++) {
|
|
114
|
+
let i = e.layersData[t][n];
|
|
115
|
+
i && i.type !== "additional-curve" && (i.info = r[n]);
|
|
116
|
+
}
|
|
117
|
+
if (o) for (let n = 0; n < o.curves.length; n++) {
|
|
118
|
+
let i = r.length + n, a = e.layersData[t][i];
|
|
119
|
+
a && a.type === "additional-curve" && (e.layersData[t][i] = {
|
|
120
|
+
...a,
|
|
121
|
+
entry: o.curves[n],
|
|
122
|
+
smoothing: o.smoothing
|
|
123
|
+
});
|
|
124
|
+
}
|
|
113
125
|
}), [
|
|
114
126
|
...t,
|
|
115
127
|
...i,
|
|
@@ -120,21 +132,27 @@ var b = class extends e {
|
|
|
120
132
|
e.aes && Object.entries(e.aes).forEach(([e, n]) => {
|
|
121
133
|
_(n) && n.value === t.value && (i.add(e), n.palette && (a[e] = n.palette));
|
|
122
134
|
});
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
|
|
135
|
+
});
|
|
136
|
+
for (let e of o?.curves ?? []) {
|
|
137
|
+
_(e.lineColor) && e.lineColor.value === t.value && (i.add("lineColor"), e.lineColor.palette && (a.lineColor = e.lineColor.palette));
|
|
138
|
+
let n = e.trend?.color;
|
|
139
|
+
n && _(n) && n.value === t.value && (i.add("lineColor"), n.palette && (a.lineColor = n.palette));
|
|
140
|
+
}
|
|
141
|
+
e.legendLabels[t.value].usedAes = [...i], e.legendLabels[t.value].aesMap = p(t, a, n);
|
|
142
|
+
}), c && n && Object.keys(c).forEach((e) => {
|
|
143
|
+
c[e].forEach((e) => {
|
|
126
144
|
e.color = n.color, e.bounded = n.bounded;
|
|
127
145
|
});
|
|
128
146
|
});
|
|
129
147
|
}
|
|
130
148
|
_updateChart() {
|
|
131
149
|
if (!this.calculatedData) return;
|
|
132
|
-
let { facetLabels: e } = this.calculatedData, { id: t, chartSettings: n, facetSettings: r, grouping: i, dotSize: a, dotShape: o, keyColumn: s, layers: c, trend: l } = this.settings;
|
|
150
|
+
let { facetLabels: e } = this.calculatedData, { id: t, chartSettings: n, facetSettings: r, grouping: i, dotSize: a, dotShape: o, keyColumn: s, layers: c, trend: l, additionalCurves: u, y: d } = this.settings;
|
|
133
151
|
this.chartRenderer.render(this.data, t, n, r, this.calculatedData.facetKeys, this.calculatedData.facetKeys.map((t) => e[t]), this.calculatedData.dotsByFacets, this.calculatedData.trendsData, s, this.calculatedData.onlyPositive, this.calculatedData.legendLabels, this.calculatedData.layersData, [
|
|
134
152
|
...i.map((e) => e.columnName),
|
|
135
153
|
...a.map((e) => e.columnName),
|
|
136
154
|
...o.map((e) => e.columnName)
|
|
137
|
-
], c, l, this.calculatedData.discreteAxisDataX, this.calculatedData.discreteAxisDataY, this.onTooltipHintSwitch);
|
|
155
|
+
], c, l, this.calculatedData.discreteAxisDataX, this.calculatedData.discreteAxisDataY, this.onTooltipHintSwitch, u, d);
|
|
138
156
|
}
|
|
139
157
|
};
|
|
140
158
|
export { b as ChartScatterplot };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/scatterplot/index.ts"],"sourcesContent":["import { renderToString } from 'react-dom/server.browser';\nimport { AbstractChart } from '../AbstractChart';\nimport { type DataFrame, type GroupKey, NO_GROUPED } from '../DataFrame';\nimport type { DataValue} from '../types';\nimport {\n type AesItem,\n type AxisSettings,\n type AxisSettingsDiscrete,\n type Category,\n type ColumnName,\n type ContinuousAesFromColumn,\n getUnknownErrorInfo,\n type InheritAesScatterplot,\n isErrorInfo,\n type ScatterplotEventHandlers,\n type ScatterplotLegendInfo,\n type ScatterplotSettings,\n} from '../types';\nimport { intersection } from 'lodash';\nimport { arraysAreDifferent } from '../utils/arraysAreDifferent';\nimport { getKeysCombinations } from '../utils/getKeysCombination';\nimport ChartRenderer from './ChartRenderer';\nimport type { GroupedDots } from './dots';\nimport { getDots } from './dots';\nimport type { ScatterplotLayerData } from './getLayersData';\nimport { getLayersData } from './getLayersData';\nimport type { TrendsData } from './linearRegression';\nimport { getRegressionData } from './linearRegression';\nimport { ScatterplotSettingsImpl } from './ScatterplotSettingsImpl';\nimport { addPalettesToAesMapping, createLegendInfo } from './utils/createLegendInfo';\nimport type { DiscreteAxisData } from './components/types';\nimport { getFacetLabels } from '../discrete/utils/getFacetLabels';\nimport { getFacetStringKey } from '../discrete/utils/getFacetStringKey';\n\nfunction isInheritMapping<T extends (string | number)>(value:T | InheritAesScatterplot | ContinuousAesFromColumn<T>):value is InheritAesScatterplot {\n return typeof value === 'object' && 'type' in value && value.type === 'grouping';\n}\n\nfunction getDiscreteAxisData(data: DataFrame, axis: AxisSettings, column: ColumnName): DiscreteAxisData {\n if (axis.scale === 'discrete') {\n const keys = axis.keys ? axis.keys : data.getColumnCategories(column.value, false);\n return {keys, labels: keys.reduce((res, v) => {\n const labelsMap = axis.labels ?? {};\n const labelValue = labelsMap[v] ?? (column.valueLabels ? data.getColumnValue(column.valueLabels, data.getColumnCategoryRowIndex(column.value, v as Category)) : v);\n res[v] = String(labelValue);\n if (v === 'null') {\n res[v] = column.nullValueLabel ?? 'NA';\n }\n return res;\n }, {} as Record<string, string>)};\n }\n return {keys: [], labels: {}};\n}\n\nfunction getGroupingKeys(data: DataFrame, column: ColumnName, order: DataValue[] | null = null) {\n const groupingColumn = column.value;\n const availableKeys = data.getColumnCategories(groupingColumn);\n return intersection(order ?? availableKeys, availableKeys).map(String);\n}\nexport class ChartScatterplot extends AbstractChart {\n settings: ScatterplotSettingsImpl;\n chartRenderer: ChartRenderer;\n\n onTooltipHintSwitch: (v:boolean) => void = () => undefined;\n calculatedData: {\n onlyPositive: {x: boolean; y: boolean};\n dotsByFacets: GroupedDots;\n facetKeys: string[];\n facetLabels: Record<string, string[]>;\n trendsData: TrendsData | null;\n legendLabels: ScatterplotLegendInfo;\n layersData: Record<string, ScatterplotLayerData[]>;\n discreteAxisDataX: DiscreteAxisData;\n discreteAxisDataY: DiscreteAxisData;\n } | null = null;\n\n constructor(data: DataFrame, settings: ScatterplotSettings, eventHandlers?:ScatterplotEventHandlers) {\n super(data, settings);\n\n this.chartRenderer = new ChartRenderer();\n this.settings = new ScatterplotSettingsImpl(settings);\n if (eventHandlers) {\n this.onTooltipHintSwitch = eventHandlers.onTooltipHintSwitch;\n }\n }\n\n mount(node: HTMLElement) {\n try {\n this.chartRenderer.init(node);\n this._updateData();\n this._updateChart();\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n unmount() {\n this.chartRenderer.clear();\n }\n\n updateSettingsAndData(data: DataFrame, settings: ScatterplotSettings) {\n try {\n const previousSettings = this.settings;\n const previousData = this.data;\n this.settings = new ScatterplotSettingsImpl(settings);\n this.data = data;\n if (\n this._needUpdateCalculatedDataBySettings(previousSettings, this.settings) ||\n this._needUpdateCalculatedDataByData(previousData, this.data)\n ) {\n this._updateData();\n } else {\n this._updateAesInData();\n }\n this._updateChart();\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n console.error(err);\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n updateChartState(_field: string, _value: unknown) {\n console.warn('no chart state for scatterplot');\n }\n\n export(): string {\n this._updateChart();\n return renderToString(this.chartRenderer.component);\n }\n\n _needUpdateCalculatedDataBySettings(prevSettings: ScatterplotSettingsImpl, settings: ScatterplotSettingsImpl) {\n return (\n arraysAreDifferent(prevSettings.facetSettings?.order ?? [], settings.facetSettings?.order ?? []) ||\n prevSettings.facetBy.some((el, idx) => el.value !== settings.facetBy[idx]?.value) ||\n prevSettings.grouping.length !== settings.grouping.length ||\n arraysAreDifferent(\n prevSettings.grouping.map(v => v.columnName.value),\n settings.grouping.map(v => v.columnName.value),\n ) ||\n arraysAreDifferent(\n prevSettings.grouping.map(v => v.columnName.nullValueLabel),\n settings.grouping.map(v => v.columnName.nullValueLabel),\n ) ||\n prevSettings.grouping.some((v, idx) => arraysAreDifferent(v.order, settings.grouping?.[idx].order)) ||\n arraysAreDifferent(prevSettings.facetSettings?.order ?? [], settings.facetSettings?.order ?? []) ||\n arraysAreDifferent((prevSettings.chartSettings.xAxis as AxisSettingsDiscrete).keys, (settings.chartSettings.xAxis as AxisSettingsDiscrete).keys) ||\n arraysAreDifferent((prevSettings.chartSettings.yAxis as AxisSettingsDiscrete).keys, (settings.chartSettings.yAxis as AxisSettingsDiscrete).keys) ||\n (prevSettings.label?.value || settings.label?.value) && prevSettings.label?.value !== settings.label?.value ||\n prevSettings.layers.length !== settings.layers.length ||\n prevSettings.layers.some((l, idx) => l.type !== settings.layers[idx].type) ||\n Boolean(prevSettings.trend) !== Boolean(settings.trend)\n );\n }\n\n _needUpdateCalculatedDataByData(prevData: DataFrame, data: DataFrame) {\n const prevKeys = Object.keys(prevData.data);\n const keys = Object.keys(data.data);\n return (\n prevData.id !== data.id ||\n prevKeys.length !== keys.length ||\n prevKeys.some(key => prevData.data[key].length !== data.data[key]?.length)\n );\n }\n\n _updateData() {\n const {x, y, facetBy, grouping, dotSize, dotShape, trend, layers, label, highlight, chartSettings, facetSettings} = this.settings;\n let facetKeyLists: (GroupKey)[][] = getKeysCombinations(\n facetBy.map(column => getGroupingKeys(this.data, column))\n );\n if (facetKeyLists.length === 0) {\n facetKeyLists = [[NO_GROUPED]];\n }\n if (facetSettings?.order?.length) {\n const allFacetKeys = facetKeyLists.map(getFacetStringKey);\n const keyOrder = intersection(facetSettings.order, allFacetKeys);\n facetKeyLists = keyOrder\n .map((keyStr) => facetKeyLists.find((fkl) => getFacetStringKey(fkl) === keyStr))\n .filter((x): x is GroupKey[] => x != null);\n }\n const facetGroupingValues = facetBy.length ? facetBy.map(column => column.value) : [null];\n const facetGroupingKeys = facetBy.length\n ? facetGroupingValues.map((_, idx) => [...new Set(facetKeyLists.map(fkl => fkl[idx]))])\n : [undefined];\n this.data.setGrouping(facetGroupingValues, facetGroupingKeys);\n const onlyPositive = {\n x: this.data.getColumn(x.value).every(v => {\n return v === null || !(Number(v) < 0);\n }),\n y: this.data.getColumn(y.value).every(v => {\n return v === null || !(Number(v) < 0);\n }),\n };\n\n const groupingColumns = grouping.map(v => v.columnName);\n\n const dotsByFacets = getDots(this.data, facetKeyLists, x, y, label, highlight, grouping, chartSettings.xAxis, chartSettings.yAxis, layers.find(l => l.type === 'dots'));\n const facetKeys = facetKeyLists.map(getFacetStringKey);\n\n // not for data groupig, for curves, trends, colors\n const categoryGroupingKeysLists = grouping.map(({columnName}) => this.data.getColumnCategories(columnName.value, false)).filter(v => v.length > 0);\n const categoryGroupingCombinations = categoryGroupingKeysLists.length\n ? getKeysCombinations(categoryGroupingKeysLists)\n : [['null']];\n const trendsData = getRegressionData(this.data, dotsByFacets, facetKeys, categoryGroupingCombinations, groupingColumns, trend);\n\n const discreteAxisDataX = getDiscreteAxisData(this.data, chartSettings.xAxis, x);\n const discreteAxisDataY = getDiscreteAxisData(this.data, chartSettings.yAxis, y);\n\n const allAesMappings = [...grouping, ...dotSize, ...dotShape];\n const legendLabels = createLegendInfo(this.data, allAesMappings, layers);\n const layersData = getLayersData(this.data, layers, facetKeys, dotsByFacets, categoryGroupingCombinations, groupingColumns, chartSettings.xAxis, discreteAxisDataX);\n const facetLabels = getFacetLabels(this.data, facetBy, facetKeys, facetKeyLists);\n\n this.calculatedData = {\n onlyPositive,\n dotsByFacets,\n facetKeys,\n facetLabels,\n trendsData,\n legendLabels,\n layersData,\n discreteAxisDataX,\n discreteAxisDataY\n };\n }\n\n _updateAesInData() {\n const calculated = this.calculatedData;\n if (!calculated) {\n return;\n }\n const {grouping, trend, layers, dotSize, dotShape} = this.settings;\n const {facetKeys, trendsData} = calculated;\n\n facetKeys.forEach(facetKey => {\n for (let i = 0; i < layers.length; i++) {\n calculated.layersData[facetKey][i].info = layers[i];\n }\n });\n\n const allAesMappings = [...grouping, ...dotSize, ...dotShape];\n\n allAesMappings.forEach(({columnName, inheritedAes}) => {\n const usedAes = new Set<keyof AesItem>();\n const usedAesFromPalettes: Partial<Record<keyof AesItem, string[]>> = {}; // if there is palette in mapping then\n layers.forEach(layer => {\n if (layer.aes) {\n Object.entries(layer.aes).forEach(([key, value]) => {\n if (isInheritMapping(value) && value.value === columnName.value) {\n usedAes.add(key as keyof AesItem);\n if (value.palette) {\n usedAesFromPalettes[key as keyof AesItem] = value.palette;\n }\n }\n });\n }\n });\n calculated.legendLabels[columnName.value].usedAes = [...usedAes];\n calculated.legendLabels[columnName.value].aesMap = addPalettesToAesMapping(\n columnName,\n usedAesFromPalettes,\n inheritedAes\n );\n });\n if (trendsData && trend) {\n Object.keys(trendsData).forEach((key) => {\n trendsData[key].forEach(trendInfo => {\n trendInfo.color = trend.color;\n trendInfo.bounded = trend.bounded;\n });\n });\n }\n }\n\n _updateChart() {\n if (!this.calculatedData) {\n return;\n }\n const {facetLabels} = this.calculatedData;\n const {id, chartSettings, facetSettings, grouping, dotSize, dotShape, keyColumn, layers, trend} = this.settings;\n\n this.chartRenderer.render(\n this.data,\n id,\n chartSettings,\n facetSettings,\n this.calculatedData.facetKeys,\n this.calculatedData.facetKeys.map(v => facetLabels[v]), //for titles, if facet by more than 1 column\n this.calculatedData.dotsByFacets,\n this.calculatedData.trendsData,\n keyColumn,\n this.calculatedData.onlyPositive,\n this.calculatedData.legendLabels,\n this.calculatedData.layersData,\n [...grouping.map(v => v.columnName), ...dotSize.map(v => v.columnName), ...dotShape.map(v => v.columnName)],\n layers,\n trend,\n this.calculatedData.discreteAxisDataX,\n this.calculatedData.discreteAxisDataY,\n this.onTooltipHintSwitch\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/scatterplot/index.ts"],"sourcesContent":["import { renderToString } from 'react-dom/server.browser';\nimport { AbstractChart } from '../AbstractChart';\nimport { type DataFrame, type GroupKey, NO_GROUPED } from '../DataFrame';\nimport type { DataValue} from '../types';\nimport {\n type AesItem,\n type AxisSettings,\n type AxisSettingsDiscrete,\n type Category,\n type ColumnName,\n type ContinuousAesFromColumn,\n getUnknownErrorInfo,\n type InheritAesScatterplot,\n isErrorInfo,\n type ScatterplotEventHandlers,\n type ScatterplotLegendInfo,\n type ScatterplotSettings,\n} from '../types';\nimport { intersection } from 'lodash';\nimport { arraysAreDifferent } from '../utils/arraysAreDifferent';\nimport { getKeysCombinations } from '../utils/getKeysCombination';\nimport ChartRenderer from './ChartRenderer';\nimport type { GroupedDots } from './dots';\nimport { getDots } from './dots';\nimport type { ScatterplotLayerData } from './getLayersData';\nimport { getLayersData } from './getLayersData';\nimport type { TrendsData } from './linearRegression';\nimport { getRegressionData } from './linearRegression';\nimport { ScatterplotSettingsImpl } from './ScatterplotSettingsImpl';\nimport { addPalettesToAesMapping, createLegendInfo } from './utils/createLegendInfo';\nimport type { DiscreteAxisData } from './components/types';\nimport { getFacetLabels } from '../discrete/utils/getFacetLabels';\nimport { getFacetStringKey } from '../discrete/utils/getFacetStringKey';\n\nfunction isInheritMapping<T extends (string | number)>(value:T | InheritAesScatterplot | ContinuousAesFromColumn<T>):value is InheritAesScatterplot {\n return typeof value === 'object' && 'type' in value && value.type === 'grouping';\n}\n\nfunction getDiscreteAxisData(data: DataFrame, axis: AxisSettings, column: ColumnName): DiscreteAxisData {\n if (axis.scale === 'discrete') {\n const keys = axis.keys ? axis.keys : data.getColumnCategories(column.value, false);\n return {keys, labels: keys.reduce((res, v) => {\n const labelsMap = axis.labels ?? {};\n const labelValue = labelsMap[v] ?? (column.valueLabels ? data.getColumnValue(column.valueLabels, data.getColumnCategoryRowIndex(column.value, v as Category)) : v);\n res[v] = String(labelValue);\n if (v === 'null') {\n res[v] = column.nullValueLabel ?? 'NA';\n }\n return res;\n }, {} as Record<string, string>)};\n }\n return {keys: [], labels: {}};\n}\n\nfunction getGroupingKeys(data: DataFrame, column: ColumnName, order: DataValue[] | null = null) {\n const groupingColumn = column.value;\n const availableKeys = data.getColumnCategories(groupingColumn);\n return intersection(order ?? availableKeys, availableKeys).map(String);\n}\nexport class ChartScatterplot extends AbstractChart {\n settings: ScatterplotSettingsImpl;\n chartRenderer: ChartRenderer;\n\n onTooltipHintSwitch: (v:boolean) => void = () => undefined;\n calculatedData: {\n onlyPositive: {x: boolean; y: boolean};\n dotsByFacets: GroupedDots;\n facetKeys: string[];\n facetLabels: Record<string, string[]>;\n trendsData: TrendsData | null;\n legendLabels: ScatterplotLegendInfo;\n layersData: Record<string, ScatterplotLayerData[]>;\n discreteAxisDataX: DiscreteAxisData;\n discreteAxisDataY: DiscreteAxisData;\n } | null = null;\n\n constructor(data: DataFrame, settings: ScatterplotSettings, eventHandlers?:ScatterplotEventHandlers) {\n super(data, settings);\n\n this.chartRenderer = new ChartRenderer();\n this.settings = new ScatterplotSettingsImpl(settings);\n if (eventHandlers) {\n this.onTooltipHintSwitch = eventHandlers.onTooltipHintSwitch;\n }\n }\n\n mount(node: HTMLElement) {\n try {\n this.chartRenderer.init(node);\n this._updateData();\n this._updateChart();\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n unmount() {\n this.chartRenderer.clear();\n }\n\n updateSettingsAndData(data: DataFrame, settings: ScatterplotSettings) {\n try {\n const previousSettings = this.settings;\n const previousData = this.data;\n this.settings = new ScatterplotSettingsImpl(settings);\n this.data = data;\n if (\n this._needUpdateCalculatedDataBySettings(previousSettings, this.settings) ||\n this._needUpdateCalculatedDataByData(previousData, this.data)\n ) {\n this._updateData();\n } else {\n this._updateAesInData();\n }\n this._updateChart();\n this.hasError = false;\n this.errorInfo = null;\n } catch (err) {\n this.hasError = true;\n console.error(err);\n if (err instanceof Error) {\n this.errorInfo = isErrorInfo(err.cause) ? err.cause : getUnknownErrorInfo(err);\n this.chartRenderer.renderError(err.message as string);\n console.error(err);\n }\n }\n }\n\n updateChartState(_field: string, _value: unknown) {\n console.warn('no chart state for scatterplot');\n }\n\n export(): string {\n this._updateChart();\n return renderToString(this.chartRenderer.component);\n }\n\n _needUpdateCalculatedDataBySettings(prevSettings: ScatterplotSettingsImpl, settings: ScatterplotSettingsImpl) {\n const prevCurves = prevSettings.additionalCurves?.curves ?? [];\n const curves = settings.additionalCurves?.curves ?? [];\n return (\n arraysAreDifferent(prevSettings.facetSettings?.order ?? [], settings.facetSettings?.order ?? []) ||\n prevSettings.facetBy.some((el, idx) => el.value !== settings.facetBy[idx]?.value) ||\n prevSettings.grouping.length !== settings.grouping.length ||\n arraysAreDifferent(\n prevSettings.grouping.map(v => v.columnName.value),\n settings.grouping.map(v => v.columnName.value),\n ) ||\n arraysAreDifferent(\n prevSettings.grouping.map(v => v.columnName.nullValueLabel),\n settings.grouping.map(v => v.columnName.nullValueLabel),\n ) ||\n prevSettings.grouping.some((v, idx) => arraysAreDifferent(v.order, settings.grouping?.[idx].order)) ||\n arraysAreDifferent(prevSettings.facetSettings?.order ?? [], settings.facetSettings?.order ?? []) ||\n arraysAreDifferent((prevSettings.chartSettings.xAxis as AxisSettingsDiscrete).keys, (settings.chartSettings.xAxis as AxisSettingsDiscrete).keys) ||\n arraysAreDifferent((prevSettings.chartSettings.yAxis as AxisSettingsDiscrete).keys, (settings.chartSettings.yAxis as AxisSettingsDiscrete).keys) ||\n (prevSettings.label?.value || settings.label?.value) && prevSettings.label?.value !== settings.label?.value ||\n prevSettings.layers.length !== settings.layers.length ||\n prevSettings.layers.some((l, idx) => l.type !== settings.layers[idx].type) ||\n Boolean(prevSettings.trend) !== Boolean(settings.trend) ||\n // Curve count, columnName, or per-entry trend presence → full recalc. Aesthetic-only changes fall through to _updateAesInData.\n prevCurves.length !== curves.length ||\n arraysAreDifferent(prevCurves.map(c => c.columnName.value), curves.map(c => c.columnName.value)) ||\n prevCurves.some((c, idx) => Boolean(c.trend) !== Boolean(curves[idx]?.trend))\n );\n }\n\n _needUpdateCalculatedDataByData(prevData: DataFrame, data: DataFrame) {\n const prevKeys = Object.keys(prevData.data);\n const keys = Object.keys(data.data);\n return (\n prevData.id !== data.id ||\n prevKeys.length !== keys.length ||\n prevKeys.some(key => prevData.data[key].length !== data.data[key]?.length)\n );\n }\n\n _updateData() {\n const {x, y, facetBy, grouping, dotSize, dotShape, trend, layers, label, highlight, chartSettings, facetSettings, additionalCurves} = this.settings;\n let facetKeyLists: (GroupKey)[][] = getKeysCombinations(\n facetBy.map(column => getGroupingKeys(this.data, column))\n );\n if (facetKeyLists.length === 0) {\n facetKeyLists = [[NO_GROUPED]];\n }\n if (facetSettings?.order?.length) {\n const allFacetKeys = facetKeyLists.map(getFacetStringKey);\n const keyOrder = intersection(facetSettings.order, allFacetKeys);\n facetKeyLists = keyOrder\n .map((keyStr) => facetKeyLists.find((fkl) => getFacetStringKey(fkl) === keyStr))\n .filter((x): x is GroupKey[] => x != null);\n }\n const facetGroupingValues = facetBy.length ? facetBy.map(column => column.value) : [null];\n const facetGroupingKeys = facetBy.length\n ? facetGroupingValues.map((_, idx) => [...new Set(facetKeyLists.map(fkl => fkl[idx]))])\n : [undefined];\n this.data.setGrouping(facetGroupingValues, facetGroupingKeys);\n const onlyPositive = {\n x: this.data.getColumn(x.value).every(v => {\n return v === null || !(Number(v) < 0);\n }),\n y: this.data.getColumn(y.value).every(v => {\n return v === null || !(Number(v) < 0);\n }),\n };\n\n const groupingColumns = grouping.map(v => v.columnName);\n\n const dotsByFacets = getDots(this.data, facetKeyLists, x, y, label, highlight, grouping, chartSettings.xAxis, chartSettings.yAxis, layers.find(l => l.type === 'dots'));\n const facetKeys = facetKeyLists.map(getFacetStringKey);\n\n // not for data groupig, for curves, trends, colors\n const categoryGroupingKeysLists = grouping.map(({columnName}) => this.data.getColumnCategories(columnName.value, false)).filter(v => v.length > 0);\n const categoryGroupingCombinations = categoryGroupingKeysLists.length\n ? getKeysCombinations(categoryGroupingKeysLists)\n : [['null']];\n const trendsData = getRegressionData(this.data, dotsByFacets, facetKeys, categoryGroupingCombinations, groupingColumns, trend);\n\n const discreteAxisDataX = getDiscreteAxisData(this.data, chartSettings.xAxis, x);\n const discreteAxisDataY = getDiscreteAxisData(this.data, chartSettings.yAxis, y);\n\n const allAesMappings = [...grouping, ...dotSize, ...dotShape];\n const legendLabels = createLegendInfo(this.data, allAesMappings, layers, additionalCurves);\n const layersData = getLayersData(this.data, layers, facetKeys, dotsByFacets, categoryGroupingCombinations, groupingColumns, chartSettings.xAxis, discreteAxisDataX, additionalCurves);\n const facetLabels = getFacetLabels(this.data, facetBy, facetKeys, facetKeyLists);\n\n this.calculatedData = {\n onlyPositive,\n dotsByFacets,\n facetKeys,\n facetLabels,\n trendsData,\n legendLabels,\n layersData,\n discreteAxisDataX,\n discreteAxisDataY\n };\n }\n\n _updateAesInData() {\n const calculated = this.calculatedData;\n if (!calculated) {\n return;\n }\n const {grouping, trend, layers, dotSize, dotShape, additionalCurves} = this.settings;\n const {facetKeys, trendsData} = calculated;\n\n facetKeys.forEach(facetKey => {\n for (let i = 0; i < layers.length; i++) {\n const existingLayer = calculated.layersData[facetKey][i];\n // Primary layers live at indices 0..layers.length-1. additional-curve entries are appended\n // after (getLayersData preserves this order), refreshed separately below.\n if (existingLayer && existingLayer.type !== 'additional-curve') {\n existingLayer.info = layers[i];\n }\n }\n // Aesthetic-only refresh for additional-curve entries: the count + columnName + trend-presence\n // diff would have triggered _updateData, so here we only need to re-point entry + smoothing\n // at the new settings so lineShape/lineWidth/lineColor/opacity/showDots + shared smoothing\n // flow through to the renderer without a full recompute.\n //\n // Each layer entry must be REPLACED (not mutated) — ChartAdditionalCurveLayer is React.memo'd\n // on (layer, scales) so a stable reference would cause the child to bail out of re-rendering.\n if (additionalCurves) {\n for (let i = 0; i < additionalCurves.curves.length; i++) {\n const idx = layers.length + i;\n const existing = calculated.layersData[facetKey][idx];\n if (existing && existing.type === 'additional-curve') {\n calculated.layersData[facetKey][idx] = {\n ...existing,\n entry: additionalCurves.curves[i],\n smoothing: additionalCurves.smoothing,\n };\n }\n }\n }\n });\n\n const allAesMappings = [...grouping, ...dotSize, ...dotShape];\n\n allAesMappings.forEach(({columnName, inheritedAes}) => {\n const usedAes = new Set<keyof AesItem>();\n const usedAesFromPalettes: Partial<Record<keyof AesItem, string[]>> = {}; // if there is palette in mapping then\n layers.forEach(layer => {\n if (layer.aes) {\n Object.entries(layer.aes).forEach(([key, value]) => {\n if (isInheritMapping(value) && value.value === columnName.value) {\n usedAes.add(key as keyof AesItem);\n if (value.palette) {\n usedAesFromPalettes[key as keyof AesItem] = value.palette;\n }\n }\n });\n }\n });\n // Keep additional curves in sync with the createLegendInfo init path so aes-only refreshes\n // pick up new grouping-inherited lineColor / trend color without a full _updateData.\n for (const entry of additionalCurves?.curves ?? []) {\n if (isInheritMapping(entry.lineColor) && entry.lineColor.value === columnName.value) {\n usedAes.add('lineColor');\n if (entry.lineColor.palette) {\n usedAesFromPalettes['lineColor'] = entry.lineColor.palette;\n }\n }\n const trendColor = entry.trend?.color;\n if (trendColor && isInheritMapping(trendColor) && trendColor.value === columnName.value) {\n usedAes.add('lineColor');\n if (trendColor.palette) {\n usedAesFromPalettes['lineColor'] = trendColor.palette;\n }\n }\n }\n calculated.legendLabels[columnName.value].usedAes = [...usedAes];\n calculated.legendLabels[columnName.value].aesMap = addPalettesToAesMapping(\n columnName,\n usedAesFromPalettes,\n inheritedAes\n );\n });\n if (trendsData && trend) {\n Object.keys(trendsData).forEach((key) => {\n trendsData[key].forEach(trendInfo => {\n trendInfo.color = trend.color;\n trendInfo.bounded = trend.bounded;\n });\n });\n }\n }\n\n _updateChart() {\n if (!this.calculatedData) {\n return;\n }\n const {facetLabels} = this.calculatedData;\n const {id, chartSettings, facetSettings, grouping, dotSize, dotShape, keyColumn, layers, trend, additionalCurves, y} = this.settings;\n\n this.chartRenderer.render(\n this.data,\n id,\n chartSettings,\n facetSettings,\n this.calculatedData.facetKeys,\n this.calculatedData.facetKeys.map(v => facetLabels[v]), //for titles, if facet by more than 1 column\n this.calculatedData.dotsByFacets,\n this.calculatedData.trendsData,\n keyColumn,\n this.calculatedData.onlyPositive,\n this.calculatedData.legendLabels,\n this.calculatedData.layersData,\n [...grouping.map(v => v.columnName), ...dotSize.map(v => v.columnName), ...dotShape.map(v => v.columnName)],\n layers,\n trend,\n this.calculatedData.discreteAxisDataX,\n this.calculatedData.discreteAxisDataY,\n this.onTooltipHintSwitch,\n additionalCurves,\n y,\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAesGetter.d.ts","sourceRoot":"","sources":["../../../src/scatterplot/utils/createAesGetter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EACR,OAAO,EACP,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,UAAU,EACV,qBAAqB,EACxB,MAAM,aAAa,CAAC;AAQrB,wBAAgB,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,EACtF,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,SAAS,GAAG,uBAAuB,CAAC,SAAS,CAAC,GAAG,qBAAqB,EAC/E,KAAK,EAAE,MAAM,OAAO,cAOU,MAAM,KAEO,SAAS,
|
|
1
|
+
{"version":3,"file":"createAesGetter.d.ts","sourceRoot":"","sources":["../../../src/scatterplot/utils/createAesGetter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EACR,OAAO,EACP,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,UAAU,EACV,qBAAqB,EACxB,MAAM,aAAa,CAAC;AAQrB,wBAAgB,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,EACtF,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,SAAS,GAAG,uBAAuB,CAAC,SAAS,CAAC,GAAG,qBAAqB,EAC/E,KAAK,EAAE,MAAM,OAAO,cAOU,MAAM,KAEO,SAAS,CA6BvD"}
|
|
@@ -22,9 +22,11 @@ function o(o, s, c, l) {
|
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
24
|
if (a(c)) {
|
|
25
|
-
let t = c.value, n = s[t]
|
|
26
|
-
return
|
|
27
|
-
|
|
25
|
+
let t = c.value, n = s[t];
|
|
26
|
+
if (!n) return () => e[l];
|
|
27
|
+
let r = n.aesMap;
|
|
28
|
+
return function(n) {
|
|
29
|
+
return r(o.getColumnValueCategory(t, n), l) ?? e[l];
|
|
28
30
|
};
|
|
29
31
|
}
|
|
30
32
|
return () => c;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAesGetter.js","names":[],"sources":["../../../src/scatterplot/utils/createAesGetter.ts"],"sourcesContent":["import type { ScalePower } from 'd3-scale';\nimport { scaleSqrt } from 'd3-scale';\nimport type { DataFrame } from '../../DataFrame';\nimport type {\n AesItem,\n ContinuousAesFromColumn,\n InheritAesScatterplot,\n LineShape,\n PointShape,\n ScatterplotLegendInfo\n} from '../../types';\nimport { isContinuousAes } from '../../types';\nimport { getContinuousColorScale } from '../../utils/getContinuousColorScale';\nimport { DEFAULT_COMMON_AES, DEFAULT_DOT_AES } from '../constants';\n\nfunction isInheritedAes(v: InheritAesScatterplot | unknown): v is InheritAesScatterplot {\n return typeof v === 'object' && v !== null && 'type' in v && 'value' in v && v.type === 'grouping';\n}\nexport function createAesGetter<ValueType extends string | number | PointShape | LineShape>(\n dataFrame: DataFrame,\n legendInfo: ScatterplotLegendInfo,\n aesItem: ValueType | ContinuousAesFromColumn<ValueType> | InheritAesScatterplot,\n field: keyof AesItem\n) {\n if (isContinuousAes<ValueType>(aesItem) && field === 'dotSize') {\n const {domain, range} = aesItem;\n const scale: ScalePower<number, number> = scaleSqrt<number, number>()\n .domain(domain)\n .range(range as number[]);\n return function(rowIndex: number) {\n const v = scale(Number(dataFrame.getColumnValue(aesItem.columnName.value, rowIndex)));\n return Math.max(1, v as number) as ValueType;\n };\n }\n if (isContinuousAes<ValueType>(aesItem) && (field === 'dotFill' || field === 'lineColor')) {\n const {domain, range, type = 'linear'} = aesItem;\n const scale = getContinuousColorScale(range as string[], domain, type);\n return function(rowIndex: number) {\n const v = dataFrame.getColumnValue(aesItem.columnName.value, rowIndex);\n if (v === null) {\n return DEFAULT_DOT_AES.color as ValueType;\n }\n return scale(Number(v)) as ValueType;\n };\n }\n if (isInheritedAes(aesItem)) {\n const columnId = aesItem.value;\n const
|
|
1
|
+
{"version":3,"file":"createAesGetter.js","names":[],"sources":["../../../src/scatterplot/utils/createAesGetter.ts"],"sourcesContent":["import type { ScalePower } from 'd3-scale';\nimport { scaleSqrt } from 'd3-scale';\nimport type { DataFrame } from '../../DataFrame';\nimport type {\n AesItem,\n ContinuousAesFromColumn,\n InheritAesScatterplot,\n LineShape,\n PointShape,\n ScatterplotLegendInfo\n} from '../../types';\nimport { isContinuousAes } from '../../types';\nimport { getContinuousColorScale } from '../../utils/getContinuousColorScale';\nimport { DEFAULT_COMMON_AES, DEFAULT_DOT_AES } from '../constants';\n\nfunction isInheritedAes(v: InheritAesScatterplot | unknown): v is InheritAesScatterplot {\n return typeof v === 'object' && v !== null && 'type' in v && 'value' in v && v.type === 'grouping';\n}\nexport function createAesGetter<ValueType extends string | number | PointShape | LineShape>(\n dataFrame: DataFrame,\n legendInfo: ScatterplotLegendInfo,\n aesItem: ValueType | ContinuousAesFromColumn<ValueType> | InheritAesScatterplot,\n field: keyof AesItem\n) {\n if (isContinuousAes<ValueType>(aesItem) && field === 'dotSize') {\n const {domain, range} = aesItem;\n const scale: ScalePower<number, number> = scaleSqrt<number, number>()\n .domain(domain)\n .range(range as number[]);\n return function(rowIndex: number) {\n const v = scale(Number(dataFrame.getColumnValue(aesItem.columnName.value, rowIndex)));\n return Math.max(1, v as number) as ValueType;\n };\n }\n if (isContinuousAes<ValueType>(aesItem) && (field === 'dotFill' || field === 'lineColor')) {\n const {domain, range, type = 'linear'} = aesItem;\n const scale = getContinuousColorScale(range as string[], domain, type);\n return function(rowIndex: number) {\n const v = dataFrame.getColumnValue(aesItem.columnName.value, rowIndex);\n if (v === null) {\n return DEFAULT_DOT_AES.color as ValueType;\n }\n return scale(Number(v)) as ValueType;\n };\n }\n if (isInheritedAes(aesItem)) {\n const columnId = aesItem.value;\n // Stale InheritAes: stored `lineColor: {type:'grouping', value:<col>}` can outlive its grouping\n // column (e.g. user removes the grouping slot). Fall back to the field default instead of throwing.\n const entry = legendInfo[columnId];\n if (!entry) {\n return () => DEFAULT_COMMON_AES[field] as ValueType;\n }\n const mapping = entry.aesMap;\n return function(rowIndex: number) {\n const category = dataFrame.getColumnValueCategory(columnId, rowIndex);\n return (mapping(category, field) ?? DEFAULT_COMMON_AES[field]) as ValueType;\n };\n }\n return () => aesItem as ValueType;\n}\n"],"mappings":";;;;;AAeA,SAAS,EAAe,GAAgE;AACpF,QAAO,OAAO,KAAM,cAAY,KAAc,UAAU,KAAK,WAAW,KAAK,EAAE,SAAS;;AAE5F,SAAgB,EACZ,GACA,GACA,GACA,GACF;AACE,KAAI,EAA2B,EAAQ,IAAI,MAAU,WAAW;EAC5D,IAAM,EAAC,WAAQ,aAAS,GAClB,IAAoC,GAA2B,CAChE,OAAO,EAAO,CACd,MAAM,EAAkB;AAC7B,SAAO,SAAS,GAAkB;GAC9B,IAAM,IAAI,EAAM,OAAO,EAAU,eAAe,EAAQ,WAAW,OAAO,EAAS,CAAC,CAAC;AACrF,UAAO,KAAK,IAAI,GAAG,EAAY;;;AAGvC,KAAI,EAA2B,EAAQ,KAAK,MAAU,aAAa,MAAU,cAAc;EACvF,IAAM,EAAC,WAAQ,UAAO,UAAO,aAAY,GACnC,IAAQ,EAAwB,GAAmB,GAAQ,EAAK;AACtE,SAAO,SAAS,GAAkB;GAC9B,IAAM,IAAI,EAAU,eAAe,EAAQ,WAAW,OAAO,EAAS;AAItE,UAHI,MAAM,OACC,EAAgB,QAEpB,EAAM,OAAO,EAAE,CAAC;;;AAG/B,KAAI,EAAe,EAAQ,EAAE;EACzB,IAAM,IAAW,EAAQ,OAGnB,IAAQ,EAAW;AACzB,MAAI,CAAC,EACD,cAAa,EAAmB;EAEpC,IAAM,IAAU,EAAM;AACtB,SAAO,SAAS,GAAkB;AAE9B,UAAQ,EADS,EAAU,uBAAuB,GAAU,EAAS,EAC3C,EAAM,IAAI,EAAmB;;;AAG/D,cAAa"}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { DataFrame } from '../../DataFrame';
|
|
2
|
-
import { AesRecord, AesItem, Category, ColumnName, ScatterplotLayer, ScatterplotLegendInfo } from '../../types';
|
|
2
|
+
import { AesRecord, AesItem, Category, ColumnName, ContinuousAesFromColumn, InheritAesScatterplot, ScatterplotLayer, ScatterplotLegendInfo } from '../../types';
|
|
3
3
|
import { ScatterplotSettingsImpl } from '../ScatterplotSettingsImpl';
|
|
4
4
|
export declare function addPalettesToAesMapping(columnName: ColumnName, usedAesFromPalettes: Partial<Record<keyof AesItem, string[]>>, inheritedAes?: AesRecord): (category: Category, field: keyof AesItem) => string | number | undefined;
|
|
5
|
-
|
|
5
|
+
type LegendAdditionalCurves = {
|
|
6
|
+
curves: ReadonlyArray<{
|
|
7
|
+
lineColor: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;
|
|
8
|
+
trend?: {
|
|
9
|
+
color?: string | InheritAesScatterplot | ContinuousAesFromColumn<string>;
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
};
|
|
13
|
+
export declare function createLegendInfo(data: DataFrame, grouping: ScatterplotSettingsImpl['grouping'], layers: ScatterplotLayer[], additionalCurves?: LegendAdditionalCurves | null): ScatterplotLegendInfo;
|
|
14
|
+
export {};
|
|
6
15
|
//# sourceMappingURL=createLegendInfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createLegendInfo.d.ts","sourceRoot":"","sources":["../../../src/scatterplot/utils/createLegendInfo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACR,OAAO,EACP,QAAQ,EACR,UAAU,
|
|
1
|
+
{"version":3,"file":"createLegendInfo.d.ts","sourceRoot":"","sources":["../../../src/scatterplot/utils/createLegendInfo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACR,OAAO,EACP,QAAQ,EACR,UAAU,EACV,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACxB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAyB1E,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,UAAU,EACtB,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,EAC7D,YAAY,CAAC,EAAE,SAAS,cAQO,QAAQ,SAAS,MAAM,OAAO,iCAahE;AASD,KAAK,sBAAsB,GAAG;IAC1B,MAAM,EAAE,aAAa,CAAC;QAClB,SAAS,EAAE,MAAM,GAAG,qBAAqB,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAC5E,KAAK,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAA;SAAE,CAAC;KACxF,CAAC,CAAC;CACN,CAAC;AAEF,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,uBAAuB,CAAC,UAAU,CAAC,EAC7C,MAAM,EAAE,gBAAgB,EAAE,EAC1B,gBAAgB,CAAC,EAAE,sBAAsB,GAAG,IAAI,GACjD,qBAAqB,CA8EvB"}
|