Skip to content

Commit

Permalink
Adds colorPalette service (#1209)
Browse files Browse the repository at this point in the history
* adds colorPalette service

* addressing some feedback

* various and sundry feedback changes

* code, palettes, docs cleanup
  • Loading branch information
Ryan Keairns authored Sep 25, 2018
1 parent cff4915 commit 584fdd2
Show file tree
Hide file tree
Showing 19 changed files with 491 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added a new `colorPalette` service for retrieving and generating color arrays for use in charts ([#1209](https://github.com/elastic/eui/pull/1209))
- Added `1` as a valid value for the `columns` prop in `EuiFlexGrid` ([#1210](https://github.com/elastic/eui/pull/1210))

## [`4.2.0`](https://github.com/elastic/eui/tree/v4.2.0)
Expand Down
32 changes: 32 additions & 0 deletions src-docs/src/components/guide_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@ $guideZLevelHighest: $euiZLevel9 + 1000;
outline: solid 2px purple;
}

.guideColorPalette__swatch {

span {
height: $euiSize;
width: $euiSizeL;
}

&:first-child span {
border-radius: $euiBorderRadius 0 0 $euiBorderRadius;
}

&:last-child span {
border-radius: 0 $euiBorderRadius $euiBorderRadius 0;
}
}

@import "../views/guidelines/index";
@import "guide_section/index";
Expand Down Expand Up @@ -193,4 +208,21 @@ $guideZLevelHighest: $euiZLevel9 + 1000;
.guidePageContent {
margin-left: 0;
}

.euiFlexGroup--responsive > .euiFlexItem.guideColorPalette__swatch {
margin-bottom: 0 !important;

span {
height: $euiSize;
width: $euiSizeL;
}

&:first-child span {
border-radius: $euiBorderRadius $euiBorderRadius 0 0;
}

&:last-child span {
border-radius: 0 0 $euiBorderRadius $euiBorderRadius;
}
}
}
10 changes: 7 additions & 3 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import WritingGuidelines

// Services

import { ColorPaletteExample }
from './views/color_palette/color_palette_example';

import { IsColorDarkExample }
from './views/is_color_dark/is_color_dark_example';

Expand Down Expand Up @@ -395,17 +398,18 @@ const navigation = [{
name: 'Utilities',
items: [
AccessibilityExample,
ColorPaletteExample,
CopyExample,
ResponsiveExample,
UtilityClassesExample,
DelayHideExample,
ErrorBoundaryExample,
HighlightExample,
IsColorDarkExample,
MutationObserverExample,
OutsideClickDetectorExample,
PortalExample,
ResponsiveExample,
ToggleExample,
UtilityClassesExample,
MutationObserverExample,
WindowEventExample,
].map(example => createExample(example)),
}, {
Expand Down
38 changes: 38 additions & 0 deletions src-docs/src/views/color_palette/color_palette.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { Fragment } from 'react';

import {
EuiFlexGroup,
EuiFlexItem,
EuiTitle,
EuiSpacer,
} from '../../../../src/components';

import {
palettes,
} from '../../../../src/services';

const paletteData = palettes;
const paletteNames = Object.keys(paletteData);

export default () => (
<Fragment>
{
paletteNames.map((paletteName, i) => (
<div key={paletteName}>
<EuiTitle key={i} size="xxs"><h3>{paletteName}</h3></EuiTitle>
<EuiSpacer size="s" />
<EuiFlexGroup gutterSize="none" alignItems="flexStart" key={`${paletteName}-${i}`}>
{
paletteData[paletteName].colors.map((hexCode, j) => (
<EuiFlexItem key={`${hexCode}-${j}`} grow={false} className={'guideColorPalette__swatch'}>
<span title={hexCode} style={{ backgroundColor: hexCode }} />
</EuiFlexItem>
))
}
</EuiFlexGroup>
<EuiSpacer size="l" />
</div>
))
}
</Fragment>
);
62 changes: 62 additions & 0 deletions src-docs/src/views/color_palette/color_palette_custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { Fragment } from 'react';

import {
EuiFlexGroup,
EuiFlexItem,
EuiTitle,
EuiSpacer,
} from '../../../../src/components';

import {
colorPalette,
palettes,
} from '../../../../src/services';

const euiColors = palettes.euiPaletteForLightBackground.colors;

export default () => (
<Fragment>
<EuiTitle size="xxs"><h3>For mapping density, low to high</h3></EuiTitle>
<EuiSpacer size="s" />
{
euiColors.map((color, j) => (
<div key={j}>
<EuiFlexGroup gutterSize="none" alignItems="flexStart" key={`${color}-${j}`}>
{
colorPalette('FFFFFF', color, 20).map((hexCode, k) => (
<EuiFlexItem key={`${hexCode}-${k}`} grow={false} className={'guideColorPalette__swatch'}>
<span title={hexCode} style={{ backgroundColor: hexCode }} />
</EuiFlexItem>
))
}
</EuiFlexGroup>
<EuiSpacer size="m" />
</div>
))
}
<EuiSpacer size="l" />
<EuiTitle size="xxs"><h3>For communicating state, trending negaitve</h3></EuiTitle>
<EuiSpacer size="s" />
<EuiFlexGroup gutterSize="none" alignItems="flexStart">
{
colorPalette('#FBEFD3', '#BD4C48').map((hexCode, l) => (
<EuiFlexItem key={`${hexCode}-${l}`} grow={false} className={'guideColorPalette__swatch'}>
<span title={hexCode} style={{ backgroundColor: hexCode }} />
</EuiFlexItem>
))
}
</EuiFlexGroup>
<EuiSpacer size="l" />
<EuiTitle size="xxs"><h3>For communicating state, trending positive</h3></EuiTitle>
<EuiSpacer size="s" />
<EuiFlexGroup gutterSize="none" alignItems="flexStart">
{
colorPalette('#FFFFE0', '#017F75').map((hexCode, l) => (
<EuiFlexItem key={`${hexCode}-${l}`} grow={false} className={'guideColorPalette__swatch'}>
<span title={hexCode} style={{ backgroundColor: hexCode }} />
</EuiFlexItem>
))
}
</EuiFlexGroup>
</Fragment>
);
92 changes: 92 additions & 0 deletions src-docs/src/views/color_palette/color_palette_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import React from 'react';

import { renderToHtml } from '../../services';

import {
GuideSectionTypes,
} from '../../components';

import {
EuiCode,
} from '../../../../src/components';

import ColorPalette from './color_palette';
const colorPaletteSource = require('!!raw-loader!./color_palette');
const colorPaletteHtml = renderToHtml(ColorPalette);

import ColorPaletteCustom from './color_palette_custom';
const colorPaletteCustomSource = require('!!raw-loader!./color_palette_custom');
const colorPaletteCustomHtml = renderToHtml(ColorPaletteCustom);

import ColorPaletteHistogram from './color_palette_histogram';
const colorPaletteHistogramSource = require('!!raw-loader!./color_palette_histogram');
const colorPaletteHistogramHtml = renderToHtml(ColorPaletteHistogram);

export const ColorPaletteExample = {
title: 'Color Palettes',
sections: [{
title: 'Preset qualitative palettes',
source: [{
type: GuideSectionTypes.JS,
code: colorPaletteSource,
}, {
type: GuideSectionTypes.HTML,
code: colorPaletteHtml,
}],
text: (
<div>
<p>
The <EuiCode>eui_palettes.js</EuiCode> file provides a base set of color palettes in
an array format. The hexidecimal color codes in these sets consist of both color safe
and EUI themed colors. Import the file, then use javascript to read and apply the color
array values to other EUI components, such as charts.
</p>
<p>
Quantitative palettes are best suited for communicating and comparing discrete
data series.
</p>
</div>
),
demo: <ColorPalette />,
}, {
title: 'Recommended quantitative palettes',
source: [{
type: GuideSectionTypes.JS,
code: colorPaletteCustomSource,
}, {
type: GuideSectionTypes.HTML,
code: colorPaletteCustomHtml,
}],
text: (
<div>
<p>
Use the <EuiCode>colorPalette</EuiCode> service to generate a custom, gradiated palette
array of any length from two hexidecimal color codes. For example, obtain an array of
yellow-to-green health status colors using
<EuiCode>colorPalette&#40;&#39;#FFFF6D&#39;, &#39;#1EA593&#39;, 20&#41;</EuiCode>.
</p>
<p>
Custom palettes are best suited for displaying data on a continuum, as in the case of
health statuses and large geographic or demographic-based data sets.
</p>
</div>
),
demo: <ColorPaletteCustom />,
}, {
title: 'Usage examples',
source: [{
type: GuideSectionTypes.JS,
code: colorPaletteHistogramSource,
}, {
type: GuideSectionTypes.HTML,
code: colorPaletteHistogramHtml,
}],
text: (
<p>
Apply the colors from <EuiCode>eui_palettes.js</EuiCode> or the <EuiCode>colorPalette</EuiCode>
service to the <EuiCode>color</EuiCode> prop of EUI chart components.
</p>
),
demo: <ColorPaletteHistogram />,
}],
};
65 changes: 65 additions & 0 deletions src-docs/src/views/color_palette/color_palette_histogram.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { Component, Fragment } from 'react';

import {
EuiSpacer,
} from '../../../../src/components';
import {
EuiSeriesChart,
EuiHistogramSeries,
EuiSeriesChartUtils,
} from '../../../../src/experimental';
import {
colorPalette,
palettes,
} from '../../../../src/services/color';

const { SCALE } = EuiSeriesChartUtils;
const timestamp = Date.now();
const ONE_HOUR = 3600000;
const margins = {
top: 10,
left: 80,
right: 0,
bottom: 20,
};
const qualColors = palettes.euiPaletteColorBlind.colors;
const quantColors = colorPalette('#FFFF6D', '#1EA593', 6);

function randomizeData(size = 24, max = 8) {
return new Array(size)
.fill(0)
.map((d, i) => ({
x0: ONE_HOUR * i,
x: ONE_HOUR * (i + 1),
y: Math.floor(Math.random() * max),
}))
.map(el => ({
x0: el.x0 + timestamp,
x: el.x + timestamp,
y: el.y,
}));
}
function buildData(series) {
const max = Math.ceil(Math.random() * 1000000);
return new Array(series).fill(0).map(() => randomizeData(20, max));
}
export default class Example extends Component {
state = {
series: 6,
data: buildData(6),
};
render() {
const { data } = this.state;
return (
<Fragment>
<EuiSeriesChart width={600} height={200} xType={SCALE.TIME} stackBy="y" margins={margins}>
{data.map((d, i) => <EuiHistogramSeries key={i} name={`Chart ${i}`} data={d} color={qualColors[i]} />)}
</EuiSeriesChart>
<EuiSpacer size="xl" />
<EuiSeriesChart width={600} height={200} xType={SCALE.TIME} stackBy="y" margins={margins}>
{data.map((d, i) => <EuiHistogramSeries key={i} name={`Chart ${i}`} data={d} color={quantColors[i]} />)}
</EuiSeriesChart>
</Fragment>
);
}
}
6 changes: 2 additions & 4 deletions src/components/series_chart/series/area_series.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import PropTypes from 'prop-types';
import { AreaSeries, AbstractSeries, LineSeries } from 'react-vis';
import { CURVE } from '../utils/chart_utils';

import { VisualizationColorType } from '../utils/visualization_color_type';

// TODO: needs to send a PR to react-vis for incorporate these changes into AreaSeries class for vertical
// area chart visualizations.
// class ExtendedAreaSeries extends AreaSeries {
Expand Down Expand Up @@ -90,8 +88,8 @@ EuiAreaSeries.propTypes = {
y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
})
).isRequired,
/** An EUI visualization color, the default value is enforced by EuiSeriesChart */
color: VisualizationColorType,
/** See eui_palettes.js or colorPalette service for recommended colors */
color: PropTypes.string,
curve: PropTypes.oneOf(Object.values(CURVE)),
onSeriesClick: PropTypes.func,
lineSize: PropTypes.number,
Expand Down
8 changes: 2 additions & 6 deletions src/components/series_chart/series/bar_series.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { VerticalBarSeries, HorizontalBarSeries, AbstractSeries } from 'react-vi
import { ORIENTATION } from '../utils/chart_utils';
import classNames from 'classnames';

import { VisualizationColorType } from '../utils/visualization_color_type';

export class EuiBarSeries extends AbstractSeries {
state = {
isMouseOverValue: false,
Expand Down Expand Up @@ -68,10 +66,8 @@ EuiBarSeries.propTypes = {
PropTypes.number
]),
})).isRequired,
/**
* An EUI visualization color, the default value is passed through EuiSeriesChart
*/
color: VisualizationColorType,
/** See eui_palettes.js or colorPalette service for recommended colors */
color: PropTypes.string,
/**
* @private passed via XYChart
*/
Expand Down
Loading

0 comments on commit 584fdd2

Please sign in to comment.