diff --git a/plugins/plotly-express/src/js/src/DashboardPlugin.tsx b/plugins/plotly-express/src/js/src/DashboardPlugin.tsx new file mode 100644 index 000000000..53b335620 --- /dev/null +++ b/plugins/plotly-express/src/js/src/DashboardPlugin.tsx @@ -0,0 +1,77 @@ +import { useCallback, DragEvent, useEffect } from 'react'; +import shortid from 'shortid'; +import { + DashboardPluginComponentProps, + LayoutUtils, + PanelEvent, + useListener, +} from '@deephaven/dashboard'; +import type { VariableDescriptor } from '@deephaven/jsapi-types'; +import PlotlyExpressChartPanel from './PlotlyExpressChartPanel.js'; +import type { PlotlyChartWidget } from './PlotlyExpressChartUtils.js'; + +export function DashboardPlugin( + props: DashboardPluginComponentProps +): JSX.Element | null { + const { id, layout, registerComponent } = props; + + const handlePanelOpen = useCallback( + async ({ + dragEvent, + fetch, + metadata = {}, + panelId = shortid.generate(), + widget, + }: { + dragEvent?: DragEvent; + fetch: () => Promise; + metadata?: Record; + panelId?: string; + widget: VariableDescriptor; + }) => { + const { type, name } = widget; + if (type !== 'deephaven.plot.express.DeephavenFigure') { + return; + } + + const config = { + type: 'react-component' as const, + component: 'PlotlyPanel', + props: { + localDashboardId: id, + id: panelId, + metadata: { + ...metadata, + ...widget, + figure: name, + }, + fetch, + }, + title: name, + id: panelId, + }; + + const { root } = layout; + LayoutUtils.openComponent({ root, config, dragEvent }); + }, + [id, layout] + ); + + useEffect( + function registerComponentsAndReturnCleanup() { + const cleanups = [ + registerComponent('PlotlyPanel', PlotlyExpressChartPanel), + ]; + return () => { + cleanups.forEach(cleanup => cleanup()); + }; + }, + [registerComponent] + ); + + useListener(layout.eventHub, PanelEvent.OPEN, handlePanelOpen); + + return null; +} + +export default DashboardPlugin; diff --git a/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts b/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts index c2b193f98..c91c66f82 100644 --- a/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts +++ b/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts @@ -1,5 +1,14 @@ import type { Data, PlotlyDataLayoutConfig } from 'plotly.js'; -import type { Widget } from '@deephaven/jsapi-types'; +import type { Table, Widget } from '@deephaven/jsapi-types'; + +export interface PlotlyChartWidget { + getDataAsBase64(): string; + exportedObjects: { fetch(): Promise }[]; + addEventListener( + type: string, + fn: (event: CustomEvent) => () => void + ): void; +} export interface PlotlyChartWidgetData { type: string; diff --git a/plugins/plotly-express/src/js/src/index.ts b/plugins/plotly-express/src/js/src/index.ts index 9d83e0884..312a2bc95 100644 --- a/plugins/plotly-express/src/js/src/index.ts +++ b/plugins/plotly-express/src/js/src/index.ts @@ -1,5 +1,7 @@ import { PlotlyExpressPlugin } from './PlotlyExpressPlugin.js'; +// Export legacy dashboard plugin as named export for backwards compatibility +export * from './DashboardPlugin.js'; export * from './PlotlyExpressChartModel.js'; export * from './PlotlyExpressChartUtils.js';