mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[vislib][Heatmap] When used on a dashboard, the render event fires more than 1 time (#143734)
* [vislib][Heatmap] When used on a dashboard, the render event fires more than 1 time * update logic Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
0bdd9813bc
commit
3150520ac4
2 changed files with 63 additions and 49 deletions
|
@ -9,13 +9,10 @@
|
|||
import $ from 'jquery';
|
||||
import React, { RefObject } from 'react';
|
||||
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
|
||||
import type { PersistedState } from '@kbn/visualizations-plugin/public';
|
||||
import { IInterpreterRenderHandlers } from '@kbn/expressions-plugin/public';
|
||||
import { KibanaExecutionContext } from '@kbn/core-execution-context-common';
|
||||
import { getUsageCollectionStart } from './services';
|
||||
import { VisTypeVislibCoreSetup } from './plugin';
|
||||
import { VisLegend, CUSTOM_LEGEND_VIS_TYPES } from './vislib/components/legend';
|
||||
import { BasicVislibParams } from './types';
|
||||
|
@ -30,38 +27,6 @@ const legendClassName = {
|
|||
|
||||
export type VislibVisController = InstanceType<ReturnType<typeof createVislibVisController>>;
|
||||
|
||||
/** @internal **/
|
||||
const extractContainerType = (context?: KibanaExecutionContext): string | undefined => {
|
||||
if (context) {
|
||||
const recursiveGet = (item: KibanaExecutionContext): KibanaExecutionContext | undefined => {
|
||||
if (item.type) {
|
||||
return item;
|
||||
} else if (item.child) {
|
||||
return recursiveGet(item.child);
|
||||
}
|
||||
};
|
||||
return recursiveGet(context)?.type;
|
||||
}
|
||||
};
|
||||
|
||||
const renderComplete = (
|
||||
visParams: BasicVislibParams | PieVisParams,
|
||||
handlers: IInterpreterRenderHandlers
|
||||
) => {
|
||||
const usageCollection = getUsageCollectionStart();
|
||||
const containerType = extractContainerType(handlers.getExecutionContext());
|
||||
|
||||
if (usageCollection && containerType) {
|
||||
usageCollection.reportUiCounter(
|
||||
containerType,
|
||||
METRIC_TYPE.COUNT,
|
||||
`render_agg_based_${visParams.type}`
|
||||
);
|
||||
}
|
||||
|
||||
handlers.done();
|
||||
};
|
||||
|
||||
export const createVislibVisController = (
|
||||
core: VisTypeVislibCoreSetup,
|
||||
charts: ChartsPluginSetup
|
||||
|
@ -99,7 +64,8 @@ export const createVislibVisController = (
|
|||
async render(
|
||||
esResponse: any,
|
||||
visParams: BasicVislibParams | PieVisParams,
|
||||
handlers: IInterpreterRenderHandlers
|
||||
handlers: IInterpreterRenderHandlers,
|
||||
renderComplete: (() => void) | undefined
|
||||
): Promise<void> {
|
||||
if (this.vislibVis) {
|
||||
this.destroy(false);
|
||||
|
@ -109,7 +75,7 @@ export const createVislibVisController = (
|
|||
this.chartEl.dataset.vislibChartType = visParams.type;
|
||||
|
||||
if (this.el.clientWidth === 0 || this.el.clientHeight === 0) {
|
||||
renderComplete(visParams, handlers);
|
||||
renderComplete?.();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -133,7 +99,7 @@ export const createVislibVisController = (
|
|||
this.mountLegend(esResponse, visParams, fireEvent, uiState as PersistedState);
|
||||
}
|
||||
|
||||
renderComplete(visParams, handlers);
|
||||
renderComplete?.();
|
||||
});
|
||||
|
||||
this.removeListeners = () => {
|
||||
|
|
|
@ -6,20 +6,23 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useMemo, useRef } from 'react';
|
||||
import { EuiResizeObserver } from '@elastic/eui';
|
||||
import React, { useEffect, useMemo, useRef, useCallback } from 'react';
|
||||
import { EuiResizeObserver, EuiResizeObserverProps } from '@elastic/eui';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
import { IInterpreterRenderHandlers } from '@kbn/expressions-plugin/public';
|
||||
import type { PersistedState } from '@kbn/visualizations-plugin/public';
|
||||
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
|
||||
|
||||
import { KibanaExecutionContext } from '@kbn/core-execution-context-common';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { VislibRenderValue } from './vis_type_vislib_vis_fn';
|
||||
import { createVislibVisController, VislibVisController } from './vis_controller';
|
||||
import { VisTypeVislibCoreSetup } from './plugin';
|
||||
import { PieRenderValue } from './pie_fn';
|
||||
|
||||
import './index.scss';
|
||||
import { getUsageCollectionStart } from './services';
|
||||
|
||||
type VislibWrapperProps = (VislibRenderValue | PieRenderValue) & {
|
||||
core: VisTypeVislibCoreSetup;
|
||||
|
@ -27,20 +30,67 @@ type VislibWrapperProps = (VislibRenderValue | PieRenderValue) & {
|
|||
handlers: IInterpreterRenderHandlers;
|
||||
};
|
||||
|
||||
/** @internal **/
|
||||
const extractContainerType = (context?: KibanaExecutionContext): string | undefined => {
|
||||
if (context) {
|
||||
const recursiveGet = (item: KibanaExecutionContext): KibanaExecutionContext | undefined => {
|
||||
if (item.type) {
|
||||
return item;
|
||||
} else if (item.child) {
|
||||
return recursiveGet(item.child);
|
||||
}
|
||||
};
|
||||
return recursiveGet(context)?.type;
|
||||
}
|
||||
};
|
||||
|
||||
const VislibWrapper = ({ core, charts, visData, visConfig, handlers }: VislibWrapperProps) => {
|
||||
const chartDiv = useRef<HTMLDivElement>(null);
|
||||
const visController = useRef<VislibVisController | null>(null);
|
||||
const skipRenderComplete = useRef<boolean>(true);
|
||||
|
||||
const updateChart = useMemo(
|
||||
const renderComplete = useMemo(
|
||||
() => () => {
|
||||
const usageCollection = getUsageCollectionStart();
|
||||
const containerType = extractContainerType(handlers.getExecutionContext());
|
||||
|
||||
if (usageCollection && containerType) {
|
||||
usageCollection.reportUiCounter(
|
||||
containerType,
|
||||
METRIC_TYPE.COUNT,
|
||||
`render_agg_based_${visConfig!.type}`
|
||||
);
|
||||
}
|
||||
handlers.done();
|
||||
},
|
||||
[handlers, visConfig]
|
||||
);
|
||||
|
||||
const renderChart = useMemo(
|
||||
() =>
|
||||
debounce(() => {
|
||||
if (visController.current) {
|
||||
visController.current.render(visData, visConfig, handlers);
|
||||
visController.current.render(
|
||||
visData,
|
||||
visConfig,
|
||||
handlers,
|
||||
skipRenderComplete.current ? undefined : renderComplete
|
||||
);
|
||||
}
|
||||
skipRenderComplete.current = true;
|
||||
}, 100),
|
||||
[visConfig, visData, handlers]
|
||||
[handlers, renderComplete, skipRenderComplete, visConfig, visData]
|
||||
);
|
||||
|
||||
const onResize: EuiResizeObserverProps['onResize'] = useCallback(() => {
|
||||
renderChart();
|
||||
}, [renderChart]);
|
||||
|
||||
useEffect(() => {
|
||||
skipRenderComplete.current = false;
|
||||
renderChart();
|
||||
}, [renderChart]);
|
||||
|
||||
useEffect(() => {
|
||||
if (chartDiv.current) {
|
||||
const Controller = createVislibVisController(core, charts);
|
||||
|
@ -52,22 +102,20 @@ const VislibWrapper = ({ core, charts, visData, visConfig, handlers }: VislibWra
|
|||
};
|
||||
}, [core, charts]);
|
||||
|
||||
useEffect(updateChart, [updateChart]);
|
||||
|
||||
useEffect(() => {
|
||||
if (handlers.uiState) {
|
||||
const uiState = handlers.uiState as PersistedState;
|
||||
|
||||
uiState.on('change', updateChart);
|
||||
uiState.on('change', renderChart);
|
||||
|
||||
return () => {
|
||||
uiState?.off('change', updateChart);
|
||||
uiState?.off('change', renderChart);
|
||||
};
|
||||
}
|
||||
}, [handlers.uiState, updateChart]);
|
||||
}, [handlers.uiState, renderChart]);
|
||||
|
||||
return (
|
||||
<EuiResizeObserver onResize={updateChart}>
|
||||
<EuiResizeObserver onResize={onResize}>
|
||||
{(resizeRef) => (
|
||||
<div className="vislib__wrapper" ref={resizeRef}>
|
||||
<div className="vislib__container" ref={chartDiv} />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue