@nivo/scatterplot
Version:
1 lines • 65.8 kB
Source Map (JSON)
{"version":3,"file":"nivo-scatterplot.mjs","sources":["../src/compute.ts","../src/hooks.ts","../src/Node.tsx","../src/props.tsx","../src/Tooltip.tsx","../src/ScatterPlotAnnotations.tsx","../src/Nodes.tsx","../src/Mesh.tsx","../src/ScatterPlot.tsx","../src/ResponsiveScatterPlot.tsx","../src/ScatterPlotCanvas.tsx","../src/ResponsiveScatterPlotCanvas.tsx"],"sourcesContent":["import get from 'lodash/get.js'\nimport isString from 'lodash/isString.js'\nimport isNumber from 'lodash/isNumber.js'\nimport isPlainObject from 'lodash/isPlainObject.js'\nimport { scaleLinear } from 'd3-scale'\nimport { ComputedSerie } from '@nivo/scales'\nimport {\n ScatterPlotCommonProps,\n ScatterPlotDatum,\n ScatterPlotNodeData,\n ScatterPlotNodeDynamicSizeSpec,\n} from './types'\n\nconst isDynamicSizeSpec = <RawDatum extends ScatterPlotDatum>(\n size: ScatterPlotCommonProps<RawDatum>['nodeSize']\n): size is ScatterPlotNodeDynamicSizeSpec => isPlainObject(size)\n\nexport const getNodeSizeGenerator = <RawDatum extends ScatterPlotDatum>(\n size: ScatterPlotCommonProps<RawDatum>['nodeSize']\n) => {\n if (typeof size === 'function') return size\n if (isNumber(size)) return () => size\n if (isDynamicSizeSpec<RawDatum>(size)) {\n if (!isString(size.key)) {\n throw new Error(\n 'symbolSize is invalid, key should be a string pointing to the property to use to determine node size'\n )\n }\n if (!Array.isArray(size.values) || size.values.length !== 2) {\n throw new Error(\n 'symbolSize is invalid, values spec should be an array containing two values, min and max'\n )\n }\n if (!Array.isArray(size.sizes) || size.sizes.length !== 2) {\n throw new Error(\n 'symbolSize is invalid, sizes spec should be an array containing two values, min and max'\n )\n }\n\n const sizeScale = scaleLinear()\n .domain([size.values[0], size.values[1]])\n .range([size.sizes[0], size.sizes[1]])\n\n return (datum: Omit<ScatterPlotNodeData<RawDatum>, 'size' | 'color'>) =>\n sizeScale(get(datum, size.key))\n }\n\n throw new Error('nodeSize is invalid, it should be either a function, a number or an object')\n}\n\nexport const computePoints = <RawDatum extends ScatterPlotDatum>({\n series,\n formatX,\n formatY,\n getNodeId,\n}: {\n series: ComputedSerie<{ id: string | number }, RawDatum>[]\n formatX: (value: RawDatum['x']) => string | number\n formatY: (value: RawDatum['x']) => string | number\n getNodeId: (d: Omit<ScatterPlotNodeData<RawDatum>, 'id' | 'size' | 'color'>) => string\n}): Omit<ScatterPlotNodeData<RawDatum>, 'size' | 'color'>[] => {\n const points: Omit<ScatterPlotNodeData<RawDatum>, 'size' | 'color'>[] = []\n\n series.forEach(serie => {\n serie.data.forEach((d, serieIndex) => {\n const point: Omit<ScatterPlotNodeData<RawDatum>, 'id' | 'size' | 'color'> = {\n index: points.length,\n serieIndex,\n serieId: serie.id,\n x: d.position.x as number,\n xValue: d.data.x,\n formattedX: formatX(d.data.x),\n y: d.position.y as number,\n yValue: d.data.y,\n formattedY: formatY(d.data.y),\n data: d.data,\n }\n\n points.push({\n ...point,\n id: getNodeId(point),\n })\n })\n })\n\n return points\n}\n","import { useMemo } from 'react'\nimport { useValueFormatter, usePropertyAccessor } from '@nivo/core'\nimport { useOrdinalColorScale } from '@nivo/colors'\nimport { computeXYScalesForSeries } from '@nivo/scales'\nimport { useAnnotations } from '@nivo/annotations'\nimport { computePoints, getNodeSizeGenerator } from './compute'\nimport {\n ScatterPlotCommonProps,\n ScatterPlotDataProps,\n ScatterPlotDatum,\n ScatterPlotNodeData,\n} from './types'\n\nconst useNodeSize = <RawDatum extends ScatterPlotDatum>(\n size: ScatterPlotCommonProps<RawDatum>['nodeSize']\n) => useMemo(() => getNodeSizeGenerator<RawDatum>(size), [size])\n\nexport const useScatterPlot = <RawDatum extends ScatterPlotDatum>({\n data,\n xScaleSpec,\n xFormat,\n yScaleSpec,\n yFormat,\n width,\n height,\n nodeId,\n nodeSize,\n colors,\n}: {\n data: ScatterPlotDataProps<RawDatum>['data']\n xScaleSpec: ScatterPlotCommonProps<RawDatum>['xScale']\n xFormat?: ScatterPlotCommonProps<RawDatum>['xFormat']\n yScaleSpec: ScatterPlotCommonProps<RawDatum>['yScale']\n yFormat?: ScatterPlotCommonProps<RawDatum>['yFormat']\n width: number\n height: number\n nodeId: ScatterPlotCommonProps<RawDatum>['nodeId']\n nodeSize: ScatterPlotCommonProps<RawDatum>['nodeSize']\n colors: ScatterPlotCommonProps<RawDatum>['colors']\n}) => {\n const { series, xScale, yScale } = useMemo(\n () =>\n computeXYScalesForSeries<{ id: string | number }, RawDatum>(\n data,\n xScaleSpec,\n yScaleSpec,\n width,\n height\n ),\n [data, xScaleSpec, yScaleSpec, width, height]\n )\n\n const formatX = useValueFormatter(xFormat)\n const formatY = useValueFormatter(yFormat)\n const getNodeId = usePropertyAccessor(nodeId)\n const rawNodes = useMemo(\n () => computePoints<RawDatum>({ series, formatX, formatY, getNodeId }),\n [series, formatX, formatY, getNodeId]\n )\n\n const getNodeSize = useNodeSize<RawDatum>(nodeSize)\n\n const getColor = useOrdinalColorScale(colors, 'serieId')\n\n const nodes: ScatterPlotNodeData<RawDatum>[] = useMemo(\n () =>\n rawNodes.map(rawNode => ({\n ...rawNode,\n size: getNodeSize(rawNode),\n color: getColor({ serieId: rawNode.serieId }),\n })),\n [rawNodes, getNodeSize, getColor]\n )\n\n const legendData = useMemo(\n () =>\n series.map(serie => ({\n id: serie.id,\n label: serie.id,\n color: getColor({ serieId: serie.id }),\n })),\n [series, getColor]\n )\n\n return {\n xScale,\n yScale,\n nodes,\n legendData,\n }\n}\n\nexport const useScatterPlotAnnotations = <RawDatum extends ScatterPlotDatum>(\n items: ScatterPlotNodeData<RawDatum>[],\n annotations: ScatterPlotCommonProps<RawDatum>['annotations']\n) =>\n useAnnotations<ScatterPlotNodeData<RawDatum>>({\n data: items,\n annotations,\n getPosition: (node: ScatterPlotNodeData<RawDatum>) => ({\n x: node.x,\n y: node.y,\n }),\n getDimensions: (node: ScatterPlotNodeData<RawDatum>) => ({\n size: node.size,\n width: node.size,\n height: node.size,\n }),\n })\n","import { useCallback, MouseEvent } from 'react'\nimport { animated } from '@react-spring/web'\nimport { ScatterPlotDatum, ScatterPlotNodeProps } from './types'\n\nconst interpolateRadius = (size: number) => size / 2\n\nexport const Node = <RawDatum extends ScatterPlotDatum>({\n node,\n style,\n blendMode,\n isInteractive,\n onMouseEnter,\n onMouseMove,\n onMouseLeave,\n onMouseDown,\n onMouseUp,\n onClick,\n onDoubleClick,\n}: ScatterPlotNodeProps<RawDatum>) => {\n const handleMouseEnter = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onMouseEnter?.(node, event),\n [node, onMouseEnter]\n )\n const handleMouseMove = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onMouseMove?.(node, event),\n [node, onMouseMove]\n )\n const handleMouseLeave = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onMouseLeave?.(node, event),\n [node, onMouseLeave]\n )\n const handleMouseDown = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onMouseDown?.(node, event),\n [node, onMouseDown]\n )\n const handleMouseUp = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onMouseUp?.(node, event),\n [node, onMouseUp]\n )\n const handleClick = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onClick?.(node, event),\n [node, onClick]\n )\n const handleDoubleClick = useCallback(\n (event: MouseEvent<SVGCircleElement>) => onDoubleClick?.(node, event),\n [node, onDoubleClick]\n )\n\n return (\n <animated.circle\n cx={style.x}\n cy={style.y}\n r={style.size.to(interpolateRadius)}\n fill={style.color}\n style={{ mixBlendMode: blendMode }}\n onMouseEnter={isInteractive ? handleMouseEnter : undefined}\n onMouseMove={isInteractive ? handleMouseMove : undefined}\n onMouseLeave={isInteractive ? handleMouseLeave : undefined}\n onMouseDown={isInteractive ? handleMouseDown : undefined}\n onMouseUp={isInteractive ? handleMouseUp : undefined}\n onClick={isInteractive ? handleClick : undefined}\n onDoubleClick={isInteractive ? handleDoubleClick : undefined}\n />\n )\n}\n","import { CssMixBlendMode } from '@nivo/core'\nimport { Node } from './Node'\nimport { Tooltip } from './Tooltip'\nimport {\n ScatterPlotCommonProps,\n ScatterPlotDatum,\n ScatterPlotLayerId,\n ScatterPlotNodeData,\n} from './types'\n\nexport const commonDefaultProps = {\n xScale: {\n type: 'linear',\n min: 0,\n max: 'auto',\n } as ScatterPlotCommonProps<ScatterPlotDatum>['xScale'],\n yScale: {\n type: 'linear',\n min: 0,\n max: 'auto',\n } as ScatterPlotCommonProps<ScatterPlotDatum>['yScale'],\n enableGridX: true,\n enableGridY: true,\n axisTop: null,\n axisRight: null,\n axisBottom: {},\n axisLeft: {},\n nodeId: (({ serieId, index }) =>\n `${serieId}.${index}`) as ScatterPlotCommonProps<ScatterPlotDatum>['nodeId'],\n nodeSize: 9,\n nodeComponent: Node,\n colors: { scheme: 'nivo' } as ScatterPlotCommonProps<ScatterPlotDatum>['colors'],\n isInteractive: true,\n debugMesh: false,\n tooltip: Tooltip,\n markers: [],\n legends: [],\n annotations: [],\n}\n\nexport const svgDefaultProps = {\n ...commonDefaultProps,\n blendMode: 'normal' as CssMixBlendMode,\n layers: [\n 'grid',\n 'axes',\n 'nodes',\n 'markers',\n 'mesh',\n 'legends',\n 'annotations',\n ] as ScatterPlotLayerId[],\n role: 'img',\n useMesh: true,\n animate: true,\n motionConfig: 'default',\n}\n\nexport const canvasDefaultProps = {\n ...commonDefaultProps,\n layers: ['grid', 'axes', 'nodes', 'mesh', 'legends', 'annotations'] as ScatterPlotLayerId[],\n pixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1,\n renderNode: (ctx: CanvasRenderingContext2D, node: ScatterPlotNodeData<ScatterPlotDatum>) => {\n ctx.beginPath()\n ctx.arc(node.x, node.y, node.size / 2, 0, 2 * Math.PI)\n ctx.fillStyle = node.color\n ctx.fill()\n },\n}\n","import { BasicTooltip } from '@nivo/tooltip'\nimport { ScatterPlotTooltipProps, ScatterPlotDatum } from './types'\n\nexport const Tooltip = <RawDatum extends ScatterPlotDatum>({\n node,\n}: ScatterPlotTooltipProps<RawDatum>) => (\n <BasicTooltip\n id={node.serieId}\n value={`x: ${node.formattedX}, y: ${node.formattedY}`}\n enableChip={true}\n color={node.color}\n />\n)\n","import { Annotation } from '@nivo/annotations'\nimport { useScatterPlotAnnotations } from './hooks'\nimport { ScatterPlotCommonProps, ScatterPlotDatum, ScatterPlotNodeData } from './types'\n\ninterface ScatterPlotAnnotationsProps<RawDatum extends ScatterPlotDatum> {\n nodes: ScatterPlotNodeData<RawDatum>[]\n annotations: ScatterPlotCommonProps<RawDatum>['annotations']\n}\n\nexport const ScatterPlotAnnotations = <RawDatum extends ScatterPlotDatum>({\n nodes,\n annotations,\n}: ScatterPlotAnnotationsProps<RawDatum>) => {\n const boundAnnotations = useScatterPlotAnnotations<RawDatum>(nodes, annotations)\n\n return (\n <>\n {boundAnnotations.map((annotation, i) => (\n <Annotation key={i} {...annotation} />\n ))}\n </>\n )\n}\n","import { createElement, useCallback, MouseEvent } from 'react'\nimport { useTransition } from '@react-spring/web'\nimport { CssMixBlendMode, useMotionConfig } from '@nivo/core'\nimport { useTooltip } from '@nivo/tooltip'\nimport {\n ScatterPlotCommonProps,\n ScatterPlotDatum,\n ScatterPlotNode,\n ScatterPlotNodeData,\n} from './types'\n\ninterface NodesProps<RawDatum extends ScatterPlotDatum> {\n nodes: ScatterPlotNodeData<RawDatum>[]\n nodeComponent: ScatterPlotNode<RawDatum>\n isInteractive: boolean\n onMouseEnter?: ScatterPlotCommonProps<RawDatum>['onMouseEnter']\n onMouseMove?: ScatterPlotCommonProps<RawDatum>['onMouseMove']\n onMouseLeave?: ScatterPlotCommonProps<RawDatum>['onMouseLeave']\n onMouseDown?: ScatterPlotCommonProps<RawDatum>['onMouseDown']\n onMouseUp?: ScatterPlotCommonProps<RawDatum>['onMouseUp']\n onClick?: ScatterPlotCommonProps<RawDatum>['onClick']\n onDoubleClick?: ScatterPlotCommonProps<RawDatum>['onDoubleClick']\n tooltip: ScatterPlotCommonProps<RawDatum>['tooltip']\n blendMode: CssMixBlendMode\n}\n\nconst getNodeKey = <RawDatum extends ScatterPlotDatum>(node: ScatterPlotNodeData<RawDatum>) =>\n node.id\nconst regularTransition = <RawDatum extends ScatterPlotDatum>(\n node: ScatterPlotNodeData<RawDatum>\n) => ({\n x: node.x,\n y: node.y,\n size: node.size,\n color: node.color,\n})\nconst leaveTransition = <RawDatum extends ScatterPlotDatum>(\n node: ScatterPlotNodeData<RawDatum>\n) => ({\n x: node.x,\n y: node.y,\n size: 0,\n color: node.color,\n})\n\nexport const Nodes = <RawDatum extends ScatterPlotDatum>({\n nodes,\n nodeComponent,\n isInteractive,\n onMouseEnter,\n onMouseMove,\n onMouseLeave,\n onMouseDown,\n onMouseUp,\n onClick,\n onDoubleClick,\n tooltip,\n blendMode,\n}: NodesProps<RawDatum>) => {\n const { animate, config: springConfig } = useMotionConfig()\n const transition = useTransition<\n ScatterPlotNodeData<RawDatum>,\n {\n x: number\n y: number\n size: number\n color: string\n }\n >(nodes, {\n keys: getNodeKey,\n from: regularTransition,\n enter: regularTransition,\n update: regularTransition,\n leave: leaveTransition,\n config: springConfig,\n immediate: !animate,\n })\n\n const { showTooltipFromEvent, hideTooltip } = useTooltip()\n const handleMouseEnter = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n showTooltipFromEvent(createElement(tooltip, { node }), event)\n onMouseEnter?.(node, event)\n },\n [tooltip, showTooltipFromEvent, onMouseEnter]\n )\n const handleMouseMove = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n showTooltipFromEvent(createElement(tooltip, { node }), event)\n onMouseMove?.(node, event)\n },\n [tooltip, showTooltipFromEvent, onMouseMove]\n )\n const handleMouseLeave = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n hideTooltip()\n onMouseLeave?.(node, event)\n },\n [hideTooltip, onMouseLeave]\n )\n const handleMouseDown = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => onMouseDown?.(node, event),\n [onMouseDown]\n )\n const handleMouseUp = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => onMouseUp?.(node, event),\n [onMouseUp]\n )\n const handleClick = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => onClick?.(node, event),\n [onClick]\n )\n const handleDoubleClick = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => onDoubleClick?.(node, event),\n [onDoubleClick]\n )\n\n return (\n <>\n {transition((style, node) =>\n createElement(nodeComponent, {\n node,\n style,\n blendMode,\n isInteractive,\n onMouseEnter: isInteractive ? handleMouseEnter : undefined,\n onMouseMove: isInteractive ? handleMouseMove : undefined,\n onMouseLeave: isInteractive ? handleMouseLeave : undefined,\n onMouseDown: isInteractive ? handleMouseDown : undefined,\n onMouseUp: isInteractive ? handleMouseUp : undefined,\n onClick: isInteractive ? handleClick : undefined,\n onDoubleClick: isInteractive ? handleDoubleClick : undefined,\n })\n )}\n </>\n )\n}\n","import { createElement, useCallback, MouseEvent } from 'react'\nimport { useTooltip } from '@nivo/tooltip'\nimport { Mesh as BaseMesh } from '@nivo/voronoi'\nimport { ScatterPlotCommonProps, ScatterPlotDatum, ScatterPlotNodeData } from './types'\n\ninterface MeshProps<RawDatum extends ScatterPlotDatum> {\n nodes: ScatterPlotNodeData<RawDatum>[]\n width: number\n height: number\n onMouseEnter?: ScatterPlotCommonProps<RawDatum>['onMouseEnter']\n onMouseMove?: ScatterPlotCommonProps<RawDatum>['onMouseMove']\n onMouseLeave?: ScatterPlotCommonProps<RawDatum>['onMouseLeave']\n onMouseDown?: ScatterPlotCommonProps<RawDatum>['onMouseDown']\n onMouseUp?: ScatterPlotCommonProps<RawDatum>['onMouseUp']\n onClick?: ScatterPlotCommonProps<RawDatum>['onClick']\n onDoubleClick?: ScatterPlotCommonProps<RawDatum>['onDoubleClick']\n tooltip: ScatterPlotCommonProps<RawDatum>['tooltip']\n debug: boolean\n}\n\nexport const Mesh = <RawDatum extends ScatterPlotDatum>({\n nodes,\n width,\n height,\n onMouseEnter,\n onMouseMove,\n onMouseLeave,\n onMouseDown,\n onMouseUp,\n onClick,\n onDoubleClick,\n tooltip,\n debug,\n}: MeshProps<RawDatum>) => {\n const { showTooltipFromEvent, hideTooltip } = useTooltip()\n\n const handleMouseEnter = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n showTooltipFromEvent(createElement(tooltip, { node }), event)\n onMouseEnter?.(node, event)\n },\n [showTooltipFromEvent, tooltip, onMouseEnter]\n )\n\n const handleMouseMove = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n showTooltipFromEvent(createElement(tooltip, { node }), event)\n onMouseMove?.(node, event)\n },\n [showTooltipFromEvent, tooltip, onMouseMove]\n )\n\n const handleMouseLeave = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n hideTooltip()\n onMouseLeave?.(node, event)\n },\n [hideTooltip, onMouseLeave]\n )\n\n const handleMouseDown = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n onMouseDown?.(node, event)\n },\n [onMouseDown]\n )\n\n const handleMouseUp = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n onMouseUp?.(node, event)\n },\n [onMouseUp]\n )\n\n const handleClick = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n onClick?.(node, event)\n },\n [onClick]\n )\n\n const handleDoubleClick = useCallback(\n (node: ScatterPlotNodeData<RawDatum>, event: MouseEvent) => {\n onDoubleClick?.(node, event)\n },\n [onDoubleClick]\n )\n\n return (\n <BaseMesh\n nodes={nodes}\n width={width}\n height={height}\n onMouseEnter={handleMouseEnter}\n onMouseMove={handleMouseMove}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onClick={handleClick}\n onDoubleClick={handleDoubleClick}\n debug={debug}\n />\n )\n}\n","import { createElement, Fragment, ReactNode, useMemo, forwardRef, Ref, ReactElement } from 'react'\nimport { SvgWrapper, Container, useDimensions, CartesianMarkers, WithChartRef } from '@nivo/core'\nimport { Axes, Grid } from '@nivo/axes'\nimport { BoxLegendSvg } from '@nivo/legends'\nimport { useScatterPlot } from './hooks'\nimport { svgDefaultProps } from './props'\nimport { ScatterPlotAnnotations } from './ScatterPlotAnnotations'\nimport { Nodes } from './Nodes'\nimport { Mesh } from './Mesh'\nimport { ScatterPlotDatum, ScatterPlotLayerId, ScatterPlotSvgProps } from './types'\n\ntype InnerScatterPlotProps<RawDatum extends ScatterPlotDatum> = Omit<\n ScatterPlotSvgProps<RawDatum>,\n 'animate' | 'motionConfig' | 'renderWrapper' | 'theme'\n> & {\n forwardedRef: Ref<SVGSVGElement>\n}\n\nconst InnerScatterPlot = <RawDatum extends ScatterPlotDatum>({\n data,\n xScale: xScaleSpec = svgDefaultProps.xScale,\n xFormat,\n yScale: yScaleSpec = svgDefaultProps.yScale,\n yFormat,\n width,\n height,\n margin: partialMargin,\n layers = svgDefaultProps.layers,\n colors = svgDefaultProps.colors,\n blendMode = svgDefaultProps.blendMode,\n nodeId = svgDefaultProps.nodeId,\n nodeSize = svgDefaultProps.nodeSize,\n nodeComponent = svgDefaultProps.nodeComponent,\n enableGridX = svgDefaultProps.enableGridX,\n enableGridY = svgDefaultProps.enableGridY,\n gridXValues,\n gridYValues,\n axisTop,\n axisRight,\n axisBottom = svgDefaultProps.axisBottom,\n axisLeft = svgDefaultProps.axisLeft,\n annotations = svgDefaultProps.annotations,\n isInteractive = svgDefaultProps.isInteractive,\n useMesh = svgDefaultProps.useMesh,\n debugMesh = svgDefaultProps.debugMesh,\n onMouseEnter,\n onMouseMove,\n onMouseLeave,\n onMouseDown,\n onMouseUp,\n onClick,\n onDoubleClick,\n tooltip = svgDefaultProps.tooltip,\n markers = svgDefaultProps.markers,\n legends = svgDefaultProps.legends,\n role = svgDefaultProps.role,\n ariaLabel,\n ariaLabelledBy,\n ariaDescribedBy,\n forwardedRef,\n}: InnerScatterPlotProps<RawDatum>) => {\n const { margin, innerWidth, innerHeight, outerWidth, outerHeight } = useDimensions(\n width,\n height,\n partialMargin\n )\n\n const { xScale, yScale, nodes, legendData } = useScatterPlot<RawDatum>({\n data,\n xScaleSpec,\n xFormat,\n yScaleSpec,\n yFormat,\n width: innerWidth,\n height: innerHeight,\n nodeId,\n nodeSize,\n colors,\n })\n\n const customLayerProps = useMemo(\n () => ({\n xScale,\n yScale,\n nodes,\n margin,\n innerWidth,\n innerHeight,\n outerWidth,\n outerHeight,\n }),\n [xScale, yScale, nodes, margin, innerWidth, innerHeight, outerWidth, outerHeight]\n )\n\n const layerById: Record<ScatterPlotLayerId, ReactNode> = {\n grid: null,\n axes: null,\n nodes: null,\n markers: null,\n mesh: null,\n annotations: null,\n legends: null,\n }\n\n if (layers.includes('grid')) {\n layerById.grid = (\n <Grid\n key=\"grid\"\n width={innerWidth}\n height={innerHeight}\n xScale={enableGridX ? xScale : null}\n yScale={enableGridY ? yScale : null}\n xValues={gridXValues}\n yValues={gridYValues}\n />\n )\n }\n\n if (layers.includes('axes')) {\n layerById.axes = (\n <Axes\n key=\"axes\"\n xScale={xScale}\n yScale={yScale}\n width={innerWidth}\n height={innerHeight}\n top={axisTop}\n right={axisRight}\n bottom={axisBottom}\n left={axisLeft}\n />\n )\n }\n\n if (layers.includes('nodes')) {\n layerById.nodes = (\n <Nodes<RawDatum>\n key=\"nodes\"\n nodes={nodes}\n nodeComponent={nodeComponent}\n isInteractive={isInteractive}\n tooltip={tooltip}\n blendMode={blendMode}\n onMouseEnter={onMouseEnter}\n onMouseMove={onMouseMove}\n onMouseLeave={onMouseLeave}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n onClick={onClick}\n onDoubleClick={onDoubleClick}\n />\n )\n }\n\n if (layers.includes('markers')) {\n layerById.markers = (\n <CartesianMarkers<RawDatum['x'], RawDatum['y']>\n key=\"markers\"\n markers={markers}\n width={innerWidth}\n height={innerHeight}\n xScale={xScale as (value: RawDatum['x']) => number}\n yScale={yScale as (value: RawDatum['y']) => number}\n />\n )\n }\n\n if (layers.includes('mesh') && isInteractive && useMesh) {\n layerById.mesh = (\n <Mesh<RawDatum>\n key=\"mesh\"\n nodes={nodes}\n width={innerWidth}\n height={innerHeight}\n onMouseEnter={onMouseEnter}\n onMouseMove={onMouseMove}\n onMouseLeave={onMouseLeave}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n onClick={onClick}\n onDoubleClick={onDoubleClick}\n tooltip={tooltip}\n debug={debugMesh}\n />\n )\n }\n\n if (layers.includes('annotations')) {\n layerById.annotations = (\n <ScatterPlotAnnotations<RawDatum>\n key=\"annotations\"\n nodes={nodes}\n annotations={annotations}\n />\n )\n }\n\n if (layers.includes('legends')) {\n layerById.legends = legends.map((legend, i) => (\n <BoxLegendSvg\n key={i}\n {...legend}\n containerWidth={innerWidth}\n containerHeight={innerHeight}\n data={legendData}\n />\n ))\n }\n\n return (\n <SvgWrapper\n width={outerWidth}\n height={outerHeight}\n margin={margin}\n role={role}\n ariaLabel={ariaLabel}\n ariaLabelledBy={ariaLabelledBy}\n ariaDescribedBy={ariaDescribedBy}\n ref={forwardedRef}\n >\n {layers.map((layer, i) => {\n if (typeof layer === 'string' && layerById[layer] !== undefined) {\n return layerById[layer]\n }\n\n if (typeof layer === 'function') {\n return <Fragment key={i}>{createElement(layer, customLayerProps)}</Fragment>\n }\n\n throw new Error(`Unknown layer (${layer})`)\n })}\n </SvgWrapper>\n )\n}\n\nexport const ScatterPlot = forwardRef(\n <RawDatum extends ScatterPlotDatum>(\n {\n isInteractive = svgDefaultProps.isInteractive,\n animate = svgDefaultProps.animate,\n motionConfig = svgDefaultProps.motionConfig,\n theme,\n renderWrapper,\n ...props\n }: ScatterPlotSvgProps<RawDatum>,\n ref: Ref<SVGSVGElement>\n ) => (\n <Container\n animate={animate}\n isInteractive={isInteractive}\n motionConfig={motionConfig}\n renderWrapper={renderWrapper}\n theme={theme}\n >\n <InnerScatterPlot<RawDatum>\n {...props}\n isInteractive={isInteractive}\n forwardedRef={ref}\n />\n </Container>\n )\n) as <RawDatum extends ScatterPlotDatum>(\n props: WithChartRef<ScatterPlotSvgProps<RawDatum>, SVGSVGElement>\n) => ReactElement\n","import { forwardRef, Ref, ReactElement } from 'react'\nimport { ResponsiveWrapper, ResponsiveProps, WithChartRef } from '@nivo/core'\nimport { ScatterPlot } from './ScatterPlot'\nimport { ScatterPlotDatum, ScatterPlotSvgProps } from './types'\n\nexport const ResponsiveScatterPlot = forwardRef(\n <RawDatum extends ScatterPlotDatum>(\n {\n defaultWidth,\n defaultHeight,\n onResize,\n debounceResize,\n ...props\n }: ResponsiveProps<ScatterPlotSvgProps<RawDatum>>,\n ref: Ref<SVGSVGElement>\n ) => (\n <ResponsiveWrapper\n defaultWidth={defaultWidth}\n defaultHeight={defaultHeight}\n onResize={onResize}\n debounceResize={debounceResize}\n >\n {({ width, height }) => (\n <ScatterPlot<RawDatum> {...props} width={width} height={height} ref={ref} />\n )}\n </ResponsiveWrapper>\n )\n) as <RawDatum extends ScatterPlotDatum>(\n props: WithChartRef<ResponsiveProps<ScatterPlotSvgProps<RawDatum>>, SVGSVGElement>\n) => ReactElement\n","import {\n Ref,\n createElement,\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n MouseEvent,\n ReactElement,\n} from 'react'\nimport {\n Container,\n useDimensions,\n getRelativeCursor,\n isCursorInRect,\n mergeRefs,\n WithChartRef,\n} from '@nivo/core'\nimport { useTheme } from '@nivo/theming'\nimport { renderAnnotationsToCanvas } from '@nivo/annotations'\nimport { CanvasAxisProps, renderAxesToCanvas, renderGridLinesToCanvas } from '@nivo/axes'\nimport { renderLegendToCanvas } from '@nivo/legends'\nimport { useTooltip } from '@nivo/tooltip'\nimport { useVoronoiMesh, renderVoronoiToCanvas, renderVoronoiCellToCanvas } from '@nivo/voronoi'\nimport { canvasDefaultProps, svgDefaultProps } from './props'\nimport { useScatterPlot, useScatterPlotAnnotations } from './hooks'\nimport { ScatterPlotCanvasProps, ScatterPlotDatum, ScatterPlotNodeData } from './types'\n\ntype InnerScatterPlotCanvasProps<RawDatum extends ScatterPlotDatum> = Omit<\n ScatterPlotCanvasProps<RawDatum>,\n 'renderWrapper' | 'theme'\n> & {\n forwardedRef: Ref<HTMLCanvasElement>\n}\n\nconst InnerScatterPlotCanvas = <RawDatum extends ScatterPlotDatum>({\n data,\n xScale: xScaleSpec = canvasDefaultProps.xScale,\n xFormat,\n yScale: yScaleSpec = canvasDefaultProps.yScale,\n yFormat,\n width,\n height,\n margin: partialMargin,\n pixelRatio = canvasDefaultProps.pixelRatio,\n layers = canvasDefaultProps.layers,\n colors = canvasDefaultProps.colors,\n nodeId = svgDefaultProps.nodeId,\n nodeSize = canvasDefaultProps.nodeSize,\n renderNode = canvasDefaultProps.renderNode,\n enableGridX = canvasDefaultProps.enableGridX,\n gridXValues,\n enableGridY = canvasDefaultProps.enableGridY,\n gridYValues,\n axisTop,\n axisRight,\n axisBottom = canvasDefaultProps.axisBottom,\n axisLeft = canvasDefaultProps.axisLeft,\n annotations = canvasDefaultProps.annotations,\n isInteractive = canvasDefaultProps.isInteractive,\n debugMesh = canvasDefaultProps.debugMesh,\n onMouseEnter,\n onMouseMove,\n onMouseLeave,\n onMouseDown,\n onMouseUp,\n onClick,\n onDoubleClick,\n tooltip = canvasDefaultProps.tooltip,\n legends = canvasDefaultProps.legends,\n role,\n forwardedRef,\n}: InnerScatterPlotCanvasProps<RawDatum>) => {\n const canvasEl = useRef<HTMLCanvasElement | null>(null)\n const theme = useTheme()\n const [currentNode, setCurrentNode] = useState<ScatterPlotNodeData<RawDatum> | null>(null)\n\n const { margin, innerWidth, innerHeight, outerWidth, outerHeight } = useDimensions(\n width,\n height,\n partialMargin\n )\n\n const { xScale, yScale, nodes, legendData } = useScatterPlot<RawDatum>({\n data,\n xScaleSpec,\n xFormat,\n yScaleSpec,\n yFormat,\n width: innerWidth,\n height: innerHeight,\n nodeId,\n nodeSize,\n colors,\n })\n\n const boundAnnotations = useScatterPlotAnnotations<RawDatum>(nodes, annotations)\n\n const { delaunay, voronoi } = useVoronoiMesh({\n points: nodes,\n width: innerWidth,\n height: innerHeight,\n debug: debugMesh,\n })\n\n const customLayerProps = useMemo(\n () => ({\n xScale,\n yScale,\n nodes,\n margin,\n innerWidth,\n innerHeight,\n outerWidth,\n outerHeight,\n }),\n [xScale, yScale, nodes, margin, innerWidth, innerHeight, outerWidth, outerHeight]\n )\n\n useEffect(() => {\n if (!canvasEl.current) return\n\n canvasEl.current.width = outerWidth * pixelRatio\n canvasEl.current.height = outerHeight * pixelRatio\n\n const ctx = canvasEl.current.getContext('2d')!\n\n ctx.scale(pixelRatio, pixelRatio)\n\n ctx.fillStyle = theme.background\n ctx.fillRect(0, 0, outerWidth, outerHeight)\n ctx.translate(margin.left, margin.top)\n\n layers.forEach(layer => {\n if (layer === 'grid') {\n ctx.lineWidth = theme.grid.line.strokeWidth as number\n ctx.strokeStyle = theme.grid.line.stroke as string\n\n if (enableGridX) {\n renderGridLinesToCanvas<RawDatum['x']>(ctx, {\n width: innerWidth,\n height: innerHeight,\n scale: xScale,\n axis: 'x',\n values: gridXValues,\n })\n }\n\n if (enableGridY) {\n renderGridLinesToCanvas<RawDatum['y']>(ctx, {\n width: innerWidth,\n height: innerHeight,\n scale: yScale,\n axis: 'y',\n values: gridYValues,\n })\n }\n } else if (layer === 'annotations') {\n renderAnnotationsToCanvas<ScatterPlotNodeData<RawDatum>>(ctx, {\n annotations: boundAnnotations as any,\n theme,\n })\n } else if (layer === 'axes') {\n renderAxesToCanvas<RawDatum['x'], RawDatum['y']>(ctx, {\n xScale: xScale,\n yScale: yScale,\n width: innerWidth,\n height: innerHeight,\n top: axisTop as CanvasAxisProps<RawDatum['x']>,\n right: axisRight as CanvasAxisProps<RawDatum['y']>,\n bottom: axisBottom as CanvasAxisProps<RawDatum['x']>,\n left: axisLeft as CanvasAxisProps<RawDatum['y']>,\n theme,\n })\n } else if (layer === 'nodes') {\n nodes.forEach(node => {\n renderNode(ctx, node)\n })\n } else if (layer === 'mesh') {\n if (debugMesh) {\n renderVoronoiToCanvas(ctx, voronoi!)\n if (currentNode) {\n renderVoronoiCellToCanvas(ctx, voronoi!, currentNode.index)\n }\n }\n } else if (layer === 'legends') {\n legends.forEach(legend => {\n renderLegendToCanvas(ctx, {\n ...legend,\n data: legendData,\n containerWidth: innerWidth,\n containerHeight: innerHeight,\n theme,\n })\n })\n } else if (typeof layer === 'function') {\n layer(ctx, customLayerProps)\n } else {\n throw new Error(`Invalid layer: ${layer}`)\n }\n })\n }, [\n canvasEl,\n innerWidth,\n innerHeight,\n outerWidth,\n outerHeight,\n margin.top,\n margin.left,\n pixelRatio,\n renderNode,\n layers,\n customLayerProps,\n theme,\n xScale,\n yScale,\n nodes,\n enableGridX,\n gridXValues,\n enableGridY,\n gridYValues,\n axisTop,\n axisRight,\n axisBottom,\n axisLeft,\n legends,\n legendData,\n debugMesh,\n voronoi,\n currentNode,\n boundAnnotations,\n ])\n\n const { showTooltipFromEvent, hideTooltip } = useTooltip()\n\n const getNodeFromMouseEvent = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n const [x, y] = getRelativeCursor(canvasEl.current!, event)\n if (!isCursorInRect(margin.left, margin.top, innerWidth, innerHeight, x, y)) return null\n\n const nodeIndex = delaunay.find(x - margin.left, y - margin.top)\n return nodes[nodeIndex]\n },\n [canvasEl, margin, innerWidth, innerHeight, delaunay, nodes]\n )\n\n const handleMouseHover = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n const node = getNodeFromMouseEvent(event)\n setCurrentNode(node)\n\n if (node) {\n showTooltipFromEvent(createElement(tooltip, { node }), event)\n if (currentNode && currentNode.id !== node.id) {\n onMouseLeave?.(currentNode, event)\n onMouseEnter?.(node, event)\n }\n if (!currentNode) {\n onMouseEnter?.(node, event)\n }\n onMouseMove?.(node, event)\n } else {\n hideTooltip()\n if (currentNode) onMouseLeave?.(currentNode, event)\n }\n },\n [\n getNodeFromMouseEvent,\n currentNode,\n setCurrentNode,\n showTooltipFromEvent,\n hideTooltip,\n tooltip,\n onMouseEnter,\n onMouseMove,\n onMouseLeave,\n ]\n )\n\n const handleMouseLeave = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n hideTooltip()\n setCurrentNode(null)\n if (currentNode) onMouseLeave?.(currentNode, event)\n },\n [hideTooltip, currentNode, setCurrentNode, onMouseLeave]\n )\n\n const handleMouseDown = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n if (onMouseDown) {\n const node = getNodeFromMouseEvent(event)\n if (node) onMouseDown(node, event)\n }\n },\n [getNodeFromMouseEvent, onMouseDown]\n )\n\n const handleMouseUp = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n if (onMouseUp) {\n const node = getNodeFromMouseEvent(event)\n if (node) onMouseUp(node, event)\n }\n },\n [getNodeFromMouseEvent, onMouseUp]\n )\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n if (onClick) {\n const node = getNodeFromMouseEvent(event)\n if (node) onClick(node, event)\n }\n },\n [getNodeFromMouseEvent, onClick]\n )\n\n const handleDoubleClick = useCallback(\n (event: MouseEvent<HTMLCanvasElement>) => {\n if (onDoubleClick) {\n const node = getNodeFromMouseEvent(event)\n if (node) onDoubleClick(node, event)\n }\n },\n [getNodeFromMouseEvent, onDoubleClick]\n )\n\n return (\n <canvas\n ref={mergeRefs(canvasEl, forwardedRef)}\n width={outerWidth * pixelRatio}\n height={outerHeight * pixelRatio}\n style={{\n width: outerWidth,\n height: outerHeight,\n cursor: isInteractive ? 'auto' : 'normal',\n }}\n onMouseEnter={isInteractive ? handleMouseHover : undefined}\n onMouseMove={isInteractive ? handleMouseHover : undefined}\n onMouseLeave={isInteractive ? handleMouseLeave : undefined}\n onMouseDown={isInteractive ? handleMouseDown : undefined}\n onMouseUp={isInteractive ? handleMouseUp : undefined}\n onClick={isInteractive ? handleClick : undefined}\n onDoubleClick={isInteractive ? handleDoubleClick : undefined}\n role={role}\n />\n )\n}\n\nexport const ScatterPlotCanvas = forwardRef(\n <RawDatum extends ScatterPlotDatum>(\n { isInteractive, renderWrapper, theme, ...props }: ScatterPlotCanvasProps<RawDatum>,\n ref: Ref<HTMLCanvasElement>\n ) => (\n <Container\n isInteractive={isInteractive}\n renderWrapper={renderWrapper}\n theme={theme}\n animate={false}\n >\n <InnerScatterPlotCanvas<RawDatum>\n {...props}\n isInteractive={isInteractive}\n forwardedRef={ref}\n />\n </Container>\n )\n) as <RawDatum extends ScatterPlotDatum>(\n props: WithChartRef<ScatterPlotCanvasProps<RawDatum>, HTMLCanvasElement>\n) => ReactElement\n","import { ResponsiveWrapper, WithChartRef, ResponsiveProps } from '@nivo/core'\nimport { forwardRef, Ref, ReactElement } from 'react'\nimport { ScatterPlotCanvas } from './ScatterPlotCanvas'\nimport { ScatterPlotCanvasProps, ScatterPlotDatum } from './types'\n\nexport const ResponsiveScatterPlotCanvas = forwardRef(\n <RawDatum extends ScatterPlotDatum>(\n {\n defaultWidth,\n defaultHeight,\n onResize,\n debounceResize,\n ...props\n }: ResponsiveProps<ScatterPlotCanvasProps<RawDatum>>,\n ref: Ref<HTMLCanvasElement>\n ) => (\n <ResponsiveWrapper\n defaultWidth={defaultWidth}\n defaultHeight={defaultHeight}\n onResize={onResize}\n debounceResize={debounceResize}\n >\n {({ width, height }) => (\n <ScatterPlotCanvas {...props} width={width} height={height} ref={ref} />\n )}\n </ResponsiveWrapper>\n )\n) as <RawDatum extends ScatterPlotDatum>(\n props: WithChartRef<ResponsiveProps<ScatterPlotCanvasProps<RawDatum>>, HTMLCanvasElement>\n) => ReactElement\n"],"names":["getNodeSizeGenerator","size","isNumber","isPlainObject","isDynamicSizeSpec","isString","key","Error","Array","isArray","values","length","sizes","sizeScale","scaleLinear","domain","range","datum","get","useScatterPlot","_ref","data","xScaleSpec","xFormat","yScaleSpec","yFormat","width","height","nodeId","nodeSize","colors","_useMemo","useMemo","computeXYScalesForSeries","series","xScale","yScale","formatX","useValueFormatter","formatY","getNodeId","usePropertyAccessor","rawNodes","points","forEach","serie","d","serieIndex","point","index","serieId","id","x","position","xValue","formattedX","y","yValue","formattedY","push","_extends","computePoints","getNodeSize","getColor","useOrdinalColorScale","nodes","map","rawNode","color","legendData","label","useScatterPlotAnnotations","items","annotations","useAnnotations","getPosition","node","getDimensions","interpolateRadius","commonDefaultProps","type","min","max","enableGridX","enableGridY","axisTop","axisRight","axisBottom","axisLeft","nodeComponent","style","blendMode","isInteractive","onMouseEnter","onMouseMove","onMouseLeave","onMouseDown","onMouseUp","onClick","onDoubleClick","handleMouseEnter","useCallback","event","handleMouseMove","handleMouseLeave","handleMouseDown","handleMouseUp","handleClick","handleDoubleClick","_jsx","animated","circle","cx","cy","r","to","fill","mixBlendMode","undefined","scheme","debugMesh","tooltip","BasicTooltip","value","enableChip","markers","legends","svgDefaultProps","layers","role","useMesh","animate","motionConfig","canvasDefaultProps","pixelRatio","window","devicePixelRatio","renderNode","ctx","beginPath","arc","Math","PI","fillStyle","ScatterPlotAnnotations","boundAnnotations","_Fragment","children","annotation","i","Annotation","getNodeKey","regularTransition","leaveTransition","Nodes","_useMotionConfig","useMotionConfig","springConfig","config","transition","useTransition","keys","from","enter","update","leave","immediate","_useTooltip","useTooltip","showTooltipFromEvent","hideTooltip","createElement","Mesh","debug","BaseMesh","InnerScatterPlot","_ref$xScale","_ref$yScale","partialMargin","margin","_ref$layers","_ref$colors","_ref$blendMode","_ref$nodeId","_ref$nodeSize","_ref$nodeComponent","_ref$enableGridX","_ref$enableGridY","gridXValues","gridYValues","_ref$axisBottom","_ref$axisLeft","_ref$annotations","_ref$isInteractive","_ref$useMesh","_ref$debugMesh","_ref$tooltip","_ref$markers","_ref$legends","_ref$role","ariaLabel","ariaLabelledBy","ariaDescribedBy","forwardedRef","_useDimensions","useDimensions","innerWidth","innerHeight","outerWidth","outerHeight","_useScatterPlot","customLayerProps","layerById","grid","axes","mesh","includes","Grid","xValues","yValues","Axes","top","right","bottom","left","CartesianMarkers","legend","BoxLegendSvg","containerWidth","containerHeight","SvgWrapper","ref","layer","Fragment","ScatterPlot","forwardRef","_ref2","_ref2$isInteractive","_ref2$animate","_ref2$motionConfig","theme","renderWrapper","props","_objectWithoutPropertiesLoose","_excluded","Container","ResponsiveScatterPlot","defaultWidth","defaultHeight","onResize","debounceResize","ResponsiveWrapper","InnerScatterPlotCanvas","_ref$pixelRatio","_ref$renderNode","canvasEl","useRef","useTheme","_useState","useState","currentNode","setCurrentNode","_useVoronoiMesh","useVoronoiMesh","delaunay","voronoi","useEffect","current","getContext","scale","background","fillRect","translate","lineWidth","line","strokeWidth","strokeStyle","stroke","renderGridLinesToCanvas","axis","renderAnnotationsToCanvas","renderAxesToCanvas","renderVoronoiToCanvas","renderVoronoiCellToCanvas","renderLegendToCanvas","getNodeFromMouseEvent","_getRelativeCursor","getRelativeCursor","isCursorInRect","nodeIndex","find","handleMouseHover","mergeRefs","cursor","ScatterPlotCanvas","ResponsiveScatterPlotCanvas"],"mappings":"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