import React, { useMemo, useRef, useLayoutEffect, useEffect, useState, } from 'react' import { Provider } from 'jotai' import { generateID } from '../util' import { GGBase } from './GGBase' import type { RootGGProps } from './types/GG' /** * **The top-level component and starting point for creating Graphique visualizations**. * * Pass in data, map data properties to visual properties ([`aes`](https://graphique.dev/docs/graphique/gg#Aes)), and fill with child Geoms * to start visualizing data. Configure and customize with a friendly, component-based API. * * @param data - the data used to create the base, an array of objects * @param aes - an object of accessor methods to map data characteristics to visual characteristics * @param width - the width of the visualization area in pixels * @param height - the height of the visualization area in pixels * @param margin - an object specifying the margins surrounding the visualization area * @param isContainerWidth - when true, the visualization will fill its parent container's width * @param children - elements used to specify and configure the visualization (e.g. Geoms, Scales, Labels, Theme, etc.) * * @returns {React.JSX.Element} A React element that renders your visualization! */ export const GG = ({ children, ...props }: RootGGProps) => { const { data, aes, width, height, margin, isContainerWidth } = { ...props } const ggRef = useRef(null) const [ggWidth, setGGWidth] = useState( isContainerWidth ? ggRef.current?.clientWidth : width, ) useLayoutEffect(() => { if (isContainerWidth) setGGWidth(ggRef.current?.clientWidth) }, [isContainerWidth]) useEffect(() => { const observer = new ResizeObserver((entries) => { const rect = entries[0].contentRect if (isContainerWidth) setGGWidth(rect.width) }) if (ggRef.current && isContainerWidth) observer.observe(ggRef.current) return () => { if (ggRef.current && isContainerWidth) observer.unobserve(ggRef.current) } }, [isContainerWidth]) const id = useMemo(() => generateID(), []) return (
({ ...d, gg_gen_index: i, }))} aes={aes} width={ggWidth} height={height} margin={margin} id={id} > {children}
) }