Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,26 @@ export const computeSeriesDomainsSelector = createCustomCachedSelector(
],
computeSeriesDomains,
);

/**
* Returns series domains computed over the full dataset, ignoring any deselected series.
* When nothing is deselected, reuses the already-memoized result of computeSeriesDomainsSelector
* at zero extra cost. Only triggers a second computeSeriesDomains call when deselection is active.
* Used for stable legend width calculation.
* @internal
*/
export const computeFullSeriesDomainsSelector = createCustomCachedSelector(
[
computeSeriesDomainsSelector,
getDeselectedSeriesSelector,
getSeriesSpecsSelector,
getScaleConfigsFromSpecsSelector,
getAnnotationSpecsSelector,
getSettingsSpecSelector,
getSmallMultiplesIndexOrderSelector,
],
(domains, deselectedSeries, seriesSpecs, scaleConfigs, annotations, settings, smallMultiples) => {
if (deselectedSeries.length === 0) return domains;
return computeSeriesDomains(seriesSpecs, scaleConfigs, annotations, settings, [], smallMultiples);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { computeSeriesDomainsSelector } from './compute_series_domains';
import { computeFullSeriesDomainsSelector } from './compute_series_domains';
import { getAxisSpecsSelector, getSeriesSpecsSelector } from './get_specs';
import { createCustomCachedSelector } from '../../../../state/create_selector';
import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_spec';
Expand All @@ -19,7 +19,7 @@ import { getAxesSpecForSpecId } from '../utils/spec';
* @internal
*/
export const getLongestLegendFormattedValueSelector = createCustomCachedSelector(
[computeSeriesDomainsSelector, getSeriesSpecsSelector, getAxisSpecsSelector, getSettingsSpecSelector],
[computeFullSeriesDomainsSelector, getSeriesSpecsSelector, getAxisSpecsSelector, getSettingsSpecSelector],
({ yDomains }, seriesSpecs, axesSpecs, settings): string | undefined => {
const maxYValue = yDomains?.[0]?.domain?.[1];
if (typeof maxYValue !== 'number' || !isFinite(maxYValue)) return undefined;
Expand Down
6 changes: 3 additions & 3 deletions packages/charts/src/components/legend/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface LabelProps {
options: LegendLabelOptions;
hiddenSeriesCount: number;
totalSeriesCount: number;
truncationMode?: TruncationMode;
truncationMode: TruncationMode;
}

const isAppleDevice = typeof window !== 'undefined' && /Mac|iPhone|iPad/.test(window.navigator.userAgent);
Expand Down Expand Up @@ -92,7 +92,7 @@ export function Label({
[onToggle],
);

const title = Math.abs(options.maxLines) > 0 ? label : ''; // full text already visible
const title = truncationMode === 'px' || Math.abs(options.maxLines) > 0 ? label : '';

return isToggleable ? (
// This div is required to allow multiline text truncation, all ARIA requirements are still met
Expand Down Expand Up @@ -139,7 +139,7 @@ function getSharedProps(
const widthLimit = Math.abs(options.widthLimit);
const className = classNames('echLegendItem__label', {
'echLegendItem__label--clickable': Boolean(isToggleable),
'echLegendItem__label--singleline': maxLines === 1,
'echLegendItem__label--singleline': truncationMode === 'px' || maxLines === 1,
'echLegendItem__label--multiline': maxLines > 1 && truncationMode === 'line',
});

Expand Down
3 changes: 2 additions & 1 deletion packages/charts/src/components/legend/legend_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ export const LegendList: React.FC<Props> = (props) => {

// Pre-compute value elements for both layout modes
const valueElements: React.ReactNode[] = [];
if (!isSeriesHidden) {
const shouldShowValues = !isSeriesHidden || Boolean(isListLayout);
if (shouldShowValues) {
const valueData = isListLayout
? // In list layout, preserve the `legendValues` order and allow placeholders for CurrentAndLastValue
legendValues.map((type, index) => ({ type, legendValueItem: preparedLegendValues[index], index }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const LegendListItem: React.FC<LegendItemProps> = (props) => {
isSeriesHidden={isSeriesHidden}
totalSeriesCount={totalItems}
hiddenSeriesCount={hiddenItems}
truncationMode="line"
/>
</LegendTableCell>

Expand Down
4 changes: 2 additions & 2 deletions storybook/stories/legend/2_legend_layout.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ const getLabelOptionKnobs = (isLineLimit: boolean): LegendLabelOptions => {
return isLineLimit
? {
maxLines: number('max label lines', 1, { min: 0, step: 1 }, group),
widthLimit: 250,
widthLimit: 240,
}
: {
maxLines: 1,
maxLines: 2,
widthLimit: number('width limit', 250, { min: 0, step: 1 }, group),
};
};
Expand Down