Skip to content

Commit

Permalink
feat: Export plotly-express as a dashboard plugin (#329)
Browse files Browse the repository at this point in the history
Tested with DHE V+ (1.20231218.176) Core 0.32.1
Closes #308


BREAKING CHANGE:
- `widget` type in the `PanelEvent.OPEN` event arguments has changed
from `VariableDefinition` to `VariableDescriptor`
  • Loading branch information
vbabich authored Mar 5, 2024
1 parent 6028195 commit 6212bd5
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
77 changes: 77 additions & 0 deletions plugins/plotly-express/src/js/src/DashboardPlugin.tsx
Original file line number Diff line number Diff line change
@@ -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<PlotlyChartWidget>;
metadata?: Record<string, unknown>;
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;
11 changes: 10 additions & 1 deletion plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts
Original file line number Diff line number Diff line change
@@ -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<Table> }[];
addEventListener(
type: string,
fn: (event: CustomEvent<PlotlyChartWidget>) => () => void
): void;
}

export interface PlotlyChartWidgetData {
type: string;
Expand Down
2 changes: 2 additions & 0 deletions plugins/plotly-express/src/js/src/index.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down

0 comments on commit 6212bd5

Please sign in to comment.