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): allow color picker component #545

Merged
merged 24 commits into from
Feb 27, 2020

Conversation

nickofthyme
Copy link
Collaborator

@nickofthyme nickofthyme commented Feb 10, 2020

Summary

Add option to pass color picker component to chart.

Closes #538

Elastic charts will maintain the color selection in memory beyond chart updates. However, to persist colors beyond browser refresh the consumer would need to manage the color state and use the color prop on the SeriesSpec to assign a color via the SeriesColorAccessor.

with FunctionComponent<LegendColorPickerProps>

<Chart>
  <Settings
    showLegend
    legendColorPicker={({ anchor, onClose, color, seriesIdentifier }) => (
      <MyCustomColorPicker
        anchor={anchor}
        onClose={onClose}
        color={color}
        seriesIdentifier={seriesIdentifier}
      />
    )}
  />
</Chart>

or with Component<LegendColorPickerProps>

<Chart>
  <Settings
    showLegend
    legendColorPicker={MyCustomColorPicker}
  />
</Chart>

where

export interface LegendColorPickerProps {
  /**
   * Anchor used to position picker
   */
  anchor: HTMLDivElement;
  /**
   * Current color of the given series
   */
  color: string;
  /**
   * Callback to close color picker and set persistent color
   */
  onClose: () => void;
  /**
   * Callback to update temporary color state
   */
  onChange: (color: string) => void;
  /**
   * Series id for the active series
   */
  seriesIdentifier: XYChartSeriesIdentifier;
}
export type LegendColorPicker = ComponentType<LegendColorPickerProps>;

The button argument is the legend item that should be used as the button prop for EuiPopover as the positioning reference.

Remove seriesColorOverrides logic which was deprecated, now unused, back when the color picker was removed from elastic charts.

Demo usage with EuiColorPicker and EuiWrappingPopover

http://localhost:9001/?path=/story/legend--color-picker

Screen Recording 2020-02-26 at 03 04 PM

Code

export const example = () => {
const [colors, setColors] = useState<Record<SeriesKey, string>>({});
const renderColorPicker: LegendColorPicker = ({ anchor, color, onClose, seriesIdentifier, onChange }) => {
const handleClose = () => {
onClose();
onCloseAction();
setColors({
...colors,
[seriesIdentifier.key]: color,
});
};
const handleChange = (color: string) => {
onChangeAction(color);
onChange(color);
};
return (
<EuiWrappingPopover isOpen button={anchor} closePopover={handleClose}>
<EuiColorPicker display="inline" color={color} onChange={handleChange}></EuiColorPicker>
<EuiSpacer size="m" />
<EuiButton fullWidth size="s" onClick={handleClose}>
Done
</EuiButton>
</EuiWrappingPopover>
);
};
return (
<Chart className="story-chart">
<Settings showLegend legendColorPicker={renderColorPicker} />
<Axis id="bottom" position={Position.Bottom} title="Bottom axis" showOverlappingTicks={true} />
<Axis id="left2" title="Left axis" position={Position.Left} tickFormat={(d: any) => Number(d).toFixed(2)} />
<BarSeries
id="bars 1"
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
splitSeriesAccessors={['g']}
data={BARCHART_1Y1G}
color={({ key }) => colors[key] ?? null}
/>
</Chart>
);
};

Checklist

  • Any consumer-facing exports were added to src/index.ts (and stories only import from ../src except for test data & storybook)
  • This was checked for cross-browser compatibility, including a check against IE11
  • Proper documentation or storybook story was added for features that require explanation or tutorials
  • Unit tests were updated or added to match the most common scenarios
  • Each commit follows the convention

@nickofthyme nickofthyme added :legend Legend related issue :vislib Relating to vislib replacement labels Feb 10, 2020
@nickofthyme nickofthyme requested a review from markov00 February 10, 2020 14:54
@markov00 markov00 mentioned this pull request Feb 10, 2020
27 tasks
@nickofthyme nickofthyme marked this pull request as ready for review February 12, 2020 01:24
Copy link
Member

@markov00 markov00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added few comments that needs to be addressed before going on with this feature

src/components/legend/legend.test.tsx Outdated Show resolved Hide resolved
src/specs/settings.tsx Outdated Show resolved Hide resolved
src/specs/settings.tsx Outdated Show resolved Hide resolved
src/components/legend/legend_item.tsx Outdated Show resolved Hide resolved
src/components/legend/legend_item.tsx Outdated Show resolved Hide resolved
src/components/legend/legend_item.tsx Outdated Show resolved Hide resolved
src/components/legend/legend_item.tsx Outdated Show resolved Hide resolved
markov00 and others added 2 commits February 14, 2020 12:44
Move `Datum`, `Rotation`, `Position` and `Color` to `utils/commons`. Decouple legend from axis position method and move the `scales` to `utils/scales`.
@nickofthyme nickofthyme requested a review from markov00 February 20, 2020 17:32
@nickofthyme nickofthyme changed the title feat: add color picker render prop feat(legend): allow color picker component Feb 21, 2020
Copy link
Member

