mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Step 3] Cleanup charts plugin (#130132)
* [Step 3] Cleanup charts plugin * update JEST * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
2d188508d5
commit
f2af25db45
35 changed files with 802 additions and 581 deletions
|
@ -49,6 +49,8 @@ RUNTIME_DEPS = [
|
|||
"@npm//@elastic/eui",
|
||||
"@npm//react-use",
|
||||
"@npm//react",
|
||||
"@npm//@emotion/react",
|
||||
"@npm//@emotion/css",
|
||||
]
|
||||
|
||||
# In this array place dependencies necessary to build the types, which will include the
|
||||
|
@ -71,6 +73,8 @@ TYPES_DEPS = [
|
|||
"@npm//@types/react",
|
||||
"@npm//@elastic/eui",
|
||||
"@npm//react-use",
|
||||
"@npm//@emotion/react",
|
||||
"@npm//@emotion/css",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
.lnsPalettePanel__section {
|
||||
padding: $euiSize;
|
||||
}
|
||||
|
||||
.lnsPalettePanel__section--shaded {
|
||||
background-color: $euiColorLightestShade;
|
||||
border-bottom: $euiBorderThin;
|
||||
}
|
|
@ -8,7 +8,8 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useReducer, useMemo } from 'react';
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { EuiFormRow, htmlIdGenerator, EuiButtonGroup, EuiIconTip } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFormRow, htmlIdGenerator, EuiButtonGroup, EuiIconTip, useEuiTheme } from '@elastic/eui';
|
||||
import { PalettePicker } from './palette_picker';
|
||||
import {
|
||||
PaletteOutput,
|
||||
|
@ -19,8 +20,6 @@ import {
|
|||
RequiredPaletteParamTypes,
|
||||
} from '../../palettes';
|
||||
|
||||
import './palette_configuration.scss';
|
||||
|
||||
import { toColorRanges } from './utils';
|
||||
import { ColorRanges, ColorRangesContext } from './color_ranges';
|
||||
import { isAllColorRangesValid } from './color_ranges/color_ranges_validation';
|
||||
|
@ -72,8 +71,19 @@ export const CustomizablePalette = ({
|
|||
[localState]
|
||||
);
|
||||
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const styles = useMemo(
|
||||
() => css`
|
||||
padding: ${euiTheme.size.base};
|
||||
background-color: ${euiTheme.colors.lightestShade};
|
||||
border-bottom: ${euiTheme.border.thin};
|
||||
`,
|
||||
[euiTheme.size.base, euiTheme.colors.lightestShade, euiTheme.border.thin]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="lnsPalettePanel__section lnsPalettePanel__section--shaded">
|
||||
<div css={styles} className="lnsPalettePanel__section">
|
||||
<EuiFormRow
|
||||
display="rowCompressed"
|
||||
label={i18n.translate('coloring.dynamicColoring.palettePicker.label', {
|
||||
|
|
|
@ -3,7 +3,7 @@ pageLoadAssetSize:
|
|||
alerting: 106936
|
||||
apm: 64385
|
||||
canvas: 1066647
|
||||
charts: 95000
|
||||
charts: 55000
|
||||
cloud: 21076
|
||||
console: 46091
|
||||
core: 435325
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import React from 'react';
|
||||
import type { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const HorizontalBulletIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
width="30"
|
||||
height="22"
|
||||
viewBox="0 0 30 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
className="chart-icon__subdued"
|
||||
d="M1 13a1 1 0 00-1 1v2a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-2a1 1 0 00-1-1H1z"
|
||||
/>
|
||||
<path
|
||||
className="chart-icon__accent"
|
||||
d="M0 6a1 1 0 011-1h24a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V6z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const HorizontalBulletIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
width="30"
|
||||
height="22"
|
||||
viewBox="0 0 30 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
css={chartIcon.subdued}
|
||||
d="M1 13a1 1 0 00-1 1v2a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-1h5v1a1 1 0 102 0v-2a1 1 0 00-1-1H1z"
|
||||
/>
|
||||
<path
|
||||
css={chartIcon.accent}
|
||||
d="M0 6a1 1 0 011-1h24a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V6z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import React from 'react';
|
||||
import type { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const VerticalBulletIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
width="30"
|
||||
height="22"
|
||||
viewBox="0 0 30 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
className="chart-icon__subdued"
|
||||
d="M16 22a1 1 0 01-1-1V4a1 1 0 011-1h4a1 1 0 011 1v17a1 1 0 01-1 1h-4z"
|
||||
/>
|
||||
<path
|
||||
className="chart-icon__accent"
|
||||
d="M10 0h2a1 1 0 011 1v20a1 1 0 01-1 1h-2a1 1 0 110-2h1v-3h-1a1 1 0 110-2h1v-3h-1a1 1 0 110-2h1V7h-1a1 1 0 010-2h1V2h-1a1 1 0 010-2z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const VerticalBulletIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
width="30"
|
||||
height="22"
|
||||
viewBox="0 0 30 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
css={chartIcon.subdued}
|
||||
d="M16 22a1 1 0 01-1-1V4a1 1 0 011-1h4a1 1 0 011 1v17a1 1 0 01-1 1h-4z"
|
||||
/>
|
||||
<path
|
||||
css={chartIcon.accent}
|
||||
d="M10 0h2a1 1 0 011 1v20a1 1 0 01-1 1h-2a1 1 0 110-2h1v-3h-1a1 1 0 110-2h1v-3h-1a1 1 0 110-2h1V7h-1a1 1 0 010-2h1V2h-1a1 1 0 010-2z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -27,6 +27,17 @@ jest.mock('@elastic/charts', () => {
|
|||
};
|
||||
});
|
||||
|
||||
const actWithTimeout = (action: Function, timer: number = 1) =>
|
||||
act(
|
||||
() =>
|
||||
new Promise((resolve) =>
|
||||
setTimeout(async () => {
|
||||
await action();
|
||||
resolve();
|
||||
}, timer)
|
||||
)
|
||||
);
|
||||
|
||||
const chartsThemeService = chartPluginMock.createSetupContract().theme;
|
||||
const palettesRegistry = chartPluginMock.createPaletteRegistry();
|
||||
const formatService = fieldFormatsServiceMock.createStartContract();
|
||||
|
@ -110,6 +121,9 @@ describe('HeatmapComponent', function () {
|
|||
|
||||
it('renders the legend toggle component if uiState is set', async () => {
|
||||
const component = mountWithIntl(<HeatmapComponent {...wrapperProps} />);
|
||||
await actWithTimeout(async () => {
|
||||
await component.update();
|
||||
});
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1);
|
||||
});
|
||||
|
@ -118,6 +132,9 @@ describe('HeatmapComponent', function () {
|
|||
it('not renders the legend toggle component if uiState is undefined', async () => {
|
||||
const newProps = { ...wrapperProps, uiState: undefined } as unknown as HeatmapRenderProps;
|
||||
const component = mountWithIntl(<HeatmapComponent {...newProps} />);
|
||||
await actWithTimeout(async () => {
|
||||
await component.update();
|
||||
});
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(0);
|
||||
});
|
||||
|
@ -125,6 +142,9 @@ describe('HeatmapComponent', function () {
|
|||
|
||||
it('renders the legendColorPicker if uiState is set', async () => {
|
||||
const component = mountWithIntl(<HeatmapComponent {...wrapperProps} />);
|
||||
await actWithTimeout(async () => {
|
||||
await component.update();
|
||||
});
|
||||
await act(async () => {
|
||||
expect(component.find(Settings).prop('legendColorPicker')).toBeDefined();
|
||||
});
|
||||
|
@ -133,6 +153,9 @@ describe('HeatmapComponent', function () {
|
|||
it('not renders the legendColorPicker if uiState is undefined', async () => {
|
||||
const newProps = { ...wrapperProps, uiState: undefined } as unknown as HeatmapRenderProps;
|
||||
const component = mountWithIntl(<HeatmapComponent {...newProps} />);
|
||||
await actWithTimeout(async () => {
|
||||
await component.update();
|
||||
});
|
||||
await act(async () => {
|
||||
expect(component.find(Settings).prop('legendColorPicker')).toBeUndefined();
|
||||
});
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import { EuiIconProps } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const HeatmapIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
width={30}
|
||||
height={22}
|
||||
viewBox="0 0 30 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
className="chart-icon__accent"
|
||||
d="M16 1a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V1zM0 17a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1v-4zm17-9a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V9a1 1 0 00-1-1h-4zm-1 9a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4zm9-17a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V1a1 1 0 00-1-1h-4z"
|
||||
/>
|
||||
<path
|
||||
className="chart-icon__subdued"
|
||||
d="M0 1a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V1zm0 8a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V9zm9-9a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V1a1 1 0 00-1-1H9zM8 9a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H9a1 1 0 01-1-1V9zm1 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1v-4a1 1 0 00-1-1H9zm15-7a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V9zm1 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1v-4a1 1 0 00-1-1h-4z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const HeatmapIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
width={30}
|
||||
height={22}
|
||||
viewBox="0 0 30 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
css={chartIcon.subdued}
|
||||
d="M16 1a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V1zM0 17a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1v-4zm17-9a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V9a1 1 0 00-1-1h-4zm-1 9a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4zm9-17a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V1a1 1 0 00-1-1h-4z"
|
||||
/>
|
||||
<path
|
||||
css={chartIcon.accent}
|
||||
d="M0 1a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V1zm0 8a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H1a1 1 0 01-1-1V9zm9-9a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V1a1 1 0 00-1-1H9zM8 9a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H9a1 1 0 01-1-1V9zm1 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1v-4a1 1 0 00-1-1H9zm15-7a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V9zm1 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1v-4a1 1 0 00-1-1h-4z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -228,7 +228,7 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<Memo(LegendToggleComponent)
|
||||
<ForwardRef
|
||||
legendPosition="right"
|
||||
onClick={[Function]}
|
||||
showLegend={true}
|
||||
|
@ -656,7 +656,7 @@ exports[`PartitionVisComponent should render correct structure for mosaic 1`] =
|
|||
}
|
||||
}
|
||||
>
|
||||
<Memo(LegendToggleComponent)
|
||||
<ForwardRef
|
||||
legendPosition="right"
|
||||
onClick={[Function]}
|
||||
showLegend={true}
|
||||
|
@ -1035,7 +1035,7 @@ exports[`PartitionVisComponent should render correct structure for pie 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<Memo(LegendToggleComponent)
|
||||
<ForwardRef
|
||||
legendPosition="right"
|
||||
onClick={[Function]}
|
||||
showLegend={true}
|
||||
|
@ -1447,7 +1447,7 @@ exports[`PartitionVisComponent should render correct structure for treemap 1`] =
|
|||
}
|
||||
}
|
||||
>
|
||||
<Memo(LegendToggleComponent)
|
||||
<ForwardRef
|
||||
legendPosition="right"
|
||||
onClick={[Function]}
|
||||
showLegend={true}
|
||||
|
@ -1847,7 +1847,7 @@ exports[`PartitionVisComponent should render correct structure for waffle 1`] =
|
|||
}
|
||||
}
|
||||
>
|
||||
<Memo(LegendToggleComponent)
|
||||
<ForwardRef
|
||||
legendPosition="right"
|
||||
onClick={[Function]}
|
||||
showLegend={true}
|
||||
|
|
|
@ -34,6 +34,17 @@ jest.mock('@elastic/charts', () => {
|
|||
};
|
||||
});
|
||||
|
||||
const actWithTimeout = (action: Function, timer: number = 1) =>
|
||||
act(
|
||||
() =>
|
||||
new Promise((resolve) =>
|
||||
setTimeout(async () => {
|
||||
await action();
|
||||
resolve();
|
||||
}, timer)
|
||||
)
|
||||
);
|
||||
|
||||
const chartsThemeService = chartPluginMock.createSetupContract().theme;
|
||||
const palettesRegistry = chartPluginMock.createPaletteRegistry();
|
||||
const visParams = createMockPieParams();
|
||||
|
@ -131,13 +142,12 @@ describe('PartitionVisComponent', function () {
|
|||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders the legend on the correct position', () => {
|
||||
const component = shallow(<PartitionVisComponent {...wrapperProps} />);
|
||||
expect(component.find(Settings).prop('legendPosition')).toEqual('right');
|
||||
});
|
||||
|
||||
it('renders the legend toggle component', async () => {
|
||||
const component = mount(<PartitionVisComponent {...wrapperProps} />);
|
||||
await actWithTimeout(async () => {
|
||||
await component.update();
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
expect(findTestSubject(component, 'vislibToggleLegend').length).toBe(1);
|
||||
});
|
||||
|
@ -145,6 +155,9 @@ describe('PartitionVisComponent', function () {
|
|||
|
||||
it('hides the legend if the legend toggle is clicked', async () => {
|
||||
const component = mount(<PartitionVisComponent {...wrapperProps} />);
|
||||
await actWithTimeout(async () => {
|
||||
await component.update();
|
||||
});
|
||||
findTestSubject(component, 'vislibToggleLegend').simulate('click');
|
||||
await act(async () => {
|
||||
expect(component.find(Settings).prop('showLegend')).toEqual(false);
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const DonutIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
d="M19.21 21.119a11 11 0 006.595-8.1c.11-.577-.355-1.082-.942-1.082H20.75c-.477 0-.878.342-1.046.788a5.028 5.028 0 11-6.474-6.474c.447-.168.788-.569.788-1.046V1.094c0-.588-.505-1.053-1.082-.943a11 11 0 106.272 20.968h.002z"
|
||||
className="chart-icon__subdued"
|
||||
/>
|
||||
<path
|
||||
d="M22.778 3.176A11 11 0 0017.084.154C16.507.042 16 .507 16 1.095v4.116c0 .475.34.875.784 1.044l.14.055A5.026 5.026 0 0119.7 9.17c.168.445.568.784 1.044.784h4.115c.588 0 1.053-.506.942-1.084a11 11 0 00-3.023-5.694z"
|
||||
className="chart-icon__accent"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const DonutIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
d="M19.21 21.119a11 11 0 006.595-8.1c.11-.577-.355-1.082-.942-1.082H20.75c-.477 0-.878.342-1.046.788a5.028 5.028 0 11-6.474-6.474c.447-.168.788-.569.788-1.046V1.094c0-.588-.505-1.053-1.082-.943a11 11 0 106.272 20.968h.002z"
|
||||
css={chartIcon.subdued}
|
||||
/>
|
||||
<path
|
||||
d="M22.778 3.176A11 11 0 0017.084.154C16.507.042 16 .507 16 1.095v4.116c0 .475.34.875.784 1.044l.14.055A5.026 5.026 0 0119.7 9.17c.168.445.568.784 1.044.784h4.115c.588 0 1.053-.506.942-1.084a11 11 0 00-3.023-5.694z"
|
||||
css={chartIcon.accent}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import React from 'react';
|
||||
import type { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const MosaicIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId} /> : null}
|
||||
<path
|
||||
className="chart-icon__subdued"
|
||||
d="M2 0a1 1 0 00-1 1v2a1 1 0 001 1h6a1 1 0 001-1V1a1 1 0 00-1-1H2zM2 14a1 1 0 00-1 1v6a1 1 0 001 1h6a1 1 0 001-1v-6a1 1 0 00-1-1H2zM11 13a1 1 0 011-1h6a1 1 0 011 1v8a1 1 0 01-1 1h-6a1 1 0 01-1-1v-8zM12 0a1 1 0 100 2h6a1 1 0 100-2h-6zM21 15a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1h-6a1 1 0 01-1-1v-6zM22 0a1 1 0 00-1 1v4a1 1 0 001 1h6a1 1 0 001-1V1a1 1 0 00-1-1h-6z"
|
||||
/>
|
||||
<path
|
||||
className="chart-icon__accent"
|
||||
d="M11 5a1 1 0 011-1h6a1 1 0 011 1v4a1 1 0 01-1 1h-6a1 1 0 01-1-1V5zM1 7a1 1 0 011-1h6a1 1 0 011 1v4a1 1 0 01-1 1H2a1 1 0 01-1-1V7zM22 8a1 1 0 00-1 1v2a1 1 0 001 1h6a1 1 0 001-1V9a1 1 0 00-1-1h-6z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const MosaicIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId} /> : null}
|
||||
<path
|
||||
css={chartIcon.subdued}
|
||||
d="M2 0a1 1 0 00-1 1v2a1 1 0 001 1h6a1 1 0 001-1V1a1 1 0 00-1-1H2zM2 14a1 1 0 00-1 1v6a1 1 0 001 1h6a1 1 0 001-1v-6a1 1 0 00-1-1H2zM11 13a1 1 0 011-1h6a1 1 0 011 1v8a1 1 0 01-1 1h-6a1 1 0 01-1-1v-8zM12 0a1 1 0 100 2h6a1 1 0 100-2h-6zM21 15a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1h-6a1 1 0 01-1-1v-6zM22 0a1 1 0 00-1 1v4a1 1 0 001 1h6a1 1 0 001-1V1a1 1 0 00-1-1h-6z"
|
||||
/>
|
||||
<path
|
||||
css={chartIcon.accent}
|
||||
d="M11 5a1 1 0 011-1h6a1 1 0 011 1v4a1 1 0 01-1 1h-6a1 1 0 01-1-1V5zM1 7a1 1 0 011-1h6a1 1 0 011 1v4a1 1 0 01-1 1H2a1 1 0 01-1-1V7zM22 8a1 1 0 00-1 1v2a1 1 0 001 1h6a1 1 0 001-1V9a1 1 0 00-1-1h-6z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const PieIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
d="M17.827 21.189a10.001 10.001 0 005.952-7.148c.124-.578-.343-1.091-.935-1.091H14a1 1 0 01-1-1V3.106c0-.592-.513-1.059-1.092-.935a10 10 0 105.919 19.018z"
|
||||
className="chart-icon__subdued"
|
||||
/>
|
||||
<path
|
||||
d="M22.462 3.538A12.29 12.29 0 0016.094.16C15.512.048 15 .514 15 1.106V10a1 1 0 001 1h8.895c.591 0 1.057-.512.945-1.094a12.288 12.288 0 00-3.378-6.368z"
|
||||
className="chart-icon__accent"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const PieIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
d="M17.827 21.189a10.001 10.001 0 005.952-7.148c.124-.578-.343-1.091-.935-1.091H14a1 1 0 01-1-1V3.106c0-.592-.513-1.059-1.092-.935a10 10 0 105.919 19.018z"
|
||||
css={chartIcon.subdued}
|
||||
/>
|
||||
<path
|
||||
d="M22.462 3.538A12.29 12.29 0 0016.094.16C15.512.048 15 .514 15 1.106V10a1 1 0 001 1h8.895c.591 0 1.057-.512.945-1.094a12.288 12.288 0 00-3.378-6.368z"
|
||||
css={chartIcon.accent}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,29 +8,34 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const TreemapIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
d="M0 1a1 1 0 011-1h13a1 1 0 011 1v20a1 1 0 01-1 1H1a1 1 0 01-1-1V1z"
|
||||
className="chart-icon__subdued"
|
||||
/>
|
||||
<path
|
||||
d="M17 1a1 1 0 011-1h11a1 1 0 011 1v12a1 1 0 01-1 1H18a1 1 0 01-1-1V1z"
|
||||
className="chart-icon__accent"
|
||||
/>
|
||||
<path
|
||||
d="M29 16H18a1 1 0 00-1 1v4a1 1 0 001 1h11a1 1 0 001-1v-4a1 1 0 00-1-1z"
|
||||
className="chart-icon__subdued"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const TreemapIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId}>{title}</title> : null}
|
||||
<path
|
||||
d="M0 1a1 1 0 011-1h13a1 1 0 011 1v20a1 1 0 01-1 1H1a1 1 0 01-1-1V1z"
|
||||
css={chartIcon.subdued}
|
||||
/>
|
||||
<path
|
||||
d="M17 1a1 1 0 011-1h11a1 1 0 011 1v12a1 1 0 01-1 1H18a1 1 0 01-1-1V1z"
|
||||
css={chartIcon.accent}
|
||||
/>
|
||||
<path
|
||||
d="M29 16H18a1 1 0 00-1 1v4a1 1 0 001 1h11a1 1 0 001-1v-4a1 1 0 00-1-1z"
|
||||
css={chartIcon.subdued}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -8,25 +8,30 @@
|
|||
|
||||
import React from 'react';
|
||||
import type { EuiIconProps } from '@elastic/eui';
|
||||
import { useCommonChartStyles } from '@kbn/charts-plugin/public';
|
||||
|
||||
export const WaffleIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId} /> : null}
|
||||
<path
|
||||
className="chart-icon__accent"
|
||||
d="M16 1a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V1zM4 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1v-2zM17 6a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V7a1 1 0 00-1-1h-2zM23 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1h-2zM5 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1H5zM4 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V7zM11 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1h-2zM10 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7zM11 12a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM22 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7z"
|
||||
/>
|
||||
<path
|
||||
className="chart-icon__subdued"
|
||||
d="M22 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2zM4 19a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1v-2zM16 19a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2zM11 18a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM23 18a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM16 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export const WaffleIcon = ({ title, titleId, ...props }: Omit<EuiIconProps, 'type'>) => {
|
||||
const { chartIcon } = useCommonChartStyles();
|
||||
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 30 22"
|
||||
width={30}
|
||||
height={22}
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-labelledby={titleId}
|
||||
{...props}
|
||||
>
|
||||
{title ? <title id={titleId} /> : null}
|
||||
<path
|
||||
css={chartIcon.subdued}
|
||||
d="M16 1a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V1zM4 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1v-2zM17 6a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V7a1 1 0 00-1-1h-2zM23 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1h-2zM5 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1H5zM4 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V7zM11 0a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1V1a1 1 0 00-1-1h-2zM10 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7zM11 12a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM22 7a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1V7z"
|
||||
/>
|
||||
<path
|
||||
css={chartIcon.accent}
|
||||
d="M22 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2zM4 19a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1v-2zM16 19a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2zM11 18a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM23 18a1 1 0 00-1 1v2a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 00-1-1h-2zM16 13a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 01-1 1h-2a1 1 0 01-1-1v-2z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -20,3 +20,23 @@ export const paletteIds = [
|
|||
'warm',
|
||||
'gray',
|
||||
];
|
||||
|
||||
// This set of defaults originated in Canvas, which, at present, is the primary
|
||||
// consumer of this function. Changing this default requires a change in Canvas
|
||||
// logic, which would likely be a breaking change in 7.x.
|
||||
export const defaultCustomColors = [
|
||||
'#882E72',
|
||||
'#B178A6',
|
||||
'#D6C1DE',
|
||||
'#1965B0',
|
||||
'#5289C7',
|
||||
'#7BAFDE',
|
||||
'#4EB265',
|
||||
'#90C987',
|
||||
'#CAE0AB',
|
||||
'#F7EE55',
|
||||
'#F6C141',
|
||||
'#F1932D',
|
||||
'#E8601C',
|
||||
'#DC050C',
|
||||
];
|
||||
|
|
18
src/plugins/charts/common/expressions/palette/index.ts
Normal file
18
src/plugins/charts/common/expressions/palette/index.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { palette } from './palette';
|
||||
|
||||
export { systemPalette } from './system_palette';
|
||||
export type { SystemPaletteArguments } from './system_palette';
|
||||
|
||||
export type {
|
||||
CustomPaletteArguments,
|
||||
CustomPaletteState,
|
||||
PaletteExpressionFunctionDefinition,
|
||||
} from './types';
|
|
@ -6,14 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
import type { PaletteOutput } from '@kbn/coloring';
|
||||
import {
|
||||
palette,
|
||||
defaultCustomColors,
|
||||
systemPalette,
|
||||
CustomPaletteState,
|
||||
CustomPaletteArguments,
|
||||
} from './palette';
|
||||
import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils';
|
||||
import { palette, CustomPaletteState, CustomPaletteArguments } from '.';
|
||||
import { defaultCustomColors } from '../../constants';
|
||||
|
||||
describe('palette', () => {
|
||||
const fn = functionWrapper(palette()) as (
|
||||
|
@ -21,70 +16,70 @@ describe('palette', () => {
|
|||
args?: Partial<CustomPaletteArguments>
|
||||
) => PaletteOutput<CustomPaletteState>;
|
||||
|
||||
it('results a palette', () => {
|
||||
const result = fn(null);
|
||||
it('results a palette', async () => {
|
||||
const result = await fn(null);
|
||||
expect(result).toHaveProperty('type', 'palette');
|
||||
});
|
||||
|
||||
describe('args', () => {
|
||||
describe('color', () => {
|
||||
it('sets colors', () => {
|
||||
const result = fn(null, { color: ['red', 'green', 'blue'] });
|
||||
it('sets colors', async () => {
|
||||
const result = await fn(null, { color: ['red', 'green', 'blue'] });
|
||||
expect(result.params!.colors).toEqual(['red', 'green', 'blue']);
|
||||
});
|
||||
|
||||
it('defaults to pault_tor_14 colors', () => {
|
||||
const result = fn(null);
|
||||
it('defaults to pault_tor_14 colors', async () => {
|
||||
const result = await fn(null);
|
||||
expect(result.params!.colors).toEqual(defaultCustomColors);
|
||||
});
|
||||
});
|
||||
|
||||
describe('stop', () => {
|
||||
it('sets stops', () => {
|
||||
const result = fn(null, { color: ['red', 'green', 'blue'], stop: [1, 2, 3] });
|
||||
it('sets stops', async () => {
|
||||
const result = await fn(null, { color: ['red', 'green', 'blue'], stop: [1, 2, 3] });
|
||||
expect(result.params!.stops).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('defaults to pault_tor_14 colors', () => {
|
||||
const result = fn(null);
|
||||
it('defaults to pault_tor_14 colors', async () => {
|
||||
const result = await fn(null);
|
||||
expect(result.params!.colors).toEqual(defaultCustomColors);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gradient', () => {
|
||||
it('sets gradient', () => {
|
||||
let result = fn(null, { gradient: true });
|
||||
it('sets gradient', async () => {
|
||||
let result = await fn(null, { gradient: true });
|
||||
expect(result.params).toHaveProperty('gradient', true);
|
||||
|
||||
result = fn(null, { gradient: false });
|
||||
result = await fn(null, { gradient: false });
|
||||
expect(result.params).toHaveProperty('gradient', false);
|
||||
});
|
||||
|
||||
it('defaults to false', () => {
|
||||
const result = fn(null);
|
||||
it('defaults to false', async () => {
|
||||
const result = await fn(null);
|
||||
expect(result.params).toHaveProperty('gradient', false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverse', () => {
|
||||
it('reverses order of the colors', () => {
|
||||
const result = fn(null, { reverse: true });
|
||||
it('reverses order of the colors', async () => {
|
||||
const result = await fn(null, { reverse: true });
|
||||
expect(result.params!.colors).toEqual(defaultCustomColors.reverse());
|
||||
});
|
||||
|
||||
it('keeps the original order of the colors', () => {
|
||||
const result = fn(null, { reverse: false });
|
||||
it('keeps the original order of the colors', async () => {
|
||||
const result = await fn(null, { reverse: false });
|
||||
expect(result.params!.colors).toEqual(defaultCustomColors);
|
||||
});
|
||||
|
||||
it(`defaults to 'false`, () => {
|
||||
const result = fn(null);
|
||||
it(`defaults to 'false`, async () => {
|
||||
const result = await fn(null);
|
||||
expect(result.params!.colors).toEqual(defaultCustomColors);
|
||||
});
|
||||
|
||||
it('keeps the stops order pristine when set', () => {
|
||||
it('keeps the stops order pristine when set', async () => {
|
||||
const stops = [1, 2, 3];
|
||||
const result = fn(null, {
|
||||
const result = await fn(null, {
|
||||
color: ['red', 'green', 'blue'],
|
||||
stop: [1, 2, 3],
|
||||
reverse: true,
|
||||
|
@ -94,20 +89,3 @@ describe('palette', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('system_palette', () => {
|
||||
const fn = functionWrapper(systemPalette()) as (
|
||||
context: null,
|
||||
args: { name: string; params?: unknown }
|
||||
) => PaletteOutput<unknown>;
|
||||
|
||||
it('results a palette', () => {
|
||||
const result = fn(null, { name: 'test' });
|
||||
expect(result).toHaveProperty('type', 'palette');
|
||||
});
|
||||
|
||||
it('returns the name', () => {
|
||||
const result = fn(null, { name: 'test' });
|
||||
expect(result).toHaveProperty('name', 'test');
|
||||
});
|
||||
});
|
92
src/plugins/charts/common/expressions/palette/palette.ts
Normal file
92
src/plugins/charts/common/expressions/palette/palette.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { PaletteExpressionFunctionDefinition } from './types';
|
||||
|
||||
export function palette(): PaletteExpressionFunctionDefinition {
|
||||
return {
|
||||
name: 'palette',
|
||||
aliases: [],
|
||||
type: 'palette',
|
||||
inputTypes: ['null'],
|
||||
help: i18n.translate('charts.functions.paletteHelpText', {
|
||||
defaultMessage: 'Creates a color palette.',
|
||||
}),
|
||||
args: {
|
||||
color: {
|
||||
aliases: ['_'],
|
||||
multi: true,
|
||||
types: ['string'],
|
||||
help: i18n.translate('charts.functions.palette.args.colorHelpText', {
|
||||
defaultMessage:
|
||||
'The palette colors. Accepts an {html} color name, {hex}, {hsl}, {hsla}, {rgb}, or {rgba}.',
|
||||
values: {
|
||||
html: 'HTML',
|
||||
rgb: 'RGB',
|
||||
rgba: 'RGBA',
|
||||
hex: 'HEX',
|
||||
hsl: 'HSL',
|
||||
hsla: 'HSLA',
|
||||
},
|
||||
}),
|
||||
required: false,
|
||||
},
|
||||
stop: {
|
||||
multi: true,
|
||||
types: ['number'],
|
||||
help: i18n.translate('charts.functions.palette.args.stopHelpText', {
|
||||
defaultMessage:
|
||||
'The palette color stops. When used, it must be associated with each color.',
|
||||
}),
|
||||
required: false,
|
||||
},
|
||||
continuity: {
|
||||
types: ['string'],
|
||||
options: ['above', 'below', 'all', 'none'],
|
||||
default: 'above',
|
||||
help: '',
|
||||
},
|
||||
rangeMin: {
|
||||
types: ['number'],
|
||||
help: '',
|
||||
},
|
||||
rangeMax: {
|
||||
types: ['number'],
|
||||
help: '',
|
||||
},
|
||||
range: {
|
||||
types: ['string'],
|
||||
options: ['number', 'percent'],
|
||||
default: 'percent',
|
||||
help: '',
|
||||
},
|
||||
gradient: {
|
||||
types: ['boolean'],
|
||||
default: false,
|
||||
help: i18n.translate('charts.functions.palette.args.gradientHelpText', {
|
||||
defaultMessage: 'Make a gradient palette where supported?',
|
||||
}),
|
||||
options: [true, false],
|
||||
},
|
||||
reverse: {
|
||||
types: ['boolean'],
|
||||
default: false,
|
||||
help: i18n.translate('charts.functions.palette.args.reverseHelpText', {
|
||||
defaultMessage: 'Reverse the palette?',
|
||||
}),
|
||||
options: [true, false],
|
||||
},
|
||||
},
|
||||
async fn(...args) {
|
||||
/** Build optimization: prevent adding extra code into initial bundle **/
|
||||
const { paletteExpressionFn } = await import('./palette_fn');
|
||||
return paletteExpressionFn(...args);
|
||||
},
|
||||
};
|
||||
}
|
53
src/plugins/charts/common/expressions/palette/palette_fn.ts
Normal file
53
src/plugins/charts/common/expressions/palette/palette_fn.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { last } from 'lodash';
|
||||
import { checkIsMaxContinuity, checkIsMinContinuity } from '@kbn/coloring';
|
||||
import type { PaletteExpressionFunctionDefinition } from './types';
|
||||
import { defaultCustomColors } from '../../constants';
|
||||
|
||||
export const paletteExpressionFn: PaletteExpressionFunctionDefinition['fn'] = async (
|
||||
input,
|
||||
args
|
||||
) => {
|
||||
const { color, continuity, reverse, gradient, stop, range, rangeMin, rangeMax } = args;
|
||||
const colors = ([] as string[]).concat(color || defaultCustomColors);
|
||||
const stops = ([] as number[]).concat(stop || []);
|
||||
if (stops.length > 0 && colors.length !== stops.length) {
|
||||
throw Error('When stop is used, each color must have an associated stop value.');
|
||||
}
|
||||
|
||||
// If the user has defined stops, choose rangeMin/Max, provided by user or range,
|
||||
// taken from first/last element of ranges or default range (0 or 100).
|
||||
const calculateRange = (
|
||||
userRange: number | undefined,
|
||||
stopsRange: number | undefined,
|
||||
defaultRange: number
|
||||
) => userRange ?? stopsRange ?? defaultRange;
|
||||
|
||||
const rangeMinDefault = 0;
|
||||
const rangeMaxDefault = 100;
|
||||
|
||||
return {
|
||||
type: 'palette',
|
||||
name: 'custom',
|
||||
params: {
|
||||
colors: reverse ? colors.reverse() : colors,
|
||||
stops,
|
||||
range: range ?? 'percent',
|
||||
gradient,
|
||||
continuity,
|
||||
rangeMin: checkIsMinContinuity(continuity)
|
||||
? Number.NEGATIVE_INFINITY
|
||||
: calculateRange(rangeMin, stops[0], rangeMinDefault),
|
||||
rangeMax: checkIsMaxContinuity(continuity)
|
||||
? Number.POSITIVE_INFINITY
|
||||
: calculateRange(rangeMax, last(stops), rangeMaxDefault),
|
||||
},
|
||||
};
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import type { PaletteOutput } from '@kbn/coloring';
|
||||
import { functionWrapper } from '@kbn/expressions-plugin/common/expression_functions/specs/tests/utils';
|
||||
import { systemPalette } from './system_palette';
|
||||
|
||||
describe('system_palette', () => {
|
||||
const fn = functionWrapper(systemPalette()) as (
|
||||
context: null,
|
||||
args: { name: string; params?: unknown }
|
||||
) => PaletteOutput<unknown>;
|
||||
|
||||
it('results a palette', () => {
|
||||
const result = fn(null, { name: 'test' });
|
||||
expect(result).toHaveProperty('type', 'palette');
|
||||
});
|
||||
|
||||
it('returns the name', () => {
|
||||
const result = fn(null, { name: 'test' });
|
||||
expect(result).toHaveProperty('name', 'test');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common';
|
||||
import type { PaletteOutput } from './types';
|
||||
import { paletteIds } from '../../constants';
|
||||
|
||||
export interface SystemPaletteArguments {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export function systemPalette(): ExpressionFunctionDefinition<
|
||||
'system_palette',
|
||||
null,
|
||||
SystemPaletteArguments,
|
||||
PaletteOutput
|
||||
> {
|
||||
return {
|
||||
name: 'system_palette',
|
||||
aliases: [],
|
||||
type: 'palette',
|
||||
inputTypes: ['null'],
|
||||
help: i18n.translate('charts.functions.systemPaletteHelpText', {
|
||||
defaultMessage: 'Creates a dynamic color palette.',
|
||||
}),
|
||||
args: {
|
||||
name: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('charts.functions.systemPalette.args.nameHelpText', {
|
||||
defaultMessage: 'Name of the palette in the palette list',
|
||||
}),
|
||||
options: paletteIds,
|
||||
},
|
||||
},
|
||||
fn: (input, args) => {
|
||||
return {
|
||||
type: 'palette',
|
||||
name: args.name,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
43
src/plugins/charts/common/expressions/palette/types.ts
Normal file
43
src/plugins/charts/common/expressions/palette/types.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import type { PaletteContinuity } from '@kbn/coloring';
|
||||
import type { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common';
|
||||
|
||||
export interface PaletteOutput<T = { [key: string]: unknown }> {
|
||||
type: 'palette' | 'system_palette';
|
||||
name: string;
|
||||
params?: T;
|
||||
}
|
||||
|
||||
export interface CustomPaletteArguments {
|
||||
color?: string[];
|
||||
gradient: boolean;
|
||||
reverse?: boolean;
|
||||
stop?: number[];
|
||||
range?: 'number' | 'percent';
|
||||
rangeMin?: number;
|
||||
rangeMax?: number;
|
||||
continuity?: PaletteContinuity;
|
||||
}
|
||||
|
||||
export interface CustomPaletteState {
|
||||
colors: string[];
|
||||
gradient: boolean;
|
||||
stops: number[];
|
||||
range: 'number' | 'percent';
|
||||
rangeMin: number;
|
||||
rangeMax: number;
|
||||
continuity?: PaletteContinuity;
|
||||
}
|
||||
|
||||
export type PaletteExpressionFunctionDefinition = ExpressionFunctionDefinition<
|
||||
'palette',
|
||||
null,
|
||||
CustomPaletteArguments,
|
||||
Promise<PaletteOutput<CustomPaletteState>>
|
||||
>;
|
|
@ -9,11 +9,14 @@
|
|||
export const COLOR_MAPPING_SETTING = 'visualization:colorMapping';
|
||||
export const LEGACY_TIME_AXIS = 'visualization:useLegacyTimeAxis';
|
||||
|
||||
export type { CustomPaletteArguments, CustomPaletteState, SystemPaletteArguments } from './palette';
|
||||
export type {
|
||||
CustomPaletteArguments,
|
||||
CustomPaletteState,
|
||||
SystemPaletteArguments,
|
||||
} from './expressions/palette';
|
||||
export { palette, systemPalette } from './expressions/palette';
|
||||
|
||||
export { defaultCustomColors, palette, systemPalette } from './palette';
|
||||
|
||||
export { paletteIds } from './constants';
|
||||
export { paletteIds, defaultCustomColors } from './constants';
|
||||
export type { ColorSchema, RawColorSchema, ColorMap } from './static';
|
||||
export {
|
||||
ColorSchemas,
|
||||
|
@ -29,11 +32,3 @@ export {
|
|||
} from './static';
|
||||
|
||||
export type { ColorSchemaParams, Labels, Style } from './types';
|
||||
|
||||
/** @deprecated **/
|
||||
/** Please import directly from @kbn/coloring **/
|
||||
export { checkIsMinContinuity, checkIsMaxContinuity } from '@kbn/coloring';
|
||||
|
||||
/** @deprecated **/
|
||||
/** Please import directly from @kbn/coloring **/
|
||||
export type { PaletteOutput, PaletteContinuity } from '@kbn/coloring';
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common';
|
||||
import type { PaletteContinuity } from '@kbn/coloring';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { checkIsMaxContinuity, checkIsMinContinuity } from '@kbn/coloring';
|
||||
import { last } from 'lodash';
|
||||
import { paletteIds } from './constants';
|
||||
|
||||
export interface CustomPaletteArguments {
|
||||
color?: string[];
|
||||
gradient: boolean;
|
||||
reverse?: boolean;
|
||||
stop?: number[];
|
||||
range?: 'number' | 'percent';
|
||||
rangeMin?: number;
|
||||
rangeMax?: number;
|
||||
continuity?: PaletteContinuity;
|
||||
}
|
||||
|
||||
export interface CustomPaletteState {
|
||||
colors: string[];
|
||||
gradient: boolean;
|
||||
stops: number[];
|
||||
range: 'number' | 'percent';
|
||||
rangeMin: number;
|
||||
rangeMax: number;
|
||||
continuity?: PaletteContinuity;
|
||||
}
|
||||
|
||||
export interface SystemPaletteArguments {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface PaletteOutput<T = { [key: string]: unknown }> {
|
||||
type: 'palette' | 'system_palette';
|
||||
name: string;
|
||||
params?: T;
|
||||
}
|
||||
|
||||
export const defaultCustomColors = [
|
||||
// This set of defaults originated in Canvas, which, at present, is the primary
|
||||
// consumer of this function. Changing this default requires a change in Canvas
|
||||
// logic, which would likely be a breaking change in 7.x.
|
||||
'#882E72',
|
||||
'#B178A6',
|
||||
'#D6C1DE',
|
||||
'#1965B0',
|
||||
'#5289C7',
|
||||
'#7BAFDE',
|
||||
'#4EB265',
|
||||
'#90C987',
|
||||
'#CAE0AB',
|
||||
'#F7EE55',
|
||||
'#F6C141',
|
||||
'#F1932D',
|
||||
'#E8601C',
|
||||
'#DC050C',
|
||||
];
|
||||
|
||||
export function palette(): ExpressionFunctionDefinition<
|
||||
'palette',
|
||||
null,
|
||||
CustomPaletteArguments,
|
||||
PaletteOutput<CustomPaletteState>
|
||||
> {
|
||||
return {
|
||||
name: 'palette',
|
||||
aliases: [],
|
||||
type: 'palette',
|
||||
inputTypes: ['null'],
|
||||
help: i18n.translate('charts.functions.paletteHelpText', {
|
||||
defaultMessage: 'Creates a color palette.',
|
||||
}),
|
||||
args: {
|
||||
color: {
|
||||
aliases: ['_'],
|
||||
multi: true,
|
||||
types: ['string'],
|
||||
help: i18n.translate('charts.functions.palette.args.colorHelpText', {
|
||||
defaultMessage:
|
||||
'The palette colors. Accepts an {html} color name, {hex}, {hsl}, {hsla}, {rgb}, or {rgba}.',
|
||||
values: {
|
||||
html: 'HTML',
|
||||
rgb: 'RGB',
|
||||
rgba: 'RGBA',
|
||||
hex: 'HEX',
|
||||
hsl: 'HSL',
|
||||
hsla: 'HSLA',
|
||||
},
|
||||
}),
|
||||
required: false,
|
||||
},
|
||||
stop: {
|
||||
multi: true,
|
||||
types: ['number'],
|
||||
help: i18n.translate('charts.functions.palette.args.stopHelpText', {
|
||||
defaultMessage:
|
||||
'The palette color stops. When used, it must be associated with each color.',
|
||||
}),
|
||||
required: false,
|
||||
},
|
||||
continuity: {
|
||||
types: ['string'],
|
||||
options: ['above', 'below', 'all', 'none'],
|
||||
default: 'above',
|
||||
help: '',
|
||||
},
|
||||
rangeMin: {
|
||||
types: ['number'],
|
||||
help: '',
|
||||
},
|
||||
rangeMax: {
|
||||
types: ['number'],
|
||||
help: '',
|
||||
},
|
||||
range: {
|
||||
types: ['string'],
|
||||
options: ['number', 'percent'],
|
||||
default: 'percent',
|
||||
help: '',
|
||||
},
|
||||
gradient: {
|
||||
types: ['boolean'],
|
||||
default: false,
|
||||
help: i18n.translate('charts.functions.palette.args.gradientHelpText', {
|
||||
defaultMessage: 'Make a gradient palette where supported?',
|
||||
}),
|
||||
options: [true, false],
|
||||
},
|
||||
reverse: {
|
||||
types: ['boolean'],
|
||||
default: false,
|
||||
help: i18n.translate('charts.functions.palette.args.reverseHelpText', {
|
||||
defaultMessage: 'Reverse the palette?',
|
||||
}),
|
||||
options: [true, false],
|
||||
},
|
||||
},
|
||||
fn: (input, args) => {
|
||||
const { color, continuity, reverse, gradient, stop, range, rangeMin, rangeMax } = args;
|
||||
const colors = ([] as string[]).concat(color || defaultCustomColors);
|
||||
const stops = ([] as number[]).concat(stop || []);
|
||||
if (stops.length > 0 && colors.length !== stops.length) {
|
||||
throw Error('When stop is used, each color must have an associated stop value.');
|
||||
}
|
||||
|
||||
// If the user has defined stops, choose rangeMin/Max, provided by user or range,
|
||||
// taken from first/last element of ranges or default range (0 or 100).
|
||||
const calculateRange = (
|
||||
userRange: number | undefined,
|
||||
stopsRange: number | undefined,
|
||||
defaultRange: number
|
||||
) => userRange ?? stopsRange ?? defaultRange;
|
||||
|
||||
const rangeMinDefault = 0;
|
||||
const rangeMaxDefault = 100;
|
||||
|
||||
return {
|
||||
type: 'palette',
|
||||
name: 'custom',
|
||||
params: {
|
||||
colors: reverse ? colors.reverse() : colors,
|
||||
stops,
|
||||
range: range ?? 'percent',
|
||||
gradient,
|
||||
continuity,
|
||||
rangeMin: checkIsMinContinuity(continuity)
|
||||
? Number.NEGATIVE_INFINITY
|
||||
: calculateRange(rangeMin, stops[0], rangeMinDefault),
|
||||
rangeMax: checkIsMaxContinuity(continuity)
|
||||
? Number.POSITIVE_INFINITY
|
||||
: calculateRange(rangeMax, last(stops), rangeMaxDefault),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function systemPalette(): ExpressionFunctionDefinition<
|
||||
'system_palette',
|
||||
null,
|
||||
SystemPaletteArguments,
|
||||
PaletteOutput
|
||||
> {
|
||||
return {
|
||||
name: 'system_palette',
|
||||
aliases: [],
|
||||
type: 'palette',
|
||||
inputTypes: ['null'],
|
||||
help: i18n.translate('charts.functions.systemPaletteHelpText', {
|
||||
defaultMessage: 'Creates a dynamic color palette.',
|
||||
}),
|
||||
args: {
|
||||
name: {
|
||||
types: ['string'],
|
||||
help: i18n.translate('charts.functions.systemPalette.args.nameHelpText', {
|
||||
defaultMessage: 'Name of the palette in the palette list',
|
||||
}),
|
||||
options: paletteIds,
|
||||
},
|
||||
},
|
||||
fn: (input, args) => {
|
||||
return {
|
||||
type: 'palette',
|
||||
name: args.name,
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
|
@ -42,7 +42,3 @@ export {
|
|||
LabelRotation,
|
||||
defaultCountLabel,
|
||||
} from '../common';
|
||||
|
||||
/** @deprecated **/
|
||||
/** Please import directly from @kbn/coloring **/
|
||||
export type { SeriesLayer, PaletteRegistry, PaletteOutput, PaletteDefinition } from '@kbn/coloring';
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
$visColorPickerWidth: $euiSizeL * 8; // 8 columns
|
||||
|
||||
.visColorPicker__value {
|
||||
width: $visColorPickerWidth;
|
||||
}
|
||||
|
||||
.visColorPicker__colorBtn {
|
||||
position: relative;
|
||||
|
||||
input[type='radio'] {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.visColorPicker__valueDot {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
&-isSelected {
|
||||
border: $euiSizeXS solid;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
|
@ -6,9 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, { BaseSyntheticEvent } from 'react';
|
||||
|
||||
import React, { BaseSyntheticEvent, useMemo } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import {
|
||||
EuiButtonEmpty,
|
||||
EuiFlexItem,
|
||||
|
@ -16,10 +15,10 @@ import {
|
|||
euiPaletteColorBlind,
|
||||
EuiScreenReaderOnly,
|
||||
EuiFlexGroup,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { lightenColor } from '../../services/palettes/lighten_color';
|
||||
import './color_picker.scss';
|
||||
|
||||
export const legacyColors: string[] = [
|
||||
'#3F6833',
|
||||
|
@ -80,7 +79,7 @@ export const legacyColors: string[] = [
|
|||
'#DEDAF7',
|
||||
];
|
||||
|
||||
interface ColorPickerProps {
|
||||
export interface ColorPickerProps {
|
||||
/**
|
||||
* Label that characterizes the color that is going to change
|
||||
*/
|
||||
|
@ -116,6 +115,24 @@ interface ColorPickerProps {
|
|||
}
|
||||
const euiColors = euiPaletteColorBlind({ rotations: 4, order: 'group' });
|
||||
|
||||
const visColorPickerColorBtnStyle = css`
|
||||
position: relative;
|
||||
input[type='radio'] {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
`;
|
||||
|
||||
const visColorPickerValueDotStyle = css`
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
`;
|
||||
|
||||
export const ColorPicker = ({
|
||||
onChange,
|
||||
color: selectedColor,
|
||||
|
@ -127,6 +144,22 @@ export const ColorPicker = ({
|
|||
layerIndex,
|
||||
}: ColorPickerProps) => {
|
||||
const legendColors = useLegacyColors ? legacyColors : euiColors;
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const visColorPickerValueStyle = useMemo(
|
||||
() => css`
|
||||
width: calc(${euiTheme.size.l} * 8);
|
||||
`,
|
||||
[euiTheme.size.l]
|
||||
);
|
||||
|
||||
const visColorPickerValueDotSelectedStyle = useMemo(
|
||||
() => css`
|
||||
border: ${euiTheme.size.xs} solid;
|
||||
border-radius: 100%;
|
||||
`,
|
||||
[euiTheme.size.xs]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="visColorPicker">
|
||||
|
@ -140,9 +173,18 @@ export const ColorPicker = ({
|
|||
/>
|
||||
</legend>
|
||||
</EuiScreenReaderOnly>
|
||||
<EuiFlexGroup wrap={true} gutterSize="none" className="visColorPicker__value">
|
||||
<EuiFlexGroup
|
||||
wrap={true}
|
||||
gutterSize="none"
|
||||
css={visColorPickerValueStyle}
|
||||
className="visColorPicker__value"
|
||||
>
|
||||
{legendColors.map((color) => (
|
||||
<label key={color} className="visColorPicker__colorBtn">
|
||||
<label
|
||||
key={color}
|
||||
css={visColorPickerColorBtnStyle}
|
||||
className="visColorPicker__colorBtn"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
onChange={(e) => onChange(color, e)}
|
||||
|
@ -155,9 +197,11 @@ export const ColorPicker = ({
|
|||
type="dot"
|
||||
size="l"
|
||||
color={selectedColor}
|
||||
className={classNames('visColorPicker__valueDot', {
|
||||
'visColorPicker__valueDot-isSelected': color === selectedColor,
|
||||
})}
|
||||
css={[
|
||||
visColorPickerValueDotStyle,
|
||||
color === selectedColor ? visColorPickerValueDotSelectedStyle : null,
|
||||
]}
|
||||
className="visColorPicker__valueDot"
|
||||
style={{ color }}
|
||||
data-test-subj={`visColorPickerColor-${color}`}
|
||||
/>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
.chart-icon__subdued {
|
||||
fill: $euiTextSubduedColor;
|
||||
}
|
||||
|
||||
.chart-icon__accent {
|
||||
fill: $euiColorVis0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { css } from '@emotion/react';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useCommonChartStyles = () => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const subdued = useMemo(
|
||||
() => css`
|
||||
fill: ${euiTheme.colors.subdued};
|
||||
`,
|
||||
[euiTheme.colors.subdued]
|
||||
);
|
||||
|
||||
const accent = css`
|
||||
fill: ${euiThemeVars.euiColorVis0};
|
||||
`;
|
||||
|
||||
return {
|
||||
chartIcon: { subdued, accent },
|
||||
};
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
.chart__empty-placeholder {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
|
@ -9,8 +9,23 @@
|
|||
import React from 'react';
|
||||
import { EuiIcon, EuiText, IconType, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import './empty_placeholder.scss';
|
||||
import classnames from 'classnames';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
export interface EmptyPlaceholderProps {
|
||||
icon: IconType;
|
||||
iconColor?: string;
|
||||
message?: JSX.Element;
|
||||
dataTestSubj?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const style = css`
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
export const EmptyPlaceholder = ({
|
||||
icon,
|
||||
|
@ -18,24 +33,17 @@ export const EmptyPlaceholder = ({
|
|||
message = <FormattedMessage id="charts.noDataLabel" defaultMessage="No results found" />,
|
||||
dataTestSubj = 'emptyPlaceholder',
|
||||
className,
|
||||
}: {
|
||||
icon: IconType;
|
||||
iconColor?: string;
|
||||
message?: JSX.Element;
|
||||
dataTestSubj?: string;
|
||||
className?: string;
|
||||
}) => (
|
||||
<>
|
||||
<EuiText
|
||||
data-test-subj={dataTestSubj}
|
||||
className={classnames('chart__empty-placeholder', className)}
|
||||
textAlign="center"
|
||||
color="subdued"
|
||||
size="xs"
|
||||
>
|
||||
<EuiIcon type={icon} color={iconColor} size="l" />
|
||||
<EuiSpacer size="s" />
|
||||
<p>{message}</p>
|
||||
</EuiText>
|
||||
</>
|
||||
}: EmptyPlaceholderProps) => (
|
||||
<EuiText
|
||||
data-test-subj={dataTestSubj}
|
||||
css={style}
|
||||
className={className}
|
||||
textAlign="center"
|
||||
color="subdued"
|
||||
size="xs"
|
||||
>
|
||||
<EuiIcon type={icon} color={iconColor} size="l" />
|
||||
<EuiSpacer size="s" />
|
||||
<p>{message}</p>
|
||||
</EuiText>
|
||||
);
|
||||
|
|
|
@ -6,9 +6,45 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { LegendToggle } from './legend_toggle';
|
||||
export { ColorPicker } from './color_picker';
|
||||
import React from 'react';
|
||||
import { withSuspense } from '@kbn/shared-ux-utility';
|
||||
|
||||
export { CurrentTime } from './current_time';
|
||||
export { EmptyPlaceholder } from './empty_placeholder';
|
||||
import './common_chart_styles.scss';
|
||||
|
||||
export { useCommonChartStyles } from './common_chart_styles';
|
||||
export * from './endzones';
|
||||
|
||||
/**
|
||||
* The Lazily-loaded `ColorPicker` component. Consumers should use `React.Suspense` or
|
||||
* the withSuspense` HOC to load this component.
|
||||
*/
|
||||
export const ColorPickerLazy = React.lazy(() =>
|
||||
import('./color_picker').then(({ ColorPicker }) => ({
|
||||
default: ColorPicker,
|
||||
}))
|
||||
);
|
||||
|
||||
/**
|
||||
* A `ColorPicker` component that is wrapped by the `withSuspense` HOC. This component can
|
||||
* be used directly by consumers and will load the `ColorPickerLazy` component lazily with
|
||||
* a predefined fallback and error boundary.
|
||||
*/
|
||||
export const ColorPicker = withSuspense(ColorPickerLazy);
|
||||
|
||||
/**
|
||||
* The Lazily-loaded `LegendToggle` component. Consumers should use `React.Suspense` or
|
||||
* the withSuspense` HOC to load this component.
|
||||
*/
|
||||
export const LegendToggleLazy = React.lazy(() =>
|
||||
import('./legend_toggle').then(({ LegendToggle }) => ({
|
||||
default: LegendToggle,
|
||||
}))
|
||||
);
|
||||
|
||||
/**
|
||||
* A `LegendToggle` component that is wrapped by the `withSuspense` HOC. This component can
|
||||
* be used directly by consumers and will load the `LegendToggleLazy` component lazily with
|
||||
* a predefined fallback and error boundary.
|
||||
*/
|
||||
export const LegendToggle = withSuspense(LegendToggleLazy);
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
.echLegend__toggle {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
margin: $euiSizeXS;
|
||||
|
||||
&--isOpen {
|
||||
background-color: $euiColorLightestShade;
|
||||
}
|
||||
|
||||
&--position-left,
|
||||
&--position-bottom {
|
||||
left: auto;
|
||||
bottom: auto;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
|
@ -7,15 +7,12 @@
|
|||
*/
|
||||
|
||||
import React, { memo, useMemo } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { htmlIdGenerator, EuiButtonIcon } from '@elastic/eui';
|
||||
import { htmlIdGenerator, EuiButtonIcon, useEuiTheme } from '@elastic/eui';
|
||||
import { Position } from '@elastic/charts';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
import './legend_toggle.scss';
|
||||
|
||||
interface LegendToggleProps {
|
||||
export interface LegendToggleProps {
|
||||
onClick: () => void;
|
||||
showLegend: boolean;
|
||||
legendPosition: Position;
|
||||
|
@ -23,6 +20,35 @@ interface LegendToggleProps {
|
|||
|
||||
const LegendToggleComponent = ({ onClick, showLegend, legendPosition }: LegendToggleProps) => {
|
||||
const legendId = useMemo(() => htmlIdGenerator()('legend'), []);
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const baseStyles = useMemo(
|
||||
() => css`
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
margin: ${euiTheme.size.xs};
|
||||
`,
|
||||
[euiTheme.size.xs]
|
||||
);
|
||||
|
||||
const isOpenStyle = useMemo(
|
||||
() => css`
|
||||
background-color: ${euiTheme.colors.lightestShade};
|
||||
`,
|
||||
[euiTheme.colors.lightestShade]
|
||||
);
|
||||
|
||||
const positionStyle = useMemo(
|
||||
() => css`
|
||||
left: auto;
|
||||
bottom: auto;
|
||||
right: 0;
|
||||
top: 0;
|
||||
`,
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiButtonIcon
|
||||
|
@ -30,9 +56,11 @@ const LegendToggleComponent = ({ onClick, showLegend, legendPosition }: LegendTo
|
|||
iconType="list"
|
||||
color="text"
|
||||
onClick={onClick}
|
||||
className={classNames('echLegend__toggle', `echLegend__toggle--position-${legendPosition}`, {
|
||||
'echLegend__toggle--isOpen': showLegend,
|
||||
})}
|
||||
css={[
|
||||
baseStyles,
|
||||
showLegend ? isOpenStyle : null,
|
||||
['left', 'bottom'].includes(legendPosition) ? positionStyle : null,
|
||||
]}
|
||||
aria-label={i18n.translate('charts.legend.toggleLegendButtonAriaLabel', {
|
||||
defaultMessage: 'Toggle legend',
|
||||
})}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue