Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为更多的 echarts Viz 组件添加 rendered 事件支持 #1611

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMemo } from 'react';
import { useDashboardContext } from '~/contexts';
import { PanelRenderBase } from './panel-render-base';
import { PanelVizFeatures } from './panel-viz-features';
Expand All @@ -14,7 +15,7 @@ export interface IClientPanelRenderProps {
*/
export function ClientPanelRender(props: IClientPanelRenderProps) {
const dashboardModel = useDashboardContext();
const panel = dashboardModel.content.panels.findByID(props.panelId);
const panel = useMemo(() => dashboardModel.content.panels.findByID(props.panelId), [props.panelId]);
if (!panel) {
return null;
}
Expand Down
11 changes: 8 additions & 3 deletions dashboard/src/components/panel/plugin-adaptor.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { Text } from '@mantine/core';
import { showNotification } from '@mantine/notifications';
import { useAsyncEffect } from 'ahooks';
import { isEqual } from 'lodash';
import React, { useContext, useEffect, useState } from 'react';
import { MigrationResultType, MigrationStatus } from '~/components/plugins/instance-migrator';
import { useServiceLocator } from '~/components/plugins/service/service-locator/use-service-locator';
import { LayoutStateContext } from '../..';
import { AnyObject, IVizConfig } from '../../types';
import { IPanelInfo, tokens } from '../plugins';
import {
IConfigComponentProps,
IViewComponentProps,
VizConfigComponent,
VizViewComponent,
} from '../plugins/viz-manager/components';
import { AnyObject, IVizConfig } from '../../types';
import { LayoutStateContext } from '../..';

function usePluginMigration(onMigrate?: () => void) {
const [migrated, setMigrated] = useState(false);
Expand Down Expand Up @@ -46,8 +47,12 @@ type SetVizConfType = { setVizConf: (val: React.SetStateAction<IVizConfig['conf'

function useSyncVizConf(setVizConf: SetVizConfType['setVizConf'], panel: IPanelInfo) {
const instance = useServiceLocator().getRequired(tokens.instanceScope.vizInstance);
useAsyncEffect(async () => {
if (!isEqual(await instance.instanceData.getItem(null), panel.viz.conf)) {
await instance.instanceData.setItem(null, panel.viz.conf);
}
}, [instance, panel.viz.conf]);
useEffect(() => {
instance.instanceData.setItem(null, panel.viz.conf);
return instance.instanceData.watchItem<AnyObject>(null, (configData) => {
setVizConf(configData);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NullInteractionManager } from '~/interactions/null-interaction-manager'

export function useConfigVizInstanceService(panel: IPanelInfo, withInteraction = true) {
const { panel: panelModel } = useRenderPanelContext();

return useCallback(
(services: IServiceLocator) => {
const vizManager = services.getRequired(tokens.vizManager);
Expand Down
1 change: 1 addition & 0 deletions dashboard/src/components/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './plugin-context';
export * from './plugin-data-migrator';
export * from './hooks';
export * from './color-manager';
export { onVizRendered, notifyVizRendered } from './viz-components/viz-instance-api';
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,15 @@ import ReactEChartsCore from 'echarts-for-react/lib/core';
import 'echarts-gl';
import * as echarts from 'echarts/core';
import { defaults, get, maxBy, minBy } from 'lodash';
import { useMemo } from 'react';
import { useMemo, useRef } from 'react';
import { useStorageData } from '~/components/plugins/hooks';
import { DefaultVizBox, getBoxContentStyle } from '~/styles/viz-box';
import { VizViewProps } from '~/types/plugin';
import { extractFullQueryData, parseDataKey } from '~/utils';
import { DEFAULT_CONFIG, IBar3dChartConf } from './type';
import { notifyVizRendered } from '~/components/plugins/viz-components/viz-instance-api';

const paddings = {
top: 16,
right: 16,
bottom: 16,
left: 16,
};

export function VizBar3dChart({ context }: VizViewProps) {
export function VizBar3dChart({ context, instance }: VizViewProps) {
const { value: conf } = useStorageData<IBar3dChartConf>(context.instanceData, 'config');
const data = context.data;
const { width, height } = context.viewport;
Expand Down Expand Up @@ -44,6 +38,17 @@ export function VizBar3dChart({ context }: VizViewProps) {
};
}, [queryData, z]);

const echartsInstanceRef = useRef<ReactEChartsCore>(null);
const handleEvents = useMemo(
() => ({
finished: () => {
const chart = echartsInstanceRef.current?.getEchartsInstance();
if (!chart) return;
notifyVizRendered(instance, chart.getOption());
},
}),
[],
);
const option = {
tooltip: {},
backgroundColor: '#fff',
Expand Down Expand Up @@ -103,9 +108,11 @@ export function VizBar3dChart({ context }: VizViewProps) {
<DefaultVizBox width={width} height={height}>
<ReactEChartsCore
echarts={echarts}
ref={echartsInstanceRef}
option={option}
style={getBoxContentStyle(width, height)}
notMerge
onEvents={handleEvents}
theme="merico-light"
/>
</DefaultVizBox>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ReactEChartsCore from 'echarts-for-react/lib/core';
import 'echarts-gl';
import * as echarts from 'echarts/core';
import _, { defaults } from 'lodash';
import { useCallback, useMemo } from 'react';
import { useCallback, useMemo, useRef } from 'react';
import { useStorageData } from '~/components/plugins/hooks';
import { useRowDataMap } from '~/components/plugins/hooks/use-row-data-map';
import { useCurrentInteractionManager, useTriggerSnapshotList } from '~/interactions';
Expand All @@ -12,6 +12,7 @@ import { getOption } from './option';
import { ClickBoxplotSeries } from './triggers';
import { DEFAULT_CONFIG, IBoxplotChartConf, IBoxplotDataItem } from './type';
import { useTranslation } from 'react-i18next';
import { notifyVizRendered } from '~/components/plugins/viz-components/viz-instance-api';

interface IClickBoxplotSeries {
type: 'click';
Expand Down Expand Up @@ -50,11 +51,19 @@ export function VizBoxplotChart({ context, instance }: VizViewProps) {
[rowDataMap, triggers, interactionManager],
);

const echartsInstanceRef = useRef<ReactEChartsCore>(null);
const handleFinished = useCallback(() => {
const chart = echartsInstanceRef.current?.getEchartsInstance();
if (!chart) return;
notifyVizRendered(instance, chart.getOption());
}, []);

const onEvents = useMemo(() => {
return {
click: handleSeriesClick,
finished: handleFinished,
};
}, [handleSeriesClick]);
}, [handleSeriesClick, handleFinished]);

const option = useMemo(() => getOption({ config, data, variables, t }), [config, data, variables, t]);

Expand All @@ -66,6 +75,7 @@ export function VizBoxplotChart({ context, instance }: VizViewProps) {
<ReactEChartsCore
echarts={echarts}
option={option}
ref={echartsInstanceRef}
style={getBoxContentStyle(width, height)}
onEvents={onEvents}
notMerge
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import ReactEChartsCore from 'echarts-for-react/lib/core';
import * as echarts from 'echarts/core';
import _ from 'lodash';
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useMemo, useRef } from 'react';
import { useStorageData } from '~/components/plugins/hooks';
import { useRowDataMap } from '~/components/plugins/hooks/use-row-data-map';
import { useCurrentInteractionManager, useTriggerSnapshotList } from '~/interactions';
import { DefaultVizBox, getBoxContentHeight, getBoxContentWidth } from '~/styles/viz-box';
import { AnyObject } from '~/types';
import { IVizInteractionManager, VizViewProps } from '~/types/plugin';
import { IVizInteractionManager, VizInstance, VizViewProps } from '~/types/plugin';
import { ITemplateVariable } from '~/utils';
import { getOption } from './option';
import { ClickCalendarDate } from './triggers';
import { DEFAULT_CONFIG, ICalendarHeatmapConf } from './type';
import { notifyVizRendered } from '~/components/plugins/viz-components/viz-instance-api';

interface IClickCalendarDate {
type: 'click';
Expand Down Expand Up @@ -40,13 +41,15 @@ function Chart({
height,
interactionManager,
variables,
instance,
}: {
conf: ICalendarHeatmapConf;
data: TPanelData;
width: number;
height: number;
interactionManager: IVizInteractionManager;
variables: ITemplateVariable[];
instance: VizInstance;
}) {
const rowDataMap = useRowDataMap(data, conf.calendar.data_key);

Expand All @@ -65,13 +68,20 @@ function Chart({
},
[rowDataMap, triggers, interactionManager],
);
const echartsInstanceRef = useRef<ReactEChartsCore>(null);
const handleFinished = useCallback(() => {
const chart = echartsInstanceRef.current?.getEchartsInstance();
if (!chart) return;
notifyVizRendered(instance, chart.getOption());
}, [instance]);

const onEvents = useMemo(() => {
return {
click: handleHeatBlockClick,
legendselectchanged: handleLegendSelected,
finished: handleFinished,
};
}, [handleHeatBlockClick]);
}, [handleHeatBlockClick, handleFinished]);

const option = React.useMemo(() => {
return getOption(conf, data, variables);
Expand All @@ -81,6 +91,7 @@ function Chart({
<ReactEChartsCore
echarts={echarts}
option={option}
ref={echartsInstanceRef}
style={{ width, height }}
onEvents={onEvents}
notMerge
Expand Down Expand Up @@ -113,6 +124,7 @@ export function VizCalendarHeatmap({ context, instance }: VizViewProps) {
return (
<DefaultVizBox width={width} height={height}>
<Chart
instance={instance}
variables={variables}
width={getBoxContentWidth(width)}
height={getBoxContentHeight(height)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { getOption } from './option';
import { updateRegressionLinesColor } from './option/events';
import { ClickEchartSeries } from './triggers/click-echart';
import { DEFAULT_CONFIG, ICartesianChartConf } from './type';
import { notifyVizRendered } from '~/components/plugins/viz-components/viz-instance-api';

interface IClickEchartsSeries {
type: 'click';
Expand Down Expand Up @@ -118,7 +119,7 @@ export const VizCartesianChart = observer(({ context, instance }: VizViewProps)
const finalWidth = getBoxContentWidth(width);

function handleChartRenderFinished(chartOptions: unknown) {
instance.messageChannels.getChannel('viz').emit('rendered', chartOptions);
notifyVizRendered(instance, chartOptions);
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,55 @@ import { defaults } from 'lodash';
import React, { useMemo } from 'react';
import { useStorageData } from '~/components/plugins/hooks';
import { DefaultVizBox, getBoxContentHeight, getBoxContentWidth } from '~/styles/viz-box';
import { VizViewProps } from '~/types/plugin';
import { VizInstance, VizViewProps } from '~/types/plugin';
import { getOption } from './option';
import { DEFAULT_CONFIG, IFunnelConf } from './type';
import { notifyVizRendered } from '~/components/plugins/viz-components/viz-instance-api';

function Chart({ conf, data, width, height }: { conf: IFunnelConf; data: TPanelData; width: number; height: number }) {
function Chart({
conf,
data,
width,
height,
instance,
}: {
conf: IFunnelConf;
data: TPanelData;
width: number;
height: number;
instance: VizInstance;
}) {
const option = React.useMemo(() => {
return getOption(conf, data);
}, [conf, data]);

return <ReactEChartsCore echarts={echarts} option={option} style={{ width, height }} notMerge theme="merico-light" />;
const echartsInstanceRef = React.useRef<ReactEChartsCore>(null);
const handleFinished = React.useCallback(() => {
const chart = echartsInstanceRef.current?.getEchartsInstance();
if (!chart) return;
notifyVizRendered(instance, chart.getOption());
}, [instance]);
const onEvents = useMemo(
() => ({
finished: handleFinished,
}),
[handleFinished],
);

return (
<ReactEChartsCore
ref={echartsInstanceRef}
onEvents={onEvents}
echarts={echarts}
option={option}
style={{ width, height }}
notMerge
theme="merico-light"
/>
);
}

export function VizFunnelChart({ context }: VizViewProps) {
export function VizFunnelChart({ context, instance }: VizViewProps) {
const { value: confValue } = useStorageData<IFunnelConf>(context.instanceData, 'config');
const conf = useMemo(() => defaults({}, confValue, DEFAULT_CONFIG), [confValue]);
const data = context.data;
Expand All @@ -28,7 +64,13 @@ export function VizFunnelChart({ context }: VizViewProps) {

return (
<DefaultVizBox width={width} height={height}>
<Chart width={getBoxContentWidth(width)} height={getBoxContentHeight(height)} data={data} conf={conf} />
<Chart
instance={instance}
width={getBoxContentWidth(width)}
height={getBoxContentHeight(height)}
data={data}
conf={conf}
/>
</DefaultVizBox>
);
}
Loading
Loading