Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d11c501
Show filter actions in legend action when is computed
mariairiartef May 18, 2026
2e1fdec
Merge branch 'main' into lens/260185_legend-actions
mariairiartef May 19, 2026
a35464e
Rename to isComputedColumn
mariairiartef May 19, 2026
7287a65
Add panelHasConfiguredDrilldowns property
mariairiartef May 13, 2026
d1c04ea
Add panelHasConfiguredDrilldowns to show a different message when we …
mariairiartef May 21, 2026
76a5b69
Refactor
mariairiartef May 21, 2026
7134602
More refactora
mariairiartef May 22, 2026
96cb58f
Fix small issues
mariairiartef May 22, 2026
289e606
Add message to chart tooltip
mariairiartef May 22, 2026
395af39
Merge branch 'main' into lens/260185_legend-actions
mariairiartef May 25, 2026
df2ec9b
Refactor and cleanups
mariairiartef May 25, 2026
93df95a
Add message to partition charts tooltip in the footer
mariairiartef May 26, 2026
7b2cb66
Increase pagging for xy message legendActionPopoverStyles
mariairiartef May 26, 2026
bdcd4ca
Add message to partition charts legend actions when the column is com…
mariairiartef May 26, 2026
6e2a03d
Merge branch 'main' into lens/260185_legend-actions
mariairiartef May 26, 2026
417ef51
Changes from node scripts/check
kibanamachine May 26, 2026
7a30990
Changes from node scripts/lint_ts_projects --fix
kibanamachine May 26, 2026
dd61e4f
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine May 26, 2026
ab393d5
Fix issues
mariairiartef May 27, 2026
499e156
Changes from node scripts/regenerate_moon_projects.js --update
kibanamachine May 27, 2026
2b22c3c
Update snapshots
mariairiartef May 27, 2026
a237a82
Merge branch 'main' into lens/260185_legend-actions
mariairiartef May 27, 2026
f981d61
Changes from node scripts/check
kibanamachine May 27, 2026
6adedb0
Fix import
mariairiartef May 27, 2026
296f717
Update expressionHeatmap limitd
mariairiartef May 27, 2026
dc54d76
Add additional check for rename case
mariairiartef May 27, 2026
c2443c6
Refactor legend actions
mariairiartef May 28, 2026
d82cd55
Rename footer component for warning
mariairiartef May 28, 2026
99e7c7b
Merge branch 'main' into lens/260185_legend-actions
mariairiartef May 28, 2026
5475ea3
Revert "Add panelHasConfiguredDrilldowns property"
mariairiartef May 28, 2026
1ea692d
Remove drill down logic for showing a different message
mariairiartef May 29, 2026
4471e55
Fix issues
mariairiartef May 29, 2026
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
4 changes: 2 additions & 2 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ pageLoadAssetSize:
embeddableAlertsTable: 6524
enterpriseSearch: 37565
entityStore: 9718
esql: 29547
esql: 29469
esqlDataGrid: 10209
esUiShared: 101220
evals: 6117
eventAnnotation: 22334
eventAnnotationListing: 13164
exploratoryView: 45042
expressionGauge: 15748
expressionHeatmap: 17563
expressionHeatmap: 20303
expressionLegacyMetricVis: 11834
expressionMetricVis: 18100
expressionPartitionVis: 29826
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import type { DatatableColumn } from '@kbn/expressions-plugin/common';
import { i18n } from '@kbn/i18n';

const getComputedColumnFilterDisabledMessage = ({
computedColumnNames,
allColumnsAreComputed,
}: {
computedColumnNames: string[];
allColumnsAreComputed: boolean;
}) => {
const count = computedColumnNames.length;

if (allColumnsAreComputed) {
return i18n.translate(
'chartExpressionsCommon.computedColumn.filterDrilldownDisabledDescription',
{
defaultMessage:
"You can't apply a filter or drill down {count, plural, one {from this value because it relies on a field} other {from these values because they rely on fields}} created at query time.",
values: { count },
}
);
}

const names = computedColumnNames.map((n) => `'${n}'`).join(', ');
return i18n.translate(
'chartExpressionsCommon.computedColumn.partialFilterDrilldownDisabledDescription',
{
defaultMessage:
"You can't apply a filter or drill down from {names} because {count, plural, one {it relies on a field} other {they rely on fields}} created at query time.",
values: { names, count },
}
);
};

