Skip to content

Commit

Permalink
feat(legend): add legend item actions and margins (opensearch-project…
Browse files Browse the repository at this point in the history
…#749)

- adds legend actions at the end of the legend items
- Adds margins on inner and outer sides of legend

closes opensearch-project#717
  • Loading branch information
nickofthyme authored Jul 17, 2020
1 parent 027a772 commit 75ce7b0
Show file tree
Hide file tree
Showing 104 changed files with 381 additions and 34 deletions.
2 changes: 2 additions & 0 deletions packages/osd-charts/.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 packages/osd-charts/.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 packages/osd-charts/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 packages/osd-charts/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 packages/osd-charts/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 packages/osd-charts/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
},
);
});
});
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
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
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

0 comments on commit 75ce7b0

Please sign in to comment.