in packages/charts/src/components/legend/legend.tsx [69:180]
function LegendComponent(props: LegendStateProps & LegendDispatchProps) {
const {
items,
size,
debug,
isBrushing,
chartTheme: { chartMargins, legend },
chartDimensions,
containerDimensions,
config,
} = props;
const { onLegendItemOut, onLegendItemOver } = config;
const { onItemOutAction, onItemOverAction } = props;
const onLegendItemMouseOver = useCallback(
(seriesIdentifiers: SeriesIdentifier[], path: LegendPath) => {
// call the settings listener directly if available
if (onLegendItemOver) {
onLegendItemOver(seriesIdentifiers);
}
onItemOverAction(path);
},
[onItemOverAction, onLegendItemOver],
);
const onLegendItemMouseOut = useCallback(() => {
// call the settings listener directly if available
if (onLegendItemOut) {
onLegendItemOut();
}
onItemOutAction();
}, [onLegendItemOut, onItemOutAction]);
if (items.every(({ isItemHidden }) => isItemHidden)) {
return null;
}
const positionConfig = getLegendPositionConfig(config.legendPosition);
const containerStyle = getLegendStyle(positionConfig, size, legend.margin);
const listStyle = getLegendListStyle(positionConfig, chartMargins, legend, items.length);
const isMostlyRTL = hasMostlyRTLItems(items.map(({ label }) => label));
const legendClasses = classNames('echLegend', {
'echLegend--debug': debug,
'echLegend--inert': isBrushing,
'echLegend--horizontal': positionConfig.direction === LayoutDirection.Horizontal,
'echLegend--vertical': positionConfig.direction === LayoutDirection.Vertical,
'echLegend--left': positionConfig.hAlign === HorizontalAlignment.Left,
'echLegend--right': positionConfig.hAlign === HorizontalAlignment.Right,
'echLegend--top': positionConfig.vAlign === VerticalAlignment.Top,
'echLegend--bottom': positionConfig.vAlign === VerticalAlignment.Bottom,
});
const itemProps: Omit<LegendItemProps, 'item'> = {
positionConfig,
isMostlyRTL,
totalItems: items.length,
hiddenItems: items.filter(({ isSeriesHidden }) => isSeriesHidden).length,
extraValues: props.extraValues,
legendValues: config.legendValues,
onLegendItemMouseOver,
onLegendItemMouseOut,
onClick: config.onLegendItemClick,
clearTemporaryColorsAction: props.clearTemporaryColors,
setPersistedColorAction: props.setPersistedColor,
setTemporaryColorAction: props.setTemporaryColor,
toggleDeselectSeriesAction: props.onToggleDeselectSeriesAction,
colorPicker: config.legendColorPicker,
action: config.legendAction,
labelOptions: legend.labelOptions,
flatLegend: config.flatLegend ?? DEFAULT_LEGEND_CONFIG.flatLegend,
legendTitle: config.legendTitle,
};
const positionStyle = legendPositionStyle(config, size, chartDimensions, containerDimensions);
const isTableView = shouldDisplayTable(itemProps.legendValues);
return (
<div className={legendClasses} style={positionStyle} dir={isMostlyRTL ? 'rtl' : 'ltr'}>
{config.customLegend ? (
<div style={containerStyle}>
<CustomLegend
component={config.customLegend}
items={items.map(({ seriesIdentifiers, childId, path, ...customProps }) => ({
...customProps,
seriesIdentifiers,
path,
extraValue: itemProps.extraValues.get(seriesIdentifiers[0]?.key ?? '')?.get(childId ?? ''),
onItemOutAction,
onItemOverActon: () => onItemOverAction(path),
onItemClickAction: (negate: boolean) =>
itemProps.toggleDeselectSeriesAction({ legendItemIds: seriesIdentifiers, metaKey: negate }),
}))}
/>
</div>
) : isTableView ? (
<div style={containerStyle} className="echLegendTable__container">
<LegendTable items={items} {...itemProps} seriesWidth={size.seriesWidth} />
</div>
) : (
<div style={containerStyle} className="echLegendListContainer">
<ul style={listStyle} className="echLegendList">
{items.map((item, index) => (
<LegendListItem key={`${index}`} item={item} {...itemProps} />
))}
</ul>
</div>
)}
</div>
);
}