Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(legend): add legend item actions #749

Merged
merged 15 commits into from
Jul 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ module.exports = {
{
files: ['stories/**/*.ts?(x)', '*.test.ts?(x)'],
rules: {
'jsx-a11y/no-static-element-interactions': 0,
'jsx-a11y/click-events-have-key-events': 0,
'no-restricted-properties': [
process.env.NODE_ENV === 'production' ? 2 : 1,
{
Expand Down
5 changes: 5 additions & 0 deletions .storybook/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,8 @@ html.echVisualTesting {
padding-bottom: 200px;
}
}

// for using EuiWrappingPopover in stories
.euiPopover__anchor {
width: 100%;
}
12 changes: 11 additions & 1 deletion api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -738,10 +738,18 @@ export interface LayerValue {
value: number;
}

// @public
export type LegendAction = ComponentType<LegendActionProps>;

// @public
export interface LegendActionProps {
series: SeriesIdentifier;
}

// Warning: (ae-missing-release-tag) "LegendColorPicker" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type LegendColorPicker = React.ComponentType<LegendColorPickerProps>;
export type LegendColorPicker = ComponentType<LegendColorPickerProps>;

// Warning: (ae-missing-release-tag) "LegendColorPickerProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand All @@ -764,6 +772,7 @@ export type LegendItemListener = (series: SeriesIdentifier | null) => void;
// @public (undocumented)
export interface LegendStyle {
horizontalHeight: number;
margin: number;
spacingBuffer: number;
verticalWidth: number;
}
Expand Down Expand Up @@ -1273,6 +1282,7 @@ export interface SettingsSpec extends Spec {
externalPointerEvents: ExternalPointerEventsSettings;
flatLegend?: boolean;
hideDuplicateAxes: boolean;
legendAction?: LegendAction;
// (undocumented)
legendColorPicker?: LegendColorPicker;
legendMaxDepth?: number;
Expand Down
23 changes: 20 additions & 3 deletions integration/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { join, resolve } from 'path';

import { getStorybook, configure } from '@storybook/react';

export type StoryInfo = [string, string];
export type StoryInfo = [string, string, number];

export type StoryGroupInfo = [string, string, StoryInfo[]];

Expand Down Expand Up @@ -67,18 +67,35 @@ function encodeString(string: string) {
.toLowerCase();
}

/**
* Stories to skip in all vrt based on group.
*/
const storiesToSkip: Record<string, string[]> = {
// Interactions: ['Some story name'],
};

/**
* Delays for stories to skip in all vrt based on group.
*/
const storiesToDelay: Record<string, Record<string, number>> = {
Legend: {
Actions: 200, // needed for icon to load
},
};

export function getStorybookInfo(): StoryGroupInfo[] {
configure(requireAllStories(__dirname, '../stories'), module);

return getStorybook()
.filter(({ kind }) => kind)
.map(({ kind: group, stories: storiesRaw }) => {
const stories: StoryInfo[] = storiesRaw
.filter(({ name }) => name)
.filter(({ name }) => name && !storiesToSkip[group]?.includes(name))
.map(({ name: title }) => {
// cleans story name to match url params
const encodedTitle = encodeString(title);
return [title, encodedTitle];
const delay = (storiesToDelay[group] ?? {})[title];
return [title, encodedTitle, delay];
});

const encodedGroup = encodeString(group);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions integration/tests/all.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ const storyGroups = getStorybookInfo();

describe('Baseline Visual tests for all stories', () => {
describe.each(storyGroups)('%s', (_group, encodedGroup, stories) => {
describe.each(stories)('%s', (_title, encodedTitle) => {
describe.each(stories)('%s', (_title, encodedTitle, delay) => {
it('visually looks correct', async() => {
const url = `http://localhost:9001?id=${encodedGroup}--${encodedTitle}`;
await common.expectChartAtUrlToMatchScreenshot(url);
await common.expectChartAtUrlToMatchScreenshot(url, { delay });
});
});
});
Expand Down
12 changes: 12 additions & 0 deletions integration/tests/legend_stories.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,16 @@ describe('Legend stories', () => {
},
);
});

it('should render legend action on mouse hover', async() => {
const action = async() =>
await common.moveMouseRelativeToDOMElement({ left: 30, top: 10 }, '.echLegendItem');
await common.expectChartAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/legend--actions',
{
action,
delay: 200, // needed for icon to load
},
);
});
});
1 change: 1 addition & 0 deletions src/chart_types/xy_chart/utils/dimensions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe('Computed chart dimensions', () => {
verticalWidth: 10,
horizontalHeight: 10,
spacingBuffer: 10,
margin: 0,
};
const defaultTheme = LIGHT_THEME;
const chartTheme = {
Expand Down
2 changes: 0 additions & 2 deletions src/chart_types/xy_chart/utils/dimensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import { AxisSpec } from './specs';
* @param chartTheme the theme style of the chart
* @param axisDimensions the axis dimensions
* @param axisSpecs the axis specs
* @param showLegend is the legend shown
* @param legendPosition the optional legend position
* @internal
*/
export function computeChartDimensions(
Expand Down
2 changes: 1 addition & 1 deletion src/components/__snapshots__/chart.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Chart should render the legend name test 1`] = `"<div class=\\"echChart\\" style=\\"width: 100px; height: 100px;\\"><div class=\\"echChartBackground\\" style=\\"background-color: transparent;\\"></div><div class=\\"echChartStatus\\" data-ech-render-complete=\\"true\\" data-ech-render-count=\\"1\\"></div><div class=\\"echChartResizer\\"></div><div class=\\"echLegend echLegend--right echLegend--debug\\"><div style=\\"width: 50px; max-width: 50px;\\" class=\\"echLegendListContainer\\"><ul style=\\"padding-top: 10px; padding-bottom: 10px;\\" class=\\"echLegendList\\"><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#1EA593\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"test\\">test</div></li></ul></div></div><div class=\\"echContainer\\"><div class=\\"echChartPointerContainer\\" style=\\"cursor: default;\\"><div class=\\"echCrosshair\\"><div class=\\"echCrosshair__band\\" style=\\"top: -1px; left: -1px; width: 0px; height: 0px; background: rgb(245, 245, 245);\\"></div></div><canvas class=\\"echCanvasRenderer\\" width=\\"150\\" height=\\"200\\" style=\\"width: 150px; height: 200px;\\"></canvas><svg class=\\"echHighlighter\\"><defs><clipPath id=\\"echHighlighterClipPath__chart1\\"><rect x=\\"0\\" y=\\"0\\" width=\\"130\\" height=\\"180\\"></rect></clipPath></defs><g transform=\\"translate(10, 10) rotate(0)\\"></g></svg></div></div></div>"`;
exports[`Chart should render the legend name test 1`] = `"<div class=\\"echChart\\" style=\\"width: 100px; height: 100px;\\"><div class=\\"echChartBackground\\" style=\\"background-color: transparent;\\"></div><div class=\\"echChartStatus\\" data-ech-render-complete=\\"true\\" data-ech-render-count=\\"1\\"></div><div class=\\"echChartResizer\\"></div><div class=\\"echLegend echLegend--right echLegend--debug\\"><div style=\\"width: 50px; max-width: 50px; margin-left: 0px; margin-right: 0px;\\" class=\\"echLegendListContainer\\"><ul style=\\"padding-top: 10px; padding-bottom: 10px;\\" class=\\"echLegendList\\"><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#1EA593\\" focusable=\\"false\\"><defs><circle id=\\"dot-a\\" cx=\\"8\\" cy=\\"8\\" r=\\"4\\"></circle></defs><g><use xlink:href=\\"#dot-a\\"></use></g></svg></div><div class=\\"echLegendItem__label echLegendItem__label--clickable\\" title=\\"test\\">test</div></li></ul></div></div><div class=\\"echContainer\\"><div class=\\"echChartPointerContainer\\" style=\\"cursor: default;\\"><div class=\\"echCrosshair\\"><div class=\\"echCrosshair__band\\" style=\\"top: -1px; left: -1px; width: 0px; height: 0px; background: rgb(245, 245, 245);\\"></div></div><canvas class=\\"echCanvasRenderer\\" width=\\"150\\" height=\\"200\\" style=\\"width: 150px; height: 200px;\\"></canvas><svg class=\\"echHighlighter\\"><defs><clipPath id=\\"echHighlighterClipPath__chart1\\"><rect x=\\"0\\" y=\\"0\\" width=\\"130\\" height=\\"180\\"></rect></clipPath></defs><g transform=\\"translate(10, 10) rotate(0)\\"></g></svg></div></div></div>"`;
Loading