Skip to content

Commit

Permalink
chore: improve type and fixed legend sizing
Browse files Browse the repository at this point in the history
  • Loading branch information
markov00 committed Mar 11, 2024
1 parent 3d196b8 commit 5c928ba
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const computeLegendSelector = createCustomCachedSelector(
return {
// the band label is considered unique by construction
seriesIdentifiers: [{ key: label, specId: label }],
depth: 0,
color,
label,
isSeriesHidden: deselectedDataSeries.some(({ key }) => key === label),
Expand Down
2 changes: 2 additions & 0 deletions packages/charts/src/chart_types/xy_chart/legend/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export function computeLegend(
const formattedItemValue = itemValue !== null ? formatter(itemValue) : '';

legendItems.push({
depth: 0,
color,
label: banded ? getBandedLegendItemLabel(name, BandedAccessorType.Y1, postFixes) : name,
seriesIdentifiers: [seriesIdentifier],
Expand Down Expand Up @@ -156,6 +157,7 @@ export function computeLegend(

const labelY0 = getBandedLegendItemLabel(name, BandedAccessorType.Y0, postFixes);
legendItems.push({
depth: 0,
color,
label: labelY0,
seriesIdentifiers: [seriesIdentifier],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ describe('Rendering utils', () => {
const highlightedLegendItem: LegendItem = {
color: '',
label: '',
depth: 0,
seriesIdentifiers: [seriesIdentifier],
isSeriesHidden: false,
values: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,8 @@
* Side Public License, v 1.
*/

import { computeLegendSelector } from './compute_legend';
import { createCustomCachedSelector } from '../../../../state/create_selector';
import { LegendItemLabel } from '../../../../state/selectors/get_legend_items_labels';
import { getSettingsSpecSelector } from '../../../../state/selectors/get_settings_spec';

/** @internal */
export const getLegendItemsLabelsSelector = createCustomCachedSelector(
[computeLegendSelector, getSettingsSpecSelector],
(legendItems, { showLegendExtra }): LegendItemLabel[] =>
legendItems.map(({ label, values }) => {
return {
label: `${label}${showLegendExtra ? values[0]?.label : ''}`,
depth: 0,
};
}),
);
export const getLegendItemsLabelsSelector = createCustomCachedSelector([], (): LegendItemLabel[] => []);
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ describe('Type Checks', () => {
{
color: '#1EA593',
label: 'a',
depth: 0,
seriesIdentifiers: [
{
key: 'specId:{bars},colors:{a}',
Expand All @@ -141,6 +142,7 @@ describe('Type Checks', () => {
{
color: '#2B70F7',
label: 'b',
depth: 0,
seriesIdentifiers: [
{
key: 'specId:{bars},colors:{b}',
Expand All @@ -160,6 +162,7 @@ describe('Type Checks', () => {
{
color: '#1EA593',
label: 'a',
depth: 0,
seriesIdentifiers: [
{
key: 'specId:{bars},colors:{a}',
Expand All @@ -174,6 +177,7 @@ describe('Type Checks', () => {
{
color: '#2B70F7',
label: 'b',
depth: 0,
seriesIdentifiers: [
{
key: 'specId:{bars},colors:{b}',
Expand Down
3 changes: 2 additions & 1 deletion packages/charts/src/common/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export type LegendItemValue = { value: PrimitiveValue; label: string };
export type LegendItem = {
seriesIdentifiers: SeriesIdentifier[];
childId?: LegendItemChildId;
depth?: number;
// zero indexed
depth: number;
/**
* Path to iterm in hierarchical legend
*/
Expand Down
36 changes: 21 additions & 15 deletions packages/charts/src/state/selectors/get_legend_size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { getChartThemeSelector } from './get_chart_theme';
import { getLegendConfigSelector } from './get_legend_config_selector';
import { getLegendItemsLabelsSelector } from './get_legend_items_labels';
import { getLegendItemsSelector } from './get_legend_items';
import { DEFAULT_FONT_FAMILY } from '../../common/default_theme_attributes';
import { LEGEND_HIERARCHY_MARGIN } from '../../components/legend/legend_item';
import { LEGEND_TO_FULL_CONFIG } from '../../components/legend/position_style';
Expand All @@ -35,17 +35,23 @@ export type LegendSizing = Size & {

/** @internal */
export const getLegendSizeSelector = createCustomCachedSelector(
[getLegendConfigSelector, getChartThemeSelector, getParentDimensionSelector, getLegendItemsLabelsSelector],
(legendConfig, theme, parentDimensions, labels): LegendSizing => {
if (!legendConfig.showLegend) {
[getLegendConfigSelector, getChartThemeSelector, getParentDimensionSelector, getLegendItemsSelector],
(
{ showLegend, legendSize, showLegendExtra, legendPosition, legendAction },
theme,
parentDimensions,
items,
): LegendSizing => {
if (!showLegend) {
return { width: 0, height: 0, margin: 0, position: LEGEND_TO_FULL_CONFIG[Position.Right] };
}

const bbox = withTextMeasure((textMeasure) =>
labels.reduce(
(acc, { label, depth }) => {
items.reduce(
(acc, { label, depth, values }) => {
const itemLabel = `${label}${showLegendExtra ? values[0]?.label ?? '' : ''}`;
const { width, height } = textMeasure(
label,
itemLabel,
{ fontFamily: DEFAULT_FONT_FAMILY, fontVariant: 'normal', fontWeight: 400, fontStyle: 'normal' },
12,
1.5,
Expand All @@ -58,22 +64,22 @@ export const getLegendSizeSelector = createCustomCachedSelector(
),
);

const { showLegendExtra: showLegendDisplayValue, legendPosition, legendAction } = legendConfig;
const {
legend: { verticalWidth, spacingBuffer, margin },
} = theme;

const actionDimension = isDefined(legendAction) ? 24 : 0; // max width plus margin
const legendItemWidth = MARKER_WIDTH + SHARED_MARGIN + bbox.width + (showLegendDisplayValue ? SHARED_MARGIN : 0);
const showExtraMargin = showLegendExtra; // && items.every(({ values }) => values.length > 0); // remove unnecessary margin
const legendItemWidth = MARKER_WIDTH + SHARED_MARGIN + bbox.width + (showExtraMargin ? SHARED_MARGIN : 0);

if (legendPosition.direction === LayoutDirection.Vertical) {
const legendItemHeight = bbox.height + VERTICAL_PADDING * 2;
const legendHeight = legendItemHeight * labels.length + TOP_MARGIN;
const legendHeight = legendItemHeight * items.length + TOP_MARGIN;
const scrollBarDimension = legendHeight > parentDimensions.height ? SCROLL_BAR_WIDTH : 0;
const staticWidth = spacingBuffer + actionDimension + scrollBarDimension;

const width = Number.isFinite(legendConfig.legendSize)
? Math.min(Math.max(legendConfig.legendSize, legendItemWidth * 0.3 + staticWidth), parentDimensions.width * 0.7)
const width = Number.isFinite(legendSize)
? Math.min(Math.max(legendSize, legendItemWidth * 0.3 + staticWidth), parentDimensions.width * 0.7)
: Math.floor(Math.min(legendItemWidth + staticWidth, verticalWidth));

return {
Expand All @@ -83,9 +89,9 @@ export const getLegendSizeSelector = createCustomCachedSelector(
position: legendPosition,
};
}
const isSingleLine = (parentDimensions.width - 20) / 200 > labels.length;
const height = Number.isFinite(legendConfig.legendSize)
? Math.min(legendConfig.legendSize, parentDimensions.height * 0.7)
const isSingleLine = (parentDimensions.width - 20) / 200 > items.length;
const height = Number.isFinite(legendSize)
? Math.min(legendSize, parentDimensions.height * 0.7)
: isSingleLine
? bbox.height + 16
: bbox.height * 2 + 24;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { ChartsStory } from '../../types';
import { useBaseTheme } from '../../use_base_theme';

export const Example: ChartsStory = (_, { title, description }) => {
const showLegend = boolean('Show legend', true, 'Y axis');
const showLegend = boolean('Show legend', true);
const showLegendExtra = boolean('Show legend values', true);
const disableYAxisFormat = boolean('Disable Axis tickFormat', false, 'Y axis');
const yAxisFormat = text('Axis value format', '0[.]0', 'Y axis');
const yAxisUnit = text('Axis unit', 'pets', 'Y axis');
Expand All @@ -31,7 +32,7 @@ export const Example: ChartsStory = (_, { title, description }) => {

return (
<Chart title={title} description={description}>
<Settings baseTheme={useBaseTheme()} showLegendExtra showLegend={showLegend} />
<Settings baseTheme={useBaseTheme()} showLegendExtra={showLegendExtra} showLegend={showLegend} />
<Tooltip
headerFormatter={
disableHeaderFormat ? undefined : ({ value }) => `${value}${headerUnit ? ` ${headerUnit}` : ''}`
Expand Down

0 comments on commit 5c928ba

Please sign in to comment.