import { useState, useMemo, useEffect } from 'react'; import { FieldConfigSource, getTimeZone, PanelPlugin, PluginContextProvider, getPanelOptionsWithDefaults, OptionDefaults, useFieldOverrides, } from '@grafana/data'; import { Trans } from '@grafana/i18n'; import { getTemplateSrv, PanelRendererProps } from '@grafana/runtime'; import { ErrorBoundaryAlert, usePanelContext, useTheme2 } from '@grafana/ui'; import { appEvents } from 'app/core/core'; import { importPanelPlugin, syncGetPanelPlugin } from '../../plugins/importPanelPlugin'; const defaultFieldConfig = { defaults: {}, overrides: [] }; export function PanelRenderer

(props: PanelRendererProps) { const { pluginId, data, timeZone = getTimeZone(), options = {}, width, height, title, onOptionsChange = () => {}, onChangeTimeRange = () => {}, onFieldConfigChange = () => {}, fieldConfig = defaultFieldConfig, } = props; const theme = useTheme2(); const templateSrv = getTemplateSrv(); const replace = useMemo(() => templateSrv.replace.bind(templateSrv), [templateSrv]); const [plugin, setPlugin] = useState(syncGetPanelPlugin(pluginId)); const [error, setError] = useState(); const optionsWithDefaults = useOptionDefaults(plugin, options, fieldConfig); const { dataLinkPostProcessor } = usePanelContext(); const dataWithOverrides = useFieldOverrides( plugin, optionsWithDefaults?.fieldConfig, data, timeZone, theme, replace, dataLinkPostProcessor ); useEffect(() => { // If we already have a plugin and it's correct one do nothing if (plugin && plugin.hasPluginId(pluginId)) { return; } // Async load the plugin importPanelPlugin(pluginId) .then((result) => setPlugin(result)) .catch((err: Error) => { setError(err.message); }); }, [pluginId, plugin]); if (error) { return (

Failed to load plugin: {{ error }}
); } if (!plugin || !plugin.hasPluginId(pluginId)) { return (
Loading plugin panel...
); } if (!plugin.panel) { return (
Seems like the plugin you are trying to load does not have a panel component.
); } if (!dataWithOverrides) { return (
No panel data
); } const PanelComponent = plugin.panel; return ( str} onOptionsChange={onOptionsChange} onFieldConfigChange={onFieldConfigChange} onChangeTimeRange={onChangeTimeRange} eventBus={appEvents} /> ); } function useOptionDefaults

= {}, F extends object = {}>( plugin: PanelPlugin | undefined, options: P, fieldConfig: FieldConfigSource ): OptionDefaults | undefined { return useMemo(() => { if (!plugin) { return; } return getPanelOptionsWithDefaults({ plugin, currentOptions: options, currentFieldConfig: fieldConfig, isAfterPluginChange: false, }); }, [plugin, fieldConfig, options]); }