Skip to content

Commit

Permalink
perf(tooltip): improve placement logic (#2310)
Browse files Browse the repository at this point in the history
  • Loading branch information
nickofthyme authored Jan 29, 2024
1 parent 2c8eb29 commit cac5f49
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 21 deletions.
10 changes: 5 additions & 5 deletions packages/charts/src/components/portal/tooltip_portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,17 @@ const TooltipPortalComponent = ({
*/
useEffect(() => {
document.body.appendChild(portalNode);
});
}, [portalNode]);

/**
* Popper instance used to manage position of tooltip.
*/
const popper = useRef<Instance | null>(null);
const popperSettings = useMemo(
const popperSettings = useMemo(() => {
// @ts-ignore - nesting limitation
() => mergePartial(DEFAULT_POPPER_SETTINGS, settings),
[settings],
);
return mergePartial(DEFAULT_POPPER_SETTINGS, settings);
}, [settings]);

const destroyPopper = useCallback(() => {
if (popper.current) {
popper.current.destroy();
Expand Down
19 changes: 3 additions & 16 deletions packages/charts/src/components/tooltip/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
} from './types';
import { Colors } from '../../common/colors';
import { SeriesIdentifier } from '../../common/series_id';
import { BaseDatum, DEFAULT_TOOLTIP_SPEC, SettingsSpec, TooltipProps, TooltipSpec, TooltipValue } from '../../specs';
import { BaseDatum, DEFAULT_TOOLTIP_SPEC, TooltipProps, TooltipSpec, TooltipValue } from '../../specs';
import { onPointerMove as onPointerMoveAction } from '../../state/actions/mouse';
import {
toggleSelectedTooltipItem as toggleSelectedTooltipItemAction,
Expand All @@ -45,8 +45,8 @@ import { getInternalIsInitializedSelector, InitStatus } from '../../state/select
import { getInternalIsTooltipVisibleSelector } from '../../state/selectors/get_internal_is_tooltip_visible';
import { getInternalTooltipAnchorPositionSelector } from '../../state/selectors/get_internal_tooltip_anchor_position';
import { getInternalTooltipInfoSelector } from '../../state/selectors/get_internal_tooltip_info';
import { getSettingsSpecSelector } from '../../state/selectors/get_settings_spec';
import { getTooltipSelectedItems } from '../../state/selectors/get_tooltip_selected_items';
import { getTooltipSettings } from '../../state/selectors/get_tooltip_settings';
import { getTooltipSpecSelector } from '../../state/selectors/get_tooltip_spec';
import { isBrushingSelector } from '../../state/selectors/is_brushing';
import { Datum, hasMostlyRTLItems, isDefined, Rotation } from '../../utils/common';
Expand Down Expand Up @@ -329,19 +329,6 @@ export const TooltipComponent = <D extends BaseDatum = Datum, SI extends SeriesI

TooltipComponent.displayName = 'Tooltip';

function getTooltipSettings(
tooltip: TooltipSpec,
{ externalPointerEvents }: SettingsSpec,
isExternalTooltipVisible: boolean,
): TooltipProps {
if (!isExternalTooltipVisible) return tooltip;

return {
...tooltip,
...externalPointerEvents.tooltip,
};
}

const HIDDEN_TOOLTIP_PROPS: TooltipStateProps = {
tooltip: DEFAULT_TOOLTIP_SPEC,
zIndex: 0,
Expand Down Expand Up @@ -389,7 +376,7 @@ const mapStateToPropsBasic = (state: GlobalChartState): BasicTooltipProps => {
isExternal,
isBrushing: false,
zIndex: state.zIndex,
settings: getTooltipSettings(tooltip, getSettingsSpecSelector(state), isExternal),
settings: getTooltipSettings(state),
tooltipTheme,
rotation: getChartRotationSelector(state),
chartId: state.chartId,
Expand Down
34 changes: 34 additions & 0 deletions packages/charts/src/state/selectors/get_tooltip_settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { Selector } from 're-reselect';

import { getInternalIsTooltipVisibleSelector } from './get_internal_is_tooltip_visible';
import { getSettingsSpecSelector } from './get_settings_spec';
import { getTooltipSpecSelector } from './get_tooltip_spec';
import type { TooltipProps } from '../../specs';
import { GlobalChartState } from '../chart_state';
import { createCustomCachedSelector } from '../create_selector';

const getChartId: Selector<GlobalChartState, string> = ({ chartId }) => chartId;

/** @internal */
const getTooltipSettingsSingleton = createCustomCachedSelector([getChartId], (): Record<string, never> => ({}));

/** @internal */
export const getTooltipSettings = createCustomCachedSelector(
[getTooltipSettingsSingleton, getTooltipSpecSelector, getSettingsSpecSelector, getInternalIsTooltipVisibleSelector],
(settingsBase, tooltip, { externalPointerEvents }, { isExternal }): TooltipProps => {
if (!isExternal) return tooltip;

return Object.assign(settingsBase, {
...tooltip,
...externalPointerEvents.tooltip,
});
},
);

0 comments on commit cac5f49

Please sign in to comment.