@markov00 markov00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I've added few minor comments.
I think it will be great if you can also add a small example of the picker in storybook (maybe, you can just wait for #557 to be merged before adding it)

scripts/setup_enzyme.ts Show resolved Hide resolved
src/components/chart.tsx Show resolved Hide resolved
src/components/legend/_legend_item.scss Outdated Show resolved Hide resolved
src/components/legend/legend.test.tsx Outdated Show resolved Hide resolved
src/components/legend/legend_item.tsx Outdated Show resolved Hide resolved
src/components/legend/legend_item.tsx Outdated Show resolved Hide resolved
@codecov-io
Copy link

codecov-io commented Feb 25, 2020

Codecov Report

❗ No coverage uploaded for pull request base (master@e376620). Click here to learn what that means.
The diff coverage is 90.9%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #545   +/-   ##
=========================================
  Coverage          ?   72.09%           
=========================================
  Files             ?      213           
  Lines             ?     6197           
  Branches          ?     1185           
=========================================
  Hits              ?     4468           
  Misses            ?     1710           
  Partials          ?       19
Impacted Files Coverage Δ
src/utils/geometry.ts 100% <ø> (ø)
...art_types/xy_chart/annotations/annotation_utils.ts 100% <ø> (ø)
src/state/chart_state.ts 85.45% <ø> (ø)
...s/xy_chart/state/selectors/get_series_color_map.ts 100% <ø> (ø)
src/components/legend/legend_item.tsx 95.71% <0%> (ø)
src/specs/settings.tsx 100% <100%> (ø)
src/chart_types/xy_chart/rendering/rendering.ts 97.39% <100%> (ø)
src/chart_types/xy_chart/legend/legend.ts 92.1% <100%> (ø)
src/chart_types/xy_chart/state/utils.ts 96.38% <100%> (ø)
src/state/actions/colors.ts 88.88% <100%> (ø)
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e376620...5cf51e4. Read the comment docs.

@nickofthyme nickofthyme requested a review from markov00 February 26, 2020 00:51
Copy link
Member

@markov00 markov00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM, now I'm going through the manual test

Copy link
Member

@markov00 markov00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should rethink the implementation, see my comments below

stories/legend/9_color_picker.tsx Outdated Show resolved Hide resolved
@markov00 markov00 self-requested a review February 26, 2020 10:04
@nickofthyme
Copy link
Collaborator Author

jenkins retest this

Copy link
Member

@markov00 markov00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks great! Thanks for the cleanup on the docs also.
I've left just some very minor details comments

/**
* Helper function to get highest override color.
*
* from highest to lowest: `temporary`, `customSeriesColors` then `persisted`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

customSeriesColors => color or customColors

Comment on lines 23 to 25
clearTemporaryColors: () => void;
setTemporaryColor: (key: SeriesKey, color: string) => void;
setPersistedColor: (key: SeriesKey, color: string) => void;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
clearTemporaryColors: () => void;
setTemporaryColor: (key: SeriesKey, color: string) => void;
setPersistedColor: (key: SeriesKey, color: string) => void;
clearTemporaryColors: typeof clearTemporaryColors;
setTemporaryColor: typeof setTemporaryColor;
setPersistedColor: typeof setPersistedColor;

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this but for some reason there was a type error last time, idk but it's fixed 👍

anchor: HTMLDivElement;
/**
* Current color of the given series
*/
color: string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
color: string;
color: Color;

/**
* Callback to update temporary color state
*/
onChange: (color: string) => void;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
onChange: (color: string) => void;
onChange: (color: Color) => void;

src/state/chart_state.ts Show resolved Hide resolved
data={data}
customSeriesColors={({ key }) => colors[key] ?? null}
data={BARCHART_1Y1G}
color={({ key }) => colors[key] ?? null}
/>
</Chart>
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a description of the mechanism here:

example.story = {
  parameters: {
    info: {
      text: 'Elastic charts will maintain the color selection in memory beyond chart updates. However, to persist colors beyond browser refresh the consumer would need to manage the color state and use the color prop on the` SeriesSpec` to assign a color via the `SeriesColorAccessor`.',
    },
  },
};

Comment on lines 26 to 27
onChangeAction(color);
onChange(color);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: just to keep consistency on the code between the handleChange and the handleClose

Suggested change
onChangeAction(color);
onChange(color);
onChange(color);
onChangeAction(color);

@nickofthyme nickofthyme merged commit f1ac77c into elastic:master Feb 27, 2020
@nickofthyme nickofthyme deleted the feat/color-picker-prop branch February 27, 2020 20:45
markov00 pushed a commit that referenced this pull request Mar 2, 2020
- Add option to pass color picker component to chart
- Allow picker prop to be react component or function component
- Configure elastic charts to maintain color override state in memory
- Generalize vrt common page object and add method for clicking on element
markov00 pushed a commit that referenced this pull request Mar 17, 2020
# [18.0.0](v17.1.1...v18.0.0) (2020-03-17)

### Code Refactoring

* clean up TS types ([#554](#554)) ([22f7635](22f7635)), closes [#547](#547) [#547](#547)
* decouple tooltip from XY chart ([#553](#553)) ([e70792e](e70792e)), closes [#246](#246)

### Features

* cleaner color API on SeriesSpec ([#571](#571)) ([f769f7c](f769f7c))
* **legend:** allow color picker component render prop ([#545](#545)) ([90f4b95](90f4b95))
* **partition:** add element click, over and out events ([#578](#578)) ([103df02](103df02))
* **partition:** add tooltip ([#544](#544)) ([6bf9a69](6bf9a69)), closes [#246](#246)
* percentage display in partitioning charts ([#558](#558)) ([d6aa8d7](d6aa8d7))
* specify series name with a function on SeriesSpec ([#539](#539)) ([358455a](358455a))
* xAccessor can be a function accessor ([#574](#574)) ([bcc3d63](bcc3d63))

### BREAKING CHANGES

* The `getSpecId`, `getGroupId`, `getAxisId` and `getAnnotationId` are no longer available. Use a simple `string` instead.
* `customSeriesColors` prop on `SeriesSpec` is now `color`. The `CustomSeriesColors` type is  replaced with `SeriesColorAccessor`.
* Remove `customSubSeriesName` prop on series specs in favor of cleaner api using just the `name` prop on `SeriesSpec`. The types `SeriesStringPredicate`, `SubSeriesStringPredicate` have been removed.
* the `SeriesIdentifier` type is generalized into a simplified object with two values in common: `specId` and `key`. A specialized `XYChartSeriesIdentifier` extends now the base `SeriesIdentifier`. The `SettingsSpec` prop `showLegendDisplayValue` is renamed to `showLegendExtra` and its default value is now `false` hiding the current/last value on the legend by default.
@markov00 markov00 mentioned this pull request Mar 27, 2020
AMoo-Miki pushed a commit to AMoo-Miki/OpenSearch-Dashboards that referenced this pull request Feb 10, 2022
# [18.0.0](elastic/elastic-charts@v17.1.1...v18.0.0) (2020-03-17)

### Code Refactoring

* clean up TS types ([opensearch-project#554](elastic/elastic-charts#554)) ([6ce56fa](elastic/elastic-charts@6ce56fa)), closes [opensearch-project#547](elastic/elastic-charts#547) [opensearch-project#547](elastic/elastic-charts#547)
* decouple tooltip from XY chart ([opensearch-project#553](elastic/elastic-charts#553)) ([cb02cd0](elastic/elastic-charts@cb02cd0)), closes [opensearch-project#246](elastic/elastic-charts#246)

### Features

* cleaner color API on SeriesSpec ([opensearch-project#571](elastic/elastic-charts#571)) ([6a78c4e](elastic/elastic-charts@6a78c4e))
* **legend:** allow color picker component render prop ([opensearch-project#545](elastic/elastic-charts#545)) ([22ef1e6](elastic/elastic-charts@22ef1e6))
* **partition:** add element click, over and out events ([opensearch-project#578](elastic/elastic-charts#578)) ([4189573](elastic/elastic-charts@4189573))
* **partition:** add tooltip ([opensearch-project#544](elastic/elastic-charts#544)) ([0cffed4](elastic/elastic-charts@0cffed4)), closes [opensearch-project#246](elastic/elastic-charts#246)
* percentage display in partitioning charts ([opensearch-project#558](elastic/elastic-charts#558)) ([993a448](elastic/elastic-charts@993a448))
* specify series name with a function on SeriesSpec ([opensearch-project#539](elastic/elastic-charts#539)) ([fc6430b](elastic/elastic-charts@fc6430b))
* xAccessor can be a function accessor ([opensearch-project#574](elastic/elastic-charts#574)) ([f702e2c](elastic/elastic-charts@f702e2c))

### BREAKING CHANGES

* The `getSpecId`, `getGroupId`, `getAxisId` and `getAnnotationId` are no longer available. Use a simple `string` instead.
* `customSeriesColors` prop on `SeriesSpec` is now `color`. The `CustomSeriesColors` type is  replaced with `SeriesColorAccessor`.
* Remove `customSubSeriesName` prop on series specs in favor of cleaner api using just the `name` prop on `SeriesSpec`. The types `SeriesStringPredicate`, `SubSeriesStringPredicate` have been removed.
* the `SeriesIdentifier` type is generalized into a simplified object with two values in common: `specId` and `key`. A specialized `XYChartSeriesIdentifier` extends now the base `SeriesIdentifier`. The `SettingsSpec` prop `showLegendDisplayValue` is renamed to `showLegendExtra` and its default value is now `false` hiding the current/last value on the legend by default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:legend Legend related issue :vislib Relating to vislib replacement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Render prop for color picker component
3 participants