import React, { memo, HTMLAttributes } from 'react';
import cc from 'classcat';
import { useStore } from '../../store';
import { getRectOfNodes, getBoundsofRects } from '../../utils/graph';
import { Node, Rect, ReactFlowState } from '../../types';
import MiniMapNode from './MiniMapNode';
type StringFunc = (node: Node) => string;
export interface MiniMapProps extends HTMLAttributes {
nodeColor?: string | StringFunc;
nodeStrokeColor?: string | StringFunc;
nodeClassName?: string | StringFunc;
nodeBorderRadius?: number;
nodeStrokeWidth?: number;
maskColor?: string;
}
declare const window: any;
const defaultWidth = 200;
const defaultHeight = 150;
const selector = (s: ReactFlowState) => ({ width: s.width, height: s.height, transform: s.transform, nodes: s.nodes });
const MiniMap = ({
style,
className,
nodeStrokeColor = '#555',
nodeColor = '#fff',
nodeClassName = '',
nodeBorderRadius = 5,
nodeStrokeWidth = 2,
maskColor = 'rgb(240, 242, 243, 0.7)',
}: MiniMapProps) => {
const { width: containerWidth, height: containerHeight, transform, nodes } = useStore(selector);
const [tX, tY, tScale] = transform;
const mapClasses = cc(['react-flow__minimap', className]);
const elementWidth = (style?.width || defaultWidth)! as number;
const elementHeight = (style?.height || defaultHeight)! as number;
const nodeColorFunc = (nodeColor instanceof Function ? nodeColor : () => nodeColor) as StringFunc;
const nodeStrokeColorFunc = (
nodeStrokeColor instanceof Function ? nodeStrokeColor : () => nodeStrokeColor
) as StringFunc;
const nodeClassNameFunc = (nodeClassName instanceof Function ? nodeClassName : () => nodeClassName) as StringFunc;
const hasNodes = nodes && nodes.length;
const bb = getRectOfNodes(nodes);
const viewBB: Rect = {
x: -tX / tScale,
y: -tY / tScale,
width: containerWidth / tScale,
height: containerHeight / tScale,
};
const boundingRect = hasNodes ? getBoundsofRects(bb, viewBB) : viewBB;
const scaledWidth = boundingRect.width / elementWidth;
const scaledHeight = boundingRect.height / elementHeight;
const viewScale = Math.max(scaledWidth, scaledHeight);
const viewWidth = viewScale * elementWidth;
const viewHeight = viewScale * elementHeight;
const offset = 5 * viewScale;
const x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset;
const y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset;
const width = viewWidth + offset * 2;
const height = viewHeight + offset * 2;
const shapeRendering = typeof window === 'undefined' || !!window.chrome ? 'crispEdges' : 'geometricPrecision';
return (
);
};
MiniMap.displayName = 'MiniMap';
export default memo(MiniMap);