UNPKG

react-google-charts

Version:
1 lines 81.3 kB
{"version":3,"file":"index.cjs","sources":["../src/hooks/useLoadScript.ts","../src/hooks/useLoadGoogleCharts.ts","../src/default-props.ts","../src/generate-unique-id.ts","../src/constants.ts","../src/load-data-table-from-spreadsheet.ts","../src/Context.tsx","../src/components/GoogleChartDataTable.tsx","../src/components/GoogleChartEvents.tsx","../src/components/GoogleChart.tsx","../src/ReactGoogleCharts.tsx","../src/types.ts","../src/index.tsx"],"sourcesContent":["import { useEffect } from \"react\";\n\n/**\n * Hook to load external script.\n * @param src - Source url to load.\n * @param onLoad - Success callback.\n * @param onError - Error callback.\n */\nexport function useLoadScript(\n src: string,\n onLoad?: () => void,\n onError?: () => void\n) {\n useEffect(() => {\n if (!document) {\n return;\n }\n\n // Find script tag with same src in DOM.\n const foundScript = document.querySelector<HTMLScriptElement>(\n `script[src=\"${src}\"]`\n );\n\n // Call onLoad if script marked as loaded.\n if (foundScript?.dataset.loaded) {\n onLoad?.();\n return;\n }\n\n // Create or get existed tag.\n const script = foundScript || document.createElement(\"script\");\n\n // Set src if no script was found.\n if (!foundScript) {\n script.src = src;\n }\n\n // Mark script as loaded on load event.\n const onLoadWithMarker = () => {\n script.dataset.loaded = \"1\";\n onLoad?.();\n };\n\n script.addEventListener(\"load\", onLoadWithMarker);\n\n if (onError) {\n script.addEventListener(\"error\", onError);\n }\n\n // Add to DOM if not yet added.\n if (!foundScript) {\n document.head.append(script);\n }\n\n return () => {\n script.removeEventListener(\"load\", onLoadWithMarker);\n\n if (onError) {\n script.removeEventListener(\"error\", onError);\n }\n };\n }, []);\n}\n","import { useState, useEffect } from \"react\";\nimport { GoogleChartVersion, GoogleChartPackages, GoogleViz } from \"../types\";\nimport { useLoadScript } from \"./useLoadScript\";\n\nexport interface IUseLoadGoogleChartsParams {\n chartVersion?: GoogleChartVersion;\n chartPackages?: GoogleChartPackages[];\n chartLanguage?: string;\n mapsApiKey?: string;\n}\n\n/**\n * Hook to load Google Charts JS API.\n * @param params - Load parameters.\n * @param [params.chartVersion] - Chart version to load.\n * @param [params.chartPackages] - Packages to load.\n * @param [params.chartLanguage] - Languages to load.\n * @param [params.mapsApiKey] - Google Maps api key.\n * @returns\n */\nexport function useLoadGoogleCharts({\n chartVersion = \"current\",\n chartPackages = [\"corechart\", \"controls\"],\n chartLanguage = \"en\",\n mapsApiKey,\n}: IUseLoadGoogleChartsParams) {\n const [googleCharts, setGoogleCharts] = useState<GoogleViz | null>(null);\n const [failed, setFailed] = useState(false);\n\n useLoadScript(\n \"https://www.gstatic.com/charts/loader.js\",\n () => {\n // @ts-expect-error Getting object from global namespace.\n const google = window?.google as GoogleViz;\n\n if (!google) {\n return;\n }\n\n google.charts.load(chartVersion, {\n packages: chartPackages,\n language: chartLanguage,\n mapsApiKey,\n });\n google.charts.setOnLoadCallback(() => {\n setGoogleCharts(google);\n });\n },\n () => {\n setFailed(true);\n }\n );\n\n return [googleCharts, failed] as const;\n}\n\nexport interface ILoadGoogleChartsProps extends IUseLoadGoogleChartsParams {\n onLoad?(googleCharts: GoogleViz): void;\n onError?(): void;\n}\n\n/**\n * Wrapper around useLoadGoogleCharts to use in legacy components.\n */\nexport function LoadGoogleCharts({\n onLoad,\n onError,\n ...params\n}: ILoadGoogleChartsProps) {\n const [googleCharts, failed] = useLoadGoogleCharts(params);\n\n useEffect(() => {\n if (googleCharts && onLoad) {\n onLoad(googleCharts);\n }\n }, [googleCharts]);\n\n useEffect(() => {\n if (failed && onError) {\n onError();\n }\n }, [failed]);\n\n return null;\n}\n","import { ReactGoogleChartProps } from \"./types\";\n\nexport const chartDefaultProps: Partial<ReactGoogleChartProps> = {\n // <DEPRECATED_PROPS>\n legend_toggle: false,\n // </DEPRECATED_PROPS>\n options: {},\n legendToggle: false,\n getChartWrapper: () => {},\n spreadSheetQueryParameters: {\n headers: 1,\n gid: 1,\n },\n rootProps: {},\n chartWrapperParams: {},\n};\n","let uniqueID = 0;\nexport const generateUniqueID = () => {\n uniqueID += 1;\n return `reactgooglegraph-${uniqueID}`;\n};\n","export const DEFAULT_CHART_COLORS = [\n \"#3366CC\",\n \"#DC3912\",\n \"#FF9900\",\n \"#109618\",\n \"#990099\",\n \"#3B3EAC\",\n \"#0099C6\",\n \"#DD4477\",\n \"#66AA00\",\n \"#B82E2E\",\n \"#316395\",\n \"#994499\",\n \"#22AA99\",\n \"#AAAA11\",\n \"#6633CC\",\n \"#E67300\",\n \"#8B0707\",\n \"#329262\",\n \"#5574A6\",\n \"#3B3EAC\"\n];\n","import { GoogleViz } from \"./types\";\n\nexport const loadDataTableFromSpreadSheet = async (\n googleViz: GoogleViz,\n spreadSheetUrl: string,\n urlParams: {\n headers?: number;\n gid?: any;\n sheet?: string;\n query?: string;\n access_token?: string;\n } = {}\n) => {\n return new Promise((resolve, reject) => {\n const headers = `${\n urlParams.headers ? `headers=${urlParams.headers}` : `headers=0`\n }`;\n const queryString = `${\n urlParams.query ? `&tq=${encodeURIComponent(urlParams.query)}` : ``\n }`;\n const gid = `${urlParams.gid ? `&gid=${urlParams.gid}` : \"\"}`;\n const sheet = `${urlParams.sheet ? `&sheet=${urlParams.sheet}` : \"\"}`;\n const access_token = `${\n urlParams.access_token ? `&access_token=${urlParams.access_token}` : \"\"\n }`;\n const urlQueryString = `${headers}${gid}${sheet}${queryString}${access_token}`;\n const urlToSpreadSheet = `${spreadSheetUrl}/gviz/tq?${urlQueryString}`; //&tq=${queryString}`;\n const query = new googleViz.visualization.Query(urlToSpreadSheet);\n query.send((response: any) => {\n if (response.isError()) {\n reject(\n `Error in query: ${response.getMessage()} ${response.getDetailedMessage()}`\n );\n } else {\n resolve(response.getDataTable());\n }\n });\n });\n};\n","import * as React from \"react\";\nimport { chartDefaultProps } from \"./default-props\";\n\nimport { ReactGoogleChartProps } from \"./types\";\nconst { Provider, Consumer } = React.createContext(chartDefaultProps);\n\nexport const ContextProvider = ({\n children,\n value,\n}: {\n children: any;\n value: ReactGoogleChartProps;\n}) => {\n return <Provider value={value}>{children}</Provider>;\n};\n\nexport const ContextConsumer = ({\n render,\n}: {\n render: (context: ReactGoogleChartProps) => JSX.Element | null;\n}) => {\n return (\n <Consumer>\n {(context) => {\n return render(context as ReactGoogleChartProps);\n }}\n </Consumer>\n );\n};\n","import * as React from \"react\";\nimport {\n GoogleViz,\n GoogleChartWrapper,\n GoogleDataTable,\n ReactGoogleChartProps,\n GoogleChartDashboard,\n} from \"../types\";\nimport { DEFAULT_CHART_COLORS } from \"../constants\";\n\nimport { loadDataTableFromSpreadSheet } from \"../load-data-table-from-spreadsheet\";\nimport { ContextConsumer } from \"../Context\";\n\nconst GRAY_COLOR = \"#CCCCCC\";\nexport type ChartDrawArgs = {\n data: ReactGoogleChartProps[\"data\"];\n};\n\nexport type GoogleChartDataTableProps = {\n googleChartWrapper: GoogleChartWrapper;\n google: GoogleViz;\n googleChartDashboard: GoogleChartDashboard | null;\n};\ninterface State {\n hiddenColumns: string[];\n}\nexport class GoogleChartDataTableInner extends React.Component<\n ReactGoogleChartProps & GoogleChartDataTableProps,\n State\n> {\n state = {\n hiddenColumns: [],\n } as State;\n\n private listenToLegendToggle = () => {\n const { google, googleChartWrapper } = this.props;\n google.visualization.events.addListener(\n googleChartWrapper,\n \"select\",\n () => {\n const chart = googleChartWrapper.getChart();\n const selection = chart.getSelection();\n const dataTable = googleChartWrapper.getDataTable();\n if (\n selection.length === 0 ||\n // We want to listen to when a whole row is selected. This is the case only when row === null\n selection[0].row ||\n !dataTable\n ) {\n return;\n }\n const columnIndex = selection[0].column;\n const columnID = this.getColumnID(dataTable, columnIndex);\n if (this.state.hiddenColumns.includes(columnID)) {\n this.setState((state) => ({\n ...state,\n hiddenColumns: [\n ...state.hiddenColumns.filter((colID) => colID !== columnID),\n ],\n }));\n } else {\n this.setState((state) => ({\n ...state,\n hiddenColumns: [...state.hiddenColumns, columnID],\n }));\n }\n }\n );\n };\n\n private applyFormatters = (dataTable: GoogleDataTable, formatters: any[]) => {\n const { google } = this.props;\n for (let formatter of formatters) {\n switch (formatter.type) {\n case \"ArrowFormat\": {\n const vizFormatter = new google.visualization.ArrowFormat(\n formatter.options\n );\n vizFormatter.format(dataTable, formatter.column);\n break;\n }\n case \"BarFormat\": {\n const vizFormatter = new google.visualization.BarFormat(\n formatter.options\n );\n vizFormatter.format(dataTable, formatter.column);\n break;\n }\n case \"ColorFormat\": {\n const vizFormatter = new google.visualization.ColorFormat(\n formatter.options\n );\n const { ranges } = formatter;\n for (let range of ranges) {\n vizFormatter.addRange(...range);\n }\n vizFormatter.format(dataTable, formatter.column);\n break;\n }\n case \"DateFormat\": {\n const vizFormatter = new google.visualization.DateFormat(\n formatter.options\n );\n vizFormatter.format(dataTable, formatter.column);\n break;\n }\n case \"NumberFormat\": {\n const vizFormatter = new google.visualization.NumberFormat(\n formatter.options\n );\n vizFormatter.format(dataTable, formatter.column);\n break;\n }\n case \"PatternFormat\": {\n const vizFormatter = new google.visualization.PatternFormat(\n formatter.options\n );\n vizFormatter.format(dataTable, formatter.column);\n break;\n }\n }\n }\n };\n private getColumnID = (dataTable: GoogleDataTable, columnIndex: number) => {\n return (\n dataTable.getColumnId(columnIndex) ||\n dataTable.getColumnLabel(columnIndex)\n );\n };\n private draw = async ({\n data,\n diffdata,\n rows,\n columns,\n options,\n legend_toggle,\n legendToggle,\n chartType,\n formatters,\n spreadSheetUrl,\n spreadSheetQueryParameters,\n }: ReactGoogleChartProps) => {\n const { google, googleChartWrapper } = this.props;\n let dataTable: GoogleDataTable;\n let chartDiff = null;\n if (diffdata) {\n const oldData = google.visualization.arrayToDataTable(diffdata.old);\n const newData = google.visualization.arrayToDataTable(diffdata.new);\n chartDiff = google.visualization[chartType].prototype.computeDiff(\n oldData,\n newData\n );\n }\n if (data !== null) {\n if (Array.isArray(data)) {\n dataTable = google.visualization.arrayToDataTable(data);\n } else {\n dataTable = new google.visualization.DataTable(data);\n }\n } else if (rows && columns) {\n dataTable = google.visualization.arrayToDataTable([columns, ...rows]);\n } else if (spreadSheetUrl) {\n dataTable = (await loadDataTableFromSpreadSheet(\n google,\n spreadSheetUrl,\n spreadSheetQueryParameters\n )) as GoogleDataTable;\n } else {\n dataTable = google.visualization.arrayToDataTable([]);\n }\n const columnCount = dataTable.getNumberOfColumns();\n for (let i = 0; i < columnCount; i += 1) {\n const columnID = this.getColumnID(dataTable, i);\n if (this.state.hiddenColumns.includes(columnID)) {\n const previousColumnLabel = dataTable.getColumnLabel(i);\n const previousColumnID = dataTable.getColumnId(i);\n const previousColumnType = dataTable.getColumnType(i);\n dataTable.removeColumn(i);\n dataTable.addColumn({\n label: previousColumnLabel,\n id: previousColumnID,\n type: previousColumnType,\n });\n }\n }\n const chart = googleChartWrapper.getChart();\n if (googleChartWrapper.getChartType() === \"Timeline\") {\n chart && chart.clearChart();\n }\n googleChartWrapper.setChartType(chartType);\n googleChartWrapper.setOptions(options || {});\n googleChartWrapper.setDataTable(dataTable);\n googleChartWrapper.draw();\n if (this.props.googleChartDashboard !== null) {\n this.props.googleChartDashboard.draw(dataTable);\n }\n\n if (chartDiff) {\n googleChartWrapper.setDataTable(chartDiff);\n googleChartWrapper.draw();\n }\n if (formatters) {\n this.applyFormatters(dataTable, formatters);\n googleChartWrapper.setDataTable(dataTable);\n googleChartWrapper.draw();\n }\n if (legendToggle === true || legend_toggle === true) {\n this.grayOutHiddenColumns({ options });\n }\n return;\n };\n private grayOutHiddenColumns = ({\n options,\n }: {\n options: ReactGoogleChartProps[\"options\"];\n }) => {\n const { googleChartWrapper } = this.props;\n const dataTable = googleChartWrapper.getDataTable();\n if (!dataTable) return;\n const columnCount = dataTable.getNumberOfColumns();\n const hasAHiddenColumn = this.state.hiddenColumns.length > 0;\n if (hasAHiddenColumn === false) return;\n const colors = Array.from({ length: columnCount - 1 }).map(\n (dontcare, i) => {\n const columnID = this.getColumnID(dataTable, i + 1);\n if (this.state.hiddenColumns.includes(columnID)) {\n return GRAY_COLOR;\n } else if (options && options.colors) {\n return options.colors[i];\n } else {\n return DEFAULT_CHART_COLORS[i];\n }\n }\n );\n googleChartWrapper.setOptions({\n ...options,\n colors,\n });\n googleChartWrapper.draw();\n };\n private onResize = () => {\n const { googleChartWrapper } = this.props;\n googleChartWrapper.draw();\n };\n componentDidMount() {\n this.draw(this.props);\n window.addEventListener(\"resize\", this.onResize);\n if (this.props.legend_toggle || this.props.legendToggle) {\n this.listenToLegendToggle();\n }\n }\n\n componentWillUnmount() {\n const { google, googleChartWrapper } = this.props;\n window.removeEventListener(\"resize\", this.onResize);\n google.visualization.events.removeAllListeners(googleChartWrapper);\n if (googleChartWrapper.getChartType() === \"Timeline\") {\n googleChartWrapper.getChart() &&\n googleChartWrapper.getChart().clearChart();\n }\n }\n\n componentDidUpdate() {\n this.draw(this.props);\n }\n render() {\n return null;\n }\n}\n\nexport class GoogleChartDataTable extends React.Component<GoogleChartDataTableProps> {\n componentDidMount() {}\n\n componentWillUnmount() {}\n shouldComponentUpdate() {\n return false;\n }\n render() {\n const { google, googleChartWrapper, googleChartDashboard } = this.props;\n return (\n <ContextConsumer\n render={(props) => {\n return (\n <GoogleChartDataTableInner\n {...props}\n google={google}\n googleChartWrapper={googleChartWrapper}\n googleChartDashboard={googleChartDashboard}\n />\n );\n }}\n />\n );\n }\n}\n","import * as React from \"react\";\nimport {\n GoogleViz,\n GoogleChartWrapper,\n ReactGoogleChartProps,\n ReactGoogleChartEvent,\n} from \"../types\";\n\nimport { ContextConsumer } from \"../Context\";\n\nexport type ChartDrawArgs = {\n data: ReactGoogleChartProps[\"data\"];\n};\n\nexport interface Props {\n googleChartWrapper: GoogleChartWrapper;\n google: GoogleViz;\n}\n\nexport interface ListenToEventsArgs {\n googleChartWrapper: GoogleChartWrapper;\n google: GoogleViz;\n chartEvents: ReactGoogleChartEvent[] | null;\n}\n\nexport class GoogleChartEvents extends React.Component<Props> {\n propsFromContext: ReactGoogleChartProps | null;\n shouldComponentUpdate() {\n return false;\n }\n listenToEvents({\n chartEvents,\n google,\n googleChartWrapper,\n }: ListenToEventsArgs) {\n if (!chartEvents) {\n return;\n }\n google.visualization.events.removeAllListeners(googleChartWrapper);\n for (let event of chartEvents) {\n const { eventName, callback } = event;\n google.visualization.events.addListener(\n googleChartWrapper,\n eventName,\n (...args: any[]) => {\n callback({\n chartWrapper: googleChartWrapper,\n props: this.props as any,\n google: google,\n eventArgs: args,\n });\n }\n );\n }\n }\n\n componentDidMount() {\n const { google, googleChartWrapper } = this.props;\n\n this.listenToEvents({\n chartEvents: this.propsFromContext?.chartEvents || null,\n google,\n googleChartWrapper,\n });\n }\n\n render() {\n const { google, googleChartWrapper } = this.props;\n return (\n <ContextConsumer\n render={(propsFromContext) => {\n this.propsFromContext = propsFromContext;\n return null;\n }}\n />\n );\n }\n\n constructor(props: Props) {\n super(props);\n this.propsFromContext = null;\n }\n}\n","import * as React from \"react\";\nimport {\n GoogleViz,\n GoogleChartWrapper,\n ReactGoogleChartProps,\n GoogleChartControlProp,\n GoogleChartControl,\n GoogleChartDashboard,\n GoogleChartEditor,\n} from \"../types\";\nimport { generateUniqueID } from \"../generate-unique-id\";\nimport { GoogleChartDataTable } from \"./GoogleChartDataTable\";\nimport { GoogleChartEvents } from \"./GoogleChartEvents\";\n\nexport type Props = {\n google: GoogleViz;\n graphID?: string | null;\n graph_id?: string | null;\n options?: ReactGoogleChartProps[\"options\"];\n chartWrapperParams?: {};\n chartType: ReactGoogleChartProps[\"chartType\"];\n width?: ReactGoogleChartProps[\"width\"];\n height?: ReactGoogleChartProps[\"height\"];\n style?: ReactGoogleChartProps[\"style\"];\n className?: ReactGoogleChartProps[\"className\"];\n rootProps?: ReactGoogleChartProps[\"rootProps\"];\n} & ReactGoogleChartProps;\n\nexport interface State {\n googleChartWrapper: GoogleChartWrapper | null;\n isReady: boolean;\n googleChartDashboard: GoogleChartDashboard | null;\n googleChartEditor: GoogleChartEditor | null;\n googleChartControls:\n | { control: GoogleChartControl; controlProp: GoogleChartControlProp }[]\n | null;\n}\n\nlet controlCounter = 0;\n\nexport class GoogleChart extends React.Component<Props, State> {\n state = {\n googleChartWrapper: null,\n googleChartDashboard: null,\n googleChartControls: null,\n googleChartEditor: null,\n isReady: false,\n } as State;\n graphID: null | string = null;\n private dashboard_ref: React.RefObject<HTMLDivElement> = React.createRef();\n private toolbar_ref: React.RefObject<HTMLDivElement> = React.createRef();\n private getGraphID = () => {\n const { graphID, graph_id } = this.props;\n let instanceGraphID: string;\n if (!graphID && !graph_id) {\n if (!this.graphID) {\n instanceGraphID = generateUniqueID();\n } else {\n instanceGraphID = this.graphID;\n }\n } else if (graphID && !graph_id) {\n instanceGraphID = graphID as string;\n } else if (graph_id && !graphID) {\n instanceGraphID = graph_id as string;\n } else {\n instanceGraphID = graphID as string;\n }\n this.graphID = instanceGraphID;\n return this.graphID as string;\n };\n private getControlID = (id: undefined | string, index: number) => {\n controlCounter += 1;\n let controlID: string;\n if (typeof id === \"undefined\") {\n controlID = `googlechart-control-${index}-${controlCounter}`;\n } else {\n controlID = id;\n }\n return controlID;\n };\n\n addControls = (\n googleChartWrapper: GoogleChartWrapper,\n googleChartDashboard: GoogleChartDashboard\n ) => {\n const { google, controls } = this.props;\n\n const googleChartControls = !controls\n ? null\n : controls.map((control, i) => {\n const {\n controlID: controlIDMaybe,\n controlType,\n options: controlOptions,\n controlWrapperParams,\n } = control;\n const controlID = this.getControlID(controlIDMaybe, i);\n return {\n controlProp: control,\n control: new google.visualization.ControlWrapper({\n containerId: controlID,\n controlType,\n options: controlOptions,\n ...controlWrapperParams,\n }),\n };\n });\n if (!googleChartControls) {\n return null;\n }\n googleChartDashboard.bind(\n googleChartControls.map(({ control }) => control),\n googleChartWrapper\n );\n for (let chartControl of googleChartControls) {\n const { control, controlProp } = chartControl;\n const { controlEvents = [] } = controlProp;\n for (let event of controlEvents) {\n const { callback, eventName } = event;\n google.visualization.events.removeListener(\n control,\n eventName,\n callback\n );\n google.visualization.events.addListener(\n control,\n eventName,\n (...args: any[]) => {\n callback({\n chartWrapper: googleChartWrapper,\n controlWrapper: control,\n props: this.props as any,\n google: google,\n eventArgs: args,\n });\n }\n );\n }\n }\n return googleChartControls;\n };\n\n componentDidMount() {\n const {\n options,\n google,\n chartType,\n chartWrapperParams,\n toolbarItems,\n getChartEditor,\n getChartWrapper,\n } = this.props;\n\n const chartConfig = {\n chartType,\n options,\n containerId: this.getGraphID(),\n ...chartWrapperParams,\n };\n const googleChartWrapper = new google.visualization.ChartWrapper(\n chartConfig\n );\n googleChartWrapper.setOptions(options || {});\n if (getChartWrapper) {\n getChartWrapper(googleChartWrapper, google);\n }\n const googleChartDashboard = new google.visualization.Dashboard(\n this.dashboard_ref\n );\n\n const googleChartControls = this.addControls(\n googleChartWrapper,\n googleChartDashboard\n );\n if (toolbarItems) {\n google.visualization.drawToolbar(\n this.toolbar_ref.current as HTMLDivElement,\n toolbarItems\n );\n }\n let googleChartEditor: null | GoogleChartEditor = null;\n if (getChartEditor) {\n googleChartEditor = new google.visualization.ChartEditor();\n getChartEditor({\n chartEditor: googleChartEditor,\n chartWrapper: googleChartWrapper,\n google,\n });\n }\n\n this.setState({\n googleChartEditor,\n googleChartControls: googleChartControls,\n googleChartDashboard: googleChartDashboard,\n googleChartWrapper,\n isReady: true,\n });\n }\n componentDidUpdate() {\n if (!this.state.googleChartWrapper) return;\n if (!this.state.googleChartDashboard) return;\n if (!this.state.googleChartControls) return;\n\n const { controls } = this.props;\n if (controls) {\n for (let i = 0; i < controls.length; i += 1) {\n const { controlType, options, controlWrapperParams } = controls[i];\n if (controlWrapperParams && \"state\" in controlWrapperParams) {\n this.state.googleChartControls[i].control.setState(\n controlWrapperParams[\"state\"]\n );\n }\n this.state.googleChartControls[i].control.setOptions(options);\n this.state.googleChartControls[i].control.setControlType(controlType);\n }\n }\n }\n shouldComponentUpdate(nextProps: Props, nextState: State) {\n return (\n this.state.isReady !== nextState.isReady ||\n nextProps.controls !== this.props.controls\n );\n }\n renderChart = () => {\n const { width, height, options, style, className, rootProps, google } =\n this.props;\n\n const divStyle = {\n height: height || (options && options.height),\n width: width || (options && options.width),\n ...style,\n };\n return (\n <div\n id={this.getGraphID()}\n style={divStyle}\n className={className}\n {...rootProps}\n >\n {this.state.isReady && this.state.googleChartWrapper !== null ? (\n <React.Fragment>\n <GoogleChartDataTable\n googleChartWrapper={this.state.googleChartWrapper}\n google={google}\n googleChartDashboard={this.state.googleChartDashboard}\n />\n <GoogleChartEvents\n googleChartWrapper={this.state.googleChartWrapper}\n google={google}\n />\n </React.Fragment>\n ) : null}\n </div>\n );\n };\n renderControl = (\n filter = ({\n control,\n controlProp,\n }: {\n control: GoogleChartControl;\n controlProp: GoogleChartControlProp;\n }) => true\n ) => {\n return this.state.isReady && this.state.googleChartControls !== null ? (\n <React.Fragment>\n {this.state.googleChartControls\n .filter(({ controlProp, control }) => {\n return filter({ control, controlProp });\n })\n .map(({ control, controlProp }) => {\n return (\n <div\n key={control.getContainerId()}\n id={control.getContainerId()}\n />\n );\n })}\n </React.Fragment>\n ) : null;\n };\n renderToolBar = () => {\n if (!this.props.toolbarItems) return null;\n return <div ref={this.toolbar_ref} />;\n };\n render() {\n const { width, height, options, style } = this.props;\n\n const divStyle = {\n height: height || (options && options.height),\n width: width || (options && options.width),\n ...style,\n };\n if (this.props.render) {\n return (\n <div ref={this.dashboard_ref} style={divStyle}>\n <div ref={this.toolbar_ref} id=\"toolbar\" />\n {this.props.render({\n renderChart: this.renderChart,\n renderControl: this.renderControl,\n renderToolbar: this.renderToolBar,\n })}\n </div>\n );\n } else {\n return (\n <div ref={this.dashboard_ref} style={divStyle}>\n {this.renderControl(({ controlProp }) => {\n return controlProp.controlPosition !== \"bottom\";\n })}\n {this.renderChart()}\n {this.renderControl(({ controlProp }) => {\n return controlProp.controlPosition === \"bottom\";\n })}\n {this.renderToolBar()}\n </div>\n );\n }\n }\n}\n","import * as React from \"react\";\n\nimport {\n GoogleViz,\n ReactGoogleChartProps,\n ReactGoogleChartState,\n} from \"./types\";\nimport { LoadGoogleCharts } from \"./hooks\";\nimport { chartDefaultProps } from \"./default-props\";\nimport { GoogleChart } from \"./components/GoogleChart\";\nimport { ContextProvider } from \"./Context\";\n\nexport class Chart extends React.Component<\n ReactGoogleChartProps,\n ReactGoogleChartState\n> {\n _isMounted = false;\n\n state = {\n loadingStatus: \"loading\" as ReactGoogleChartState[\"loadingStatus\"],\n google: null as ReactGoogleChartState[\"google\"],\n };\n\n static defaultProps = chartDefaultProps;\n\n render() {\n const {\n chartLanguage,\n chartPackages,\n chartVersion,\n mapsApiKey,\n loader,\n errorElement,\n } = this.props;\n return (\n <ContextProvider value={this.props as ReactGoogleChartProps}>\n {this.state.loadingStatus === \"ready\" && this.state.google !== null ? (\n <GoogleChart\n {...(this.props as ReactGoogleChartProps)}\n google={this.state.google}\n />\n ) : this.state.loadingStatus === \"errored\" && errorElement ? (\n errorElement\n ) : (\n loader\n )}\n <LoadGoogleCharts\n chartLanguage={chartLanguage}\n chartPackages={chartPackages}\n chartVersion={chartVersion}\n mapsApiKey={mapsApiKey}\n onLoad={this.onLoad}\n onError={this.onError}\n />\n </ContextProvider>\n );\n }\n\n componentDidMount() {\n this._isMounted = true;\n }\n\n componentWillUnmount() {\n this._isMounted = false;\n }\n\n onLoad = (google: GoogleViz) => {\n if (this.props.onLoad) {\n this.props.onLoad(google);\n }\n if (this.isFullyLoaded(google)) {\n this.onSuccess(google);\n } else {\n // IE11: window.google is not fully set, we have to wait\n const id = setInterval(() => {\n const google = (\n window as Window & {\n google?: GoogleViz;\n }\n ).google;\n\n if (this._isMounted) {\n if (google && this.isFullyLoaded(google)) {\n clearInterval(id);\n this.onSuccess(google);\n }\n } else {\n clearInterval(id);\n }\n }, 1000);\n }\n };\n\n onSuccess = (google: GoogleViz) => {\n this.setState({\n loadingStatus: \"ready\",\n google,\n });\n };\n\n onError = () => {\n this.setState({\n loadingStatus: \"errored\",\n });\n };\n\n isFullyLoaded(google: GoogleViz) {\n const { controls, toolbarItems, getChartEditor } = this.props;\n\n return (\n google &&\n google.visualization &&\n google.visualization.ChartWrapper &&\n google.visualization.Dashboard &&\n (!controls || google.visualization.ChartWrapper) &&\n (!getChartEditor || google.visualization.ChartEditor) &&\n (!toolbarItems || google.visualization.drawToolbar)\n );\n }\n}\n\nexport default Chart;\n","// Complete Google Charts Type Definition : https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/google.visualization/index.d.ts\n\nexport type GoogleVizDrawToolbar = (\n toolbarContainer: HTMLDivElement,\n components: GoogleChartToolbarItem[]\n) => any;\n\nexport type GoogleViz = {\n charts: GoogleChartLoader;\n visualization: {\n ChartWrapper: GoogleChartWrapper;\n ChartEditor: GoogleChartEditor;\n DataTable: GoogleDataTable;\n events: GoogleVizEvents;\n arrayToDataTable: GoogleArrayToDataTable;\n drawToolbar: GoogleVizDrawToolbar;\n [otherKeys: string]: any;\n };\n};\n\nexport type GoogleChartTicks = (number | Date)[];\n\nexport type GoogleChartEditor = {\n new (): GoogleChartEditor;\n openDialog: (\n chartWrapper: GoogleChartWrapper,\n chartEditorOptions?: { dataSourceInput?: any; [otherKeyMaybe: string]: any }\n ) => null;\n getChartWrapper: () => GoogleChartWrapper;\n setChartWrapper: (chartWrapper: GoogleChartWrapper) => GoogleChartWrapper;\n closeDialog: () => null;\n};\n\nexport type GoogleChartLoaderOptions = {\n packages?: GoogleChartPackages[];\n language?: string;\n mapsApiKey?: string;\n};\nexport type GoogleChartLoader = {\n load: (\n version: GoogleChartVersion,\n googleChartOptions: GoogleChartLoaderOptions\n ) => void;\n setOnLoadCallback: (callback: () => void) => void;\n};\nexport interface ChartWrapperProps {\n chartType: GoogleChartWrapperChartType;\n containerId?: string;\n options?: {\n width?: number;\n height?: number;\n is3D?: boolean;\n title?: string;\n backgroundColor: string;\n };\n dataTable?: {};\n dataSourceUrl?: string;\n query?: string;\n refreshInterval?: number;\n view?: any[] | {};\n render?: (props: ChartWrapperProps, chartWrapper: GoogleChartWrapper) => any;\n children?: (\n props: ChartWrapperProps,\n chartWrapper: GoogleChartWrapper\n ) => any;\n}\n\nexport type VizEventsProps = {\n chartWrapper: GoogleChartWrapper;\n onReady?: (chartWrapper: GoogleChartWrapper) => any;\n onError?: (chartWrapper: GoogleChartWrapper) => any;\n onSelect?: (selection: Array<{ row?: any; column?: any }>) => any;\n render?: (props: VizEventsProps, chartWrapper: GoogleChartWrapper) => any;\n children?: (props: VizEventsProps, chartWrapper: GoogleChartWrapper) => any;\n};\n\n/*\n *\n * <GoogleChartsTypes>\n *\n */\n\n/*\n *\n * Reference + Docs:\n * https://developers.google.com/chart/interactive/docs/reference#constructor_3\n * https://developers.google.com/chart/interactive/docs/reference#google.visualization.drawchart\n *\n */\nexport type GoogleChartWrapperChartType =\n | \"AnnotationChart\"\n | \"AreaChart\"\n | \"BarChart\"\n | \"BubbleChart\"\n | \"Calendar\"\n | \"CandlestickChart\"\n | \"ColumnChart\"\n | \"ComboChart\"\n | \"DiffChart\"\n | \"DonutChart\"\n | \"Gantt\"\n | \"Gauge\"\n | \"GeoChart\"\n | \"Histogram\"\n | \"LineChart\"\n | \"Line\"\n | \"Bar\"\n | \"Map\"\n | \"OrgChart\"\n | \"PieChart\"\n | \"Sankey\"\n | \"ScatterChart\"\n | \"Scatter\"\n | \"SteppedAreaChart\"\n | \"Table\"\n | \"Timeline\"\n | \"TreeMap\"\n | \"WaterfallChart\"\n | \"WordTree\";\n\n// https://developers.google.com/chart/interactive/docs/reference#google.visualization.drawchart\nexport interface ChartWrapperOptions {\n chartType: string;\n containerId: string;\n options: Partial<{\n width: number;\n height: number;\n is3D: boolean;\n title: string;\n backgroundColor: string;\n hAxis?: {\n minValue?: any;\n maxValue?: any;\n ticks?: GoogleChartTicks;\n title?: string;\n viewWindow?: { max?: any; min?: any };\n [otherOptionKey: string]: any;\n };\n vAxis?: {\n minValue?: any;\n maxValue?: any;\n ticks?: GoogleChartTicks;\n title?: string;\n viewWindow?: { max?: any; min?: any };\n [otherOptionKey: string]: any;\n };\n legend: any;\n colors: string[];\n [otherOptionKey: string]: any;\n }>;\n dataTable?: GoogleDataTable;\n dataSourceUrl?: string;\n query?: string;\n refreshInterval?: number;\n view: any[] | {};\n [otherOptionKey: string]: any;\n}\n\nexport type GoogleChartAction = {\n id: string;\n text: string;\n action: (chartWrapper: GoogleChartWrapper) => void;\n};\n\nexport type GoogleChartControlProp = {\n controlType:\n | \"CategoryFilter\"\n | \"ChartRangeFilter\"\n | \"DateRangeFilter\"\n | \"NumberRangeFilter\"\n | \"StringFilter\";\n options: {};\n controlWrapperParams?: {};\n controlID?: string;\n controlPosition?: \"top\" | \"bottom\";\n controlEvents?: ReactGoogleChartEvent[];\n};\n\nexport type GoogleChartWrapper = {\n new (chartWrapperOptions: Partial<ChartWrapperOptions>): GoogleChartWrapper;\n draw: (chartArgs?: ChartWrapperProps) => any;\n toJSON: () => string;\n clone: () => GoogleChartWrapper;\n getDataSourceUrl: () => string;\n getDataTable: () => GoogleDataTable | null; // null if datasourceurl set or ref to DataTable\n getChartType: () => GoogleChartWrapperChartType;\n getChartName: () => string;\n getChart: () => {\n removeAction: (actionID: string) => void;\n getSelection: () => { row?: any; column?: any }[];\n setAction: (ChartAction: GoogleChartAction) => void;\n getImageURI: () => void;\n clearChart: () => void; // Clears the chart, and releases all of its allocated resources.\n }; // ref to chart\n getContainerId: () => string;\n getQuery: () => string;\n getRefreshInterval: () => number;\n getOption: (key: string, opt_default_value?: any) => any; // returns opt_default_value if key not found\n getOptions: () => {};\n getSelection: () => { row?: any; column?: any }[];\n getView: () => {} | any[]; // Same format as toJSON\n\n setDataSourceUrl: (url: string) => void;\n setDataTable: (table: any) => void;\n setChartType: (chartType: GoogleChartWrapperChartType) => void;\n setChartName: (name: string) => void; // Sets an arbitrary name for the chart. This is not shown anywhere on the chart, unless a custom chart is explicitly designed to use it.\n setContainerId: (id: string) => void; // Sets the ID of the containing DOM element for the chart.\n setQuery: (query_string: string) => void; // Sets a query string, if this chart queries a data source. You must also set the data source URL if specifying this value.\n setRefreshInterval: (interval: number) => void; // Sets the refresh interval for this chart, if it queries a data source. You must also set a data source URL if specifying this value. Zero indicates no refresh.\n setOption: (key: string, value: any) => void; // \tSets a single chart option value, where key is the option name and value is the value. To unset an option, pass in null for the value. Note that key may be a qualified name, such as 'vAxis.title'.\n setOptions: (options_obj: Partial<ChartWrapperOptions[\"options\"]>) => void; //\n};\n\nexport type GoogleVizEventName =\n | \"ready\"\n | \"error\"\n | \"select\"\n | \"animationfinish\"\n | \"statechange\"\n | \"ok\"\n | \"cancel\"\n | \"animationstart\";\n\nexport type GoogleVizEvents = {\n addListener: (\n chartWrapper: GoogleChartWrapper | GoogleChartControl | GoogleChartEditor,\n name: GoogleVizEventName,\n onEvent: (chartWrapper: GoogleChartWrapper) => any\n ) => any;\n removeListener: (\n chartWrapper: GoogleChartWrapper,\n name: GoogleVizEventName,\n callback: Function\n ) => any;\n removeAllListeners: (chartWrapper: GoogleChartWrapper) => any;\n};\n\nexport type GoogleChartPackages =\n | \"corechart\"\n | \"charteditor\"\n | \"controls\"\n | \"calendar\"\n | \"gantt\"\n | \"gauge\"\n | \"geochart\"\n | \"map\"\n | \"orgchart\"\n | \"sankey\"\n | \"table\"\n | \"timeline\"\n | \"treemap\"\n | \"wordtree\";\n\nexport type GoogleChartVersion = \"current\" | \"upcoming\";\n\nexport type GoogleDataTableColumnType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"timeofday\";\n\n// export type GoogleDataTable = {\n// addColumn: (type: GoogleDataTableColumnType) => number;\n// };\n\n// Reference https://developers.google.com/chart/interactive/docs/roles\nexport enum GoogleDataTableColumnRoleType {\n annotation = \"annotation\",\n annotationText = \"annotationText\",\n certainty = \"certainty\",\n emphasis = \"emphasis\",\n interval = \"interval\",\n scope = \"scope\",\n style = \"style\",\n tooltip = \"tooltip\",\n domain = \"domain\",\n}\n\nexport type GoogleDataTableColumn =\n | {\n type: GoogleDataTableColumnType;\n label?: string; // A label for the column.\n role?: GoogleDataTableColumnRoleType;\n pattern?: string;\n p?: {};\n id?: string;\n }\n | string;\n\n// Ref : https://developers.google.com/chart/interactive/docs/reference#dataparam\n\nexport type GoogleDataTableCell =\n | {\n v?: any; // The cell value. Type should match DataTableColumn type field\n f?: string; // A string version of the v value, formatted for display.\n p?: {};\n }\n | string\n | number\n | boolean\n | Date;\n\nexport type GoogleDataTableRow = GoogleDataTableCell[];\n\nexport type GoogleDataTableJS = {\n cols: GoogleDataTableColumn[];\n rows: {\n c: GoogleDataTableRow;\n }[];\n p?: {};\n};\n\n// Reference : https://developers.google.com/chart/interactive/docs/reference#DataTable\n\nexport type GoogleDataTableRowFilter = {\n column: number;\n value: any;\n minValue?: any;\n maxValue?: any;\n};\n\nexport type GoogleDataTableSortColumns =\n | number\n | {\n column: number;\n desc: boolean;\n }\n | number[]\n | {\n column: number;\n desc: boolean;\n }[];\n\nexport type GoogleDataTable = {\n // https://developers.google.com/chart/interactive/docs/reference#dataparam\n new (dataParam: any): GoogleDataTable;\n addColumn: (column: GoogleDataTableColumn) => number;\n addRow: (row?: GoogleDataTableRow) => number;\n addRows: (rows?: GoogleDataTableRow[] | number[] | any[]) => number;\n clone: () => GoogleDataTable;\n\n getColumnId: (columnIndex: number) => string;\n getColumnLabel: (columnIndex: number) => string;\n getColumnPattern: (columnIndex: number) => string;\n getColumnProperties: (columnIndex: number) => {};\n getColumnProperty: (columnIndex: number, name: string) => any;\n getColumnRange: (columnIndex: number) => {\n min: number | null;\n max: number | null;\n };\n getColumnRole: (columnIndex: number) => GoogleDataTableColumnRoleType;\n getColumnType: (columnIndex: number) => GoogleDataTableColumnType;\n getDistinctValues: (columnIndex: number) => any[];\n getFilteredRows: (filters: GoogleDataTableRowFilter[]) => number[];\n getFormattedValue: (rowIndex: number, columnIndex: number) => string;\n getNumberOfColumns: () => number;\n getNumberOfRows: () => number;\n getProperties: (rowIndex: number, columnIndex: number) => {};\n getProperty: (rowIndex: number, columnIndex: number, name: string) => any;\n getRowProperties: (rowIndex: number) => {};\n getRowProperty: (rowIndex: number, name: string) => any;\n getSortedRows: (sortColumns: GoogleDataTableSortColumns) => number[];\n getTableProperties: () => {};\n getTableProperty: (name: string) => any;\n getValue: (\n rowIndex: number,\n columnIndex: number\n ) => boolean | string | number | Date | number[] | null;\n insertColumn: (\n columnIndex: number,\n type: GoogleDataTableColumnType,\n label?: string,\n id?: string\n ) => void;\n insertRows: (\n rowIndex: number,\n numberOrArray: GoogleDataTableRow[] | number\n ) => void;\n removeColumn: (columnIndex: number) => void;\n removeColumns: (columnIndex: number, numberOfColumns: number) => void;\n removeRow: (rowIndex: number) => void;\n removeRows: (rowIndex: number, numberOfColumns: number) => void;\n setCell: (\n rowIndex: number,\n columnIndex: number,\n value?: any,\n formattedValue?: string,\n properties?: {}\n ) => {};\n setColumnLabel: (columnIndex: number, label: string) => void;\n setColumnProperty: (columnIndex: number, name: string, value: any) => void;\n setColumnProperties: (columnIndex: number, properties: {} | null) => void;\n setFormattedValue: (\n rowIndex: number,\n columnIndex: number,\n formattedValue: string\n ) => void;\n setProperty: (\n rowIndex: number,\n columnIndex: number,\n name: string,\n value: any\n ) => void;\n setProperties: (\n rowIndex: number,\n columnIndex: number,\n properties: {} | null\n ) => void;\n\n setRowProperty: (rowIndex: number, name: string, value: any) => void;\n setRowProperties: (rowIndex: number, properties: {} | null) => void;\n setTableProperties: (properties: {} | null) => void;\n setValue: (rowIndex: number, columnIndex: number, value: string) => void;\n sort: (sortColumns: GoogleDataTableSortColumns) => void;\n toJSON: () => string; // GoogleDataTableJS\n};\n\nexport type GoogleArrayToDataTable = (\n data: any[][],\n isFirstRowLabels?: boolean\n) => GoogleDataTable;\n\nexport type GoogleChartOptions = {\n width?: number;\n height?: number;\n is3D?: boolean;\n backgroundColor: string;\n\n title?: string;\n hAxis?: {\n minValue?: any;\n maxValue?: any;\n ticks?: GoogleChartTicks;\n title?: string;\n viewWindow?: { max?: any; min?: any; [otherOptionKey: string]: any };\n [otherOptionKey: string]: any;\n };\n vAxis?: {\n minValue?: any;\n maxValue?: any;\n ticks?: GoogleChartTicks;\n title?: string;\n viewWindow?: { max?: any; min?: any; [otherOptionKey: string]: any };\n [otherOptionKey: string]: any;\n };\n bubble?: {};\n pieHole?: number;\n redFrom?: number;\n redTo?: number;\n yellowFrom?: number;\n yellowTo?: number;\n minorTicks?: number;\n legend?:\n | string\n | {\n position?: string;\n maxLines?: number;\n [otherOptionKey: string]: any;\n };\n curveType?: string;\n showTooltip?: boolean;\n showInfoWindow?: boolean;\n allowHtml?: boolean;\n isStacked?: string | boolean;\n minColor?: string;\n midColor?: string;\n maxColor?: string;\n headerHeight?: number;\n fontColor?: string;\n showScale?: boolean;\n bar?: { groupWidth?: string }; // Remove space between bars.\n candlestick?: {\n fallingColor?: { strokeWidth?: number; fill?: string }; // red\n risingColor?: { strokeWidth?: number; fill?: string }; // green\n [otherOptionKey: string]: any;\n };\n wordtree?: {\n format?: string;\n word?: string;\n [otherOptionKey: string]: any;\n };\n [otherOptionKey: string]: any;\n};\n\n/*\n *\n * </GoogleChartsTypes>\n *\n */\n\nexport type WindowWithMaybeGoogle = Window & { google?: any };\n\nexport type ReactGoogleChartEvent = {\n eventName: GoogleVizEventName;\n callback: (eventCallbackArgs: {\n chartWrapper: GoogleChartWrapper;\n controlWrapper?: GoogleChartControl;\n props: ReactGoogleChartProps;\n google: GoogleViz;\n eventArgs: any;\n }) => void;\n};\n\nexport type GoogleChartToolbarItem = {\n type: \"igoogle\" | \"html\" | \"csv\" | \"htmlcode\";\n datasource: string;\n gadget?: string;\n userPrefs?: {\n \"3d\": number;\n [otherKeyMaybe: string]: any;\n };\n};\n\nexport type ReactGoogleChartProps = {\n height?: string | number;\n width?: string | number;\n graphID?: string;\n chartType: GoogleChartWrapperChartType;\n diffdata?: {\n old: any;\n new: any;\n };\n options?: ChartWrapperOptions[\"options\"];\n loader?: JSX.Element;\n errorElement?: JSX.Element;\n data?: any[] | {};\n rows?: GoogleDataTableRow[];\n columns?: GoogleDataTableColumn[];\n chartActions?: GoogleChartAction[];\n chartEvents?: ReactGoogleChartEvent[];\n chartVersion?: GoogleChartVersion;\n chartPackages?: GoogleChartPackages[];\n chartLanguage?: string;\n mapsApiKey?: string;\n graph_id?: string;\n legendToggle?: boolean;\n legend_toggle?: boolean;\n onLoad?: (google: GoogleViz) => void;\n getChartWrapper?: (\n chartWrapper: GoogleChartWrapper,\n google: GoogleViz\n ) => void;\n getChartEditor?: (args: {\n chartEditor: GoogleChartEditor;\n chartWrapper: GoogleChartWrapper;\n google: GoogleViz;\n }) => void;\n className?: string;\n style?: React.CSSProperties;\n formatters?: {\n column: number | number[];\n type:\n | \"ArrowFormat\"\n | \"BarFormat\"\n | \"ColorFormat\"\n | \"DateFormat\"\n | \"NumberFormat\"\n | \"PatternFormat\";\n options?: {};\n }[];\n spreadSheetUrl?: string;\n spreadSheetQueryParameters?: {\n headers: number;\n gid?: number | string;\n sheet?: string;\n query?: string;\n access_token?: string;\n };\n rootProps?: any;\n controls?: GoogleChartControlProp[];\n render?: ReactGoogleChartDashboardRender;\n //https://developers.google.com/chart/interactive/docs/gallery/toolbar#example_1\n toolbarItems?: GoogleChartToolbarItem[];\n toolbarID?: string;\n chartWrapperParams?: any;\n};\n\nexport type GoogleChartDashboard = {\n draw: (data: GoogleDataTable) => void;\n bind: (\n controlWrapperOrWrappers: GoogleChartControl | GoogleChartControl[],\n chartWrapper: GoogleChartWrapper\n ) => void;\n};\n\nexport type ReactGoogleChartDashboardRender = ({\n renderControl,\n renderChart,\n renderToolbar,\n}: {\n renderControl: (\n filter: ({\n control,\n controlProp,\n }: {\n control: GoogleChartControl;\n controlProp: GoogleChartControlProp;\n }) => boolean\n ) => any;\n renderChart: () => any;\n renderToolbar: () => any;\n}) => any;\nexport type GoogleChartControlOptions = any;\nexport type GoogleChartControl = {\n getContainerId: () => string;\n getOptions: () => GoogleChartControlOptions;\n getState: () => any;\n setState: (state: any) => void;\n setOptions: (options: GoogleChartControlOptions) => void;\n setControlType: (controlType: string) => void;\n};\n\nexport type ReactGoogleChartState = {\n loadingStatus: \"loading\" | \"errored\" | \"ready\";\n google: null | GoogleViz;\n // hiddenColumns: string[];\n};\n\nexport type ReactGoogleChartContext = {\n data: ReactGoogleChartProps[\"data\"];\n rows: ReactGoogleChartProps[\"rows\"] | null;\n columns: ReactGoogleChartProps[\"columns\"] | null;\n diffdata: ReactGoogleChartProps[\"diffdata\"] | null;\n options: ReactGoogleChartProps[\"options\"] | null;\n legend_toggle: ReactGoogleChartProps[\"legend_toggle\"] | null;\n legendToggle: ReactGoogleChartProps[\"legendToggle\"] | null;\n chartType: ReactGoogleChartProps[\"chartType\"] | null;\n formatters: ReactGoogleChartProps[\"formatters\"] | null;\n spreadSheetUrl: ReactGoogleChartProps[\"spreadSheetUrl\"] | null;\n spreadSheetQueryParameters:\n | ReactGoogleChartProps[\"spreadSheetQueryParameters\"]\n | null;\n};\n","import { Chart } from \"./ReactGoogleCharts\";\n\n