export function isComputedColumnNonFilterable(column: DatatableColumn): boolean {
if (column.isComputedColumn !== true) {
return false;
}
const sourceField = column.meta?.sourceParams?.sourceField;
// Without a string sourceField the filter action falls back to column.name, which always
// collides with the computed output column itself — filtering is never possible.
if (typeof sourceField !== 'string') {
return true;
}
// A column produced by RENAME has name !== sourceField; the underlying index field
// remains addressable, so filtering is still possible.
return column.name === sourceField;
}

/**
* Returns the warning message to show when filterable chart columns are computed ES|QL
* fields that cannot be used for filtering. Returns `undefined` when there is nothing
* to warn about.
*/
export const getComputedColumnWarningForColumns = (
filterableColumns: Array<DatatableColumn | undefined>
): string | undefined => {
const defined = filterableColumns.filter((c): c is DatatableColumn => c != null);
if (defined.length === 0) {
return undefined;
}

const nonFilterableComputedColumnNames = defined
.filter((col) => isComputedColumnNonFilterable(col))
.map((col) => col.name);

if (nonFilterableComputedColumnNames.length === 0) {
return undefined;
}

const allColumnsAreComputed = nonFilterableComputedColumnNames.length === defined.length;
return getComputedColumnFilterDisabledMessage({
computedColumnNames: nonFilterableComputedColumnNames,
allColumnsAreComputed,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export {
getLegendLayout,
} from './legend';

export { getComputedColumnWarningForColumns } from './computed_column_warning';
export type { Simplify, MakeOverridesSerializable, ChartSizeSpec, ChartSizeEvent } from './types';
export { isChartSizeEvent } from './types';
export type { ExpressionValueVisDimension } from './expression_value_dimension';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

import type { FC } from 'react';
import React, { memo, useMemo, useState, useCallback, useRef } from 'react';
import { css } from '@emotion/react';
import type { UseEuiTheme } from '@elastic/eui';
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
import moment from 'moment';
import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common';
import type {
Expand All @@ -23,12 +26,17 @@ import type {
SettingsProps,
SeriesIdentifier,
TooltipValue,
PointerValue,
} from '@elastic/charts';
import { Chart, Heatmap, ScaleType, Settings, TooltipType, Tooltip } from '@elastic/charts';
import type { CustomPaletteState } from '@kbn/charts-plugin/public';
import { search } from '@kbn/data-plugin/public';
import { LegendToggle, EmptyPlaceholder, useActiveCursor } from '@kbn/charts-plugin/public';
import { getAccessorByDimension, getFormatByAccessor } from '@kbn/chart-expressions-common';
import {
getAccessorByDimension,
getFormatByAccessor,
getComputedColumnWarningForColumns,
} from '@kbn/chart-expressions-common';
import { i18n } from '@kbn/i18n';
import type { DatatableColumn } from '@kbn/expressions-plugin/public';
import { IconChartHeatmap } from '@kbn/chart-icons';
Expand All @@ -39,6 +47,7 @@ import {
} from '@kbn/chart-expressions-common';
import { useKibanaIsDarkMode } from '@kbn/react-kibana-context-theme';
import type { CoreSetup } from '@kbn/core/public';

import type { HeatmapRenderProps, FilterEvent, BrushEvent } from '../../common';
import {
applyPaletteParams,
Expand Down Expand Up @@ -279,6 +288,25 @@ export function getDateFormatPattern(
return uiSettings.get('dateFormat');
}

const chartTooltipFooterMessageStyles = {
root: ({ euiTheme }: UseEuiTheme) =>
css`
color: ${euiTheme.colors.textSubdued};
font-size: ${euiTheme.size.m};
font-weight: ${euiTheme.font.weight.regular};
`,
};

/** Renders a styled message in the footer of the chart tooltip. */
const ChartTooltipFooterMessage: React.FC<{ message: string }> = ({ message }) => {
const styles = useMemoCss(chartTooltipFooterMessageStyles);
return (
<div css={styles.root} data-test-subj="chartTooltipFooterMessage">
{message}
</div>
);
};

export const HeatmapComponent: FC<HeatmapRenderProps> = memo(
({
data: table,
Expand Down Expand Up @@ -454,6 +482,24 @@ export const HeatmapComponent: FC<HeatmapRenderProps> = memo(

const hasTooltipActions = interactive && !isEsqlMode;

// Compute warning message for ES|QL computed columns that cannot be filtered.
const warningMessage = useMemo(
() =>
isEsqlMode ? getComputedColumnWarningForColumns([xAxisColumn, yAxisColumn]) : undefined,
[isEsqlMode, xAxisColumn, yAxisColumn]
);

const TooltipFooter = useMemo<
| React.ComponentType<{
items: Array<TooltipValue<Record<string, string | number>, SeriesIdentifier>>;
header: PointerValue<Record<string, string | number>> | null;
}>
| 'default'
>(() => {
if (!warningMessage) return 'default';
return () => <ChartTooltipFooterMessage message={warningMessage} />;
}, [warningMessage]);

const onElementClick = useCallback(
(e: HeatmapElementEvent[]) => {
const cell = e[0][0];
Expand Down Expand Up @@ -860,6 +906,7 @@ export const HeatmapComponent: FC<HeatmapRenderProps> = memo(
: undefined
}
type={args.showTooltip ? TooltipType.Follow : TooltipType.None}
footer={TooltipFooter}
/>
<Settings
onRenderChange={onRenderChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"@kbn/react-kibana-context-theme",
"@kbn/chart-test-jest-helpers",
"@kbn/field-formats-common",
"@kbn/visualizations-common"
"@kbn/visualizations-common",
"@kbn/css-utils"
],
"exclude": [
"target/**/*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependsOn:
- '@kbn/chart-icons'
- '@kbn/chart-expressions-common'
- '@kbn/cell-actions'
- '@kbn/css-utils'
- '@kbn/react-kibana-context-render'
- '@kbn/core-rendering-browser'
- '@kbn/palettes'
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,23 @@ import type {
PartitionElementEvent,
SettingsProps,
TooltipValue,
PointerValue,
} from '@elastic/charts';
import { Chart, Partition, Position, Settings, TooltipType, Tooltip } from '@elastic/charts';
import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import type { UseEuiTheme } from '@elastic/eui';
import { useEuiTheme } from '@elastic/eui';
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
import type { PaletteRegistry } from '@kbn/coloring';
import type { ChartsPluginSetup } from '@kbn/charts-plugin/public';
import { LegendToggle } from '@kbn/charts-plugin/public';
import type { PersistedState } from '@kbn/visualizations-common';
import { getColumnByAccessor } from '@kbn/chart-expressions-common';
import {
getColumnByAccessor,
getComputedColumnWarningForColumns,
} from '@kbn/chart-expressions-common';
import type {
Datatable,
DatatableColumn,
Expand Down Expand Up @@ -84,6 +91,26 @@ declare global {
_echDebugStateFlag?: boolean;
}
}

const chartTooltipFooterMessageStyles = {
root: ({ euiTheme }: UseEuiTheme) =>
css`
color: ${euiTheme.colors.textSubdued};
font-size: ${euiTheme.size.m};
font-weight: ${euiTheme.font.weight.regular};
`,
};

/** Renders a styled message in the footer of the chart tooltip. */
const ChartTooltipFooterMessage: React.FC<{ message: string }> = ({ message }) => {
const styles = useMemoCss(chartTooltipFooterMessageStyles);
return (
<div css={styles.root} data-test-subj="chartTooltipFooterMessage">
{message}
</div>
);
};

export type PartitionVisComponentProps = Omit<
PartitionChartProps,
'navigateToLens' | 'visConfig'
Expand Down Expand Up @@ -408,6 +435,28 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => {
const hasTooltipActions =
interactive && !isEsqlMode && bucketAccessors.filter((a) => a !== 'metric-name').length > 0;

// Compute warning message for ES|QL computed columns that cannot be filtered.
const warningMessage = useMemo(
() =>
isEsqlMode
? getComputedColumnWarningForColumns(
bucketColumns.map((col) => visData.columns.find((c) => c.id === col.id))
)
: undefined,
[isEsqlMode, bucketColumns, visData.columns]
);

const TooltipFooter = useMemo<
| React.ComponentType<{
items: Array<TooltipValue<Record<'key', string | number>, SeriesIdentifier>>;
header: PointerValue<Record<'key', string | number>> | null;
}>
| 'default'
>(() => {
if (!warningMessage) return 'default';
return () => <ChartTooltipFooterMessage message={warningMessage} />;
}, [warningMessage]);

const tooltip: TooltipProps = {
...(fixedViewPort ? { boundary: fixedViewPort } : {}),
type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None,
Expand Down Expand Up @@ -544,7 +593,7 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => {
splitColumnAccessor={splitChartColumnAccessor}
splitRowAccessor={splitChartRowAccessor}
/>
<Tooltip {...tooltip} />
<Tooltip {...tooltip} footer={TooltipFooter} />
<Settings
noResults={
<VisualizationNoResults chartType={visType} renderComplete={onRenderChange} />
Expand Down
Loading
Loading