Skip to content

Commit

Permalink
feat: shift click legend items & partition legend hover (opensearch-p…
Browse files Browse the repository at this point in the history
…roject#648)

- add shit click option to negate a series click in legend
- cleanup partition styles on legend items
  • Loading branch information
nickofthyme authored Apr 24, 2020
1 parent 0779bb8 commit cf15ca1
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ describe('Legends', () => {
seriesIdentifier: seriesCollectionValue1a.seriesIdentifier,
isItemHidden: false,
isSeriesHidden: false,
isToggleable: true,
defaultExtra: nullDisplayValue,
},
];
Expand All @@ -152,6 +153,7 @@ describe('Legends', () => {
childId: 'y1',
isItemHidden: false,
isSeriesHidden: false,
isToggleable: true,
defaultExtra: nullDisplayValue,
},
{
Expand All @@ -161,6 +163,7 @@ describe('Legends', () => {
childId: 'y1',
isItemHidden: false,
isSeriesHidden: false,
isToggleable: true,
defaultExtra: nullDisplayValue,
},
];
Expand All @@ -178,6 +181,7 @@ describe('Legends', () => {
seriesIdentifier: seriesCollectionValue1a.seriesIdentifier,
isItemHidden: false,
isSeriesHidden: false,
isToggleable: true,
defaultExtra: nullDisplayValue,
},
{
Expand All @@ -187,6 +191,7 @@ describe('Legends', () => {
seriesIdentifier: seriesCollectionValue2a.seriesIdentifier,
isItemHidden: false,
isSeriesHidden: false,
isToggleable: true,
defaultExtra: nullDisplayValue,
},
];
Expand All @@ -209,6 +214,7 @@ describe('Legends', () => {
seriesIdentifier: seriesCollectionValue1a.seriesIdentifier,
isItemHidden: false,
isSeriesHidden: false,
isToggleable: true,
defaultExtra: nullDisplayValue,
},
];
Expand Down
2 changes: 2 additions & 0 deletions packages/osd-charts/src/chart_types/xy_chart/legend/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export function computeLegend(
childId: BandedAccessorType.Y1,
isSeriesHidden,
isItemHidden: hideInLegend,
isToggleable: true,
defaultExtra: {
raw: lastValue && lastValue.y1 !== null ? lastValue.y1 : null,
formatted: lastValue && lastValue.y1 !== null ? formatter(lastValue.y1) : null,
Expand All @@ -107,6 +108,7 @@ export function computeLegend(
childId: BandedAccessorType.Y0,
isSeriesHidden,
isItemHidden: hideInLegend,
isToggleable: true,
defaultExtra: {
raw: lastValue && lastValue.y0 !== null ? lastValue.y0 : null,
formatted: lastValue && lastValue.y0 !== null ? formatter(lastValue.y0) : null,
Expand Down
2 changes: 2 additions & 0 deletions packages/osd-charts/src/commons/legend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export type LegendItem = {
raw: number | null;
formatted: number | string | null;
};
// TODO: Remove when partition layers are toggleable
isToggleable?: boolean;
};

/** @internal */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Legend #legendColorPicker should match snapshot after onChange is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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--hasClickListener\\" title=\\"splita\\">splita</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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--hasClickListener\\" title=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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--hasClickListener\\" title=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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--hasClickListener\\" title=\\"splitd\\">splitd</div></li>"`;
exports[`Legend #legendColorPicker should match snapshot after onChange is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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=\\"splita\\">splita</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"#0c7b93\\" 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=\\"splitd\\">splitd</div></li>"`;

exports[`Legend #legendColorPicker should match snapshot after onClose is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splita\\">splita</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splitd\\">splitd</div></li>"`;
exports[`Legend #legendColorPicker should match snapshot after onClose is called 1`] = `"<li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splita\\">splita</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splitd\\">splitd</div></li>"`;

exports[`Legend #legendColorPicker should render colorPicker when color is clicked 1`] = `"<div id=\\"colorPicker\\"><span>Custom Color Picker</span><button id=\\"change\\">#0c7b93</button><button id=\\"close\\">close</button></div>"`;
exports[`Legend #legendColorPicker should render colorPicker when color is clicked 2`] = `"<li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splita\\">splita</div></li><div id=\\"colorPicker\\"><span>Custom Color Picker</span><button id=\\"change\\">#0c7b93</button><button id=\\"close\\">close</button></div><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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--hasClickListener\\" title=\\"splitd\\">splitd</div></li>"`;
exports[`Legend #legendColorPicker should render colorPicker when color is clicked 2`] = `"<li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splita\\">splita</div></li><div id=\\"colorPicker\\"><span>Custom Color Picker</span><button id=\\"change\\">#0c7b93</button><button id=\\"close\\">close</button></div><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splitb\\">splitb</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splitc\\">splitc</div></li><li class=\\"echLegendItem echLegendItem--right\\"><div class=\\"echLegendItem__color echLegendItem__color--changable\\" aria-label=\\"series color\\" title=\\"series color\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"16\\" height=\\"16\\" class=\\"echIcon\\" color=\\"red\\" 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=\\"splitd\\">splitd</div></li>"`;
14 changes: 5 additions & 9 deletions packages/osd-charts/src/components/legend/_legend_item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,11 @@ $legendItemVerticalPadding: $echLegendRowGap / 2;
@include euiTextTruncate;
flex: 1 1 auto;

&:hover {
cursor: pointer;
text-decoration: underline;
}
}

&__label--hasClickListener {
&:hover {
cursor: pointer;
&--clickable {
&:hover {
cursor: pointer;
text-decoration: underline;
}
}
}

Expand Down
9 changes: 5 additions & 4 deletions packages/osd-charts/src/components/legend/color.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@
* specific language governing permissions and limitations
* under the License. */

import React from 'react';
import React, { MouseEventHandler } from 'react';
import classNames from 'classnames';
import { Icon } from '../icons/icon';

interface ColorProps {
color: string;
isSeriesHidden?: boolean;
hasColorPicker: boolean;
onColorClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
onClick?: MouseEventHandler;
}

/**
* Color component used by the legend item
* @internal
*/
export function Color({ color, isSeriesHidden = false, hasColorPicker, onColorClick }: ColorProps) {
export function Color({ color, isSeriesHidden = false, hasColorPicker, onClick }: ColorProps) {
if (isSeriesHidden) {
return (
<div className="echLegendItem__color" aria-label="series hidden" title="series hidden">
Expand All @@ -45,7 +46,7 @@ export function Color({ color, isSeriesHidden = false, hasColorPicker, onColorCl
});

return (
<div onClick={onColorClick} className={colorClasses} aria-label="series color" title="series color">
<div onClick={onClick} className={colorClasses} aria-label="series color" title="series color">
<Icon type="dot" color={color} />
</div>
);
Expand Down
11 changes: 5 additions & 6 deletions packages/osd-charts/src/components/legend/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,23 @@
* specific language governing permissions and limitations
* under the License. */

import React from 'react';
import React, { MouseEventHandler } from 'react';
import classNames from 'classnames';

interface LabelProps {
label: string;
onLabelClick: (event: React.MouseEvent<Element, MouseEvent>) => void;
hasLabelClickListener: boolean;
onClick?: MouseEventHandler;
}
/**
* Label component used to display text in legend item
* @internal
*/
export function Label({ label, onLabelClick, hasLabelClickListener }: LabelProps) {
export function Label({ label, onClick }: LabelProps) {
const labelClassNames = classNames('echLegendItem__label', {
['echLegendItem__label--hasClickListener']: hasLabelClickListener,
['echLegendItem__label--clickable']: Boolean(onClick),
});
return (
<div className={labelClassNames} title={label} onClick={onLabelClick}>
<div className={labelClassNames} title={label} onClick={onClick}>
{label}
</div>
);
Expand Down
Loading

0 comments on commit cf15ca1

Please sign in to comment.