Skip to content

Commit

Permalink
Create vis_type_xy plugin to replace histogram, area and line charts (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
nickofthyme authored Dec 18, 2020
1 parent cea865f commit ddea10e
Show file tree
Hide file tree
Showing 282 changed files with 8,357 additions and 2,763 deletions.
2 changes: 1 addition & 1 deletion docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ heatmap charts.
|{kib-repo}blob/{branch}/src/plugins/vis_type_xy/README.md[visTypeXy]
|Contains the new xy-axis chart using the elastic-charts library, which will eventually
replace the vislib xy-axis (bar, area, line) charts.
replace the vislib xy-axis charts including bar, area, and line.
|{kib-repo}blob/{branch}/src/plugins/visualizations/README.md[visualizations]
Expand Down
3 changes: 3 additions & 0 deletions docs/management/advanced-options.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ of buckets to try to represent.
==== Visualization

[horizontal]
[[visualization-visualize-chartslibrary]]`visualization:visualize:chartsLibrary`::
Enables the new charts library for area, line, and bar charts in visualization panels. Does *not* support the split chart aggregation.

[[visualization-colormapping]]`visualization:colorMapping`::
**This setting is deprecated and will not be supported as of 8.0.**
Maps values to specific colors in *Visualize* charts and *TSVB*. This setting does not apply to *Lens*.
Expand Down
4 changes: 2 additions & 2 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pageLoadAssetSize:
beatsManagement: 188135
bfetch: 41874
canvas: 1066647
charts: 159211
charts: 195358
cloud: 21076
console: 46091
core: 692106
Expand Down Expand Up @@ -98,7 +98,7 @@ pageLoadAssetSize:
visTypeTimeseries: 155203
visTypeVega: 153573
visTypeVislib: 242838
visTypeXy: 20255
visTypeXy: 113478
visualizations: 295025
visualize: 57431
watcher: 43598
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@ describe('Vislib Color Service', () => {

it('should throw an error if input is not an array', () => {
expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(200);
}).toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction('help');
}).toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(true);
}).toThrowError();

Expand All @@ -78,25 +81,30 @@ describe('Vislib Color Service', () => {
}).toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(nullValue);
}).toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(emptyObject);
}).toThrowError();
});

describe('when array is not composed of numbers, strings, or undefined values', () => {
it('should throw an error', () => {
expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(arrayOfObjects);
}).toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(arrayOfBooleans);
}).toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(arrayOfNullValues);
}).toThrowError();
});
Expand All @@ -113,6 +121,7 @@ describe('Vislib Color Service', () => {
}).not.toThrowError();

expect(() => {
// @ts-expect-error
colors.createColorLookupFunction(arrayOfUndefinedValues);
}).not.toThrowError();
});
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/charts/public/services/legacy_colors/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class LegacyColorsService {
}

createColorLookupFunction(
arrayOfStringsOrNumbers?: any,
arrayOfStringsOrNumbers?: Array<string | number>,
colorMapping: Partial<Record<string, string>> = {}
) {
if (!Array.isArray(arrayOfStringsOrNumbers)) {
Expand All @@ -67,7 +67,7 @@ export class LegacyColorsService {

this.mappedColors.mapKeys(arrayOfStringsOrNumbers);

return (value: string) => {
return (value: string | number) => {
return colorMapping[value] || this.mappedColors.get(value);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
*/

import React from 'react';

import { i18n } from '@kbn/i18n';

import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
import { VisOptionsProps } from '../../../../vis_default_editor/public';

import { SwitchOption } from './switch';
import { SelectOption } from './select';

Expand Down
25 changes: 15 additions & 10 deletions src/plugins/charts/public/static/components/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@
*/

import { $Values } from '@kbn/utility-types';
import { i18n } from '@kbn/i18n';

export const ColorModes = Object.freeze({
BACKGROUND: 'Background' as 'Background',
LABELS: 'Labels' as 'Labels',
NONE: 'None' as 'None',
export const ColorMode = Object.freeze({
Background: 'Background' as 'Background',
Labels: 'Labels' as 'Labels',
None: 'None' as 'None',
});
export type ColorModes = $Values<typeof ColorModes>;
export type ColorMode = $Values<typeof ColorMode>;

export const Rotates = Object.freeze({
HORIZONTAL: 0,
VERTICAL: 90,
ANGLED: 75,
export const LabelRotation = Object.freeze({
Horizontal: 0,
Vertical: 90,
Angled: 75,
});
export type LabelRotation = $Values<typeof LabelRotation>;

export const defaultCountLabel = i18n.translate('charts.countText', {
defaultMessage: 'Count',
});
export type Rotates = $Values<typeof Rotates>;
18 changes: 18 additions & 0 deletions src/plugins/charts/public/static/components/color_picker.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
$visColorPickerWidth: $euiSizeL * 8; // 8 columns

.visColorPicker__value {
width: $visColorPickerWidth;
}

.visColorPicker__valueDot {
cursor: pointer;

&:hover {
transform: scale(1.4);
}

&-isSelected {
border: $euiSizeXS solid;
border-radius: 100%;
}
}
138 changes: 138 additions & 0 deletions src/plugins/charts/public/static/components/color_picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

import { EuiButtonEmpty, EuiFlexItem, EuiIcon } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';

import './color_picker.scss';

export const legendColors: string[] = [
'#3F6833',
'#967302',
'#2F575E',
'#99440A',
'#58140C',
'#052B51',
'#511749',
'#3F2B5B',
'#508642',
'#CCA300',
'#447EBC',
'#C15C17',
'#890F02',
'#0A437C',
'#6D1F62',
'#584477',
'#629E51',
'#E5AC0E',
'#64B0C8',
'#E0752D',
'#BF1B00',
'#0A50A1',
'#962D82',
'#614D93',
'#7EB26D',
'#EAB839',
'#6ED0E0',
'#EF843C',
'#E24D42',
'#1F78C1',
'#BA43A9',
'#705DA0',
'#9AC48A',
'#F2C96D',
'#65C5DB',
'#F9934E',
'#EA6460',
'#5195CE',
'#D683CE',
'#806EB7',
'#B7DBAB',
'#F4D598',
'#70DBED',
'#F9BA8F',
'#F29191',
'#82B5D8',
'#E5A8E2',
'#AEA2E0',
'#E0F9D7',
'#FCEACA',
'#CFFAFF',
'#F9E2D2',
'#FCE2DE',
'#BADFF4',
'#F9D9F9',
'#DEDAF7',
];

interface ColorPickerProps {
id?: string;
label: string | number | null;
onChange: (color: string | null, event: BaseSyntheticEvent) => void;
color: string;
}

export const ColorPicker = ({ onChange, color: selectedColor, id, label }: ColorPickerProps) => (
<div className="visColorPicker">
<span id={`${id}ColorPickerDesc`} className="euiScreenReaderOnly">
<FormattedMessage
id="charts.colorPicker.setColor.screenReaderDescription"
defaultMessage="Set color for value {legendDataLabel}"
values={{ legendDataLabel: label }}
/>
</span>
<div className="visColorPicker__value" role="listbox">
{legendColors.map((color) => (
<EuiIcon
role="option"
tabIndex={0}
type="dot"
size="l"
color={selectedColor}
key={color}
aria-label={color}
aria-describedby={`${id}ColorPickerDesc`}
aria-selected={color === selectedColor}
onClick={(e) => onChange(color, e)}
onKeyPress={(e) => onChange(color, e)}
className={classNames('visColorPicker__valueDot', {
// eslint-disable-next-line @typescript-eslint/naming-convention
'visColorPicker__valueDot-isSelected': color === selectedColor,
})}
style={{ color }}
data-test-subj={`visColorPickerColor-${color}`}
/>
))}
</div>
{legendColors.some((c) => c === selectedColor) && (
<EuiFlexItem grow={false}>
<EuiButtonEmpty
size="s"
onClick={(e: any) => onChange(null, e)}
onKeyPress={(e: any) => onChange(null, e)}
>
<FormattedMessage id="charts.colorPicker.clearColor" defaultMessage="Clear color" />
</EuiButtonEmpty>
</EuiFlexItem>
)}
</div>
);
64 changes: 64 additions & 0 deletions src/plugins/charts/public/static/components/current_time.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import moment, { Moment } from 'moment';
import React, { FC } from 'react';

import { LineAnnotation, AnnotationDomainTypes, LineAnnotationStyle } from '@elastic/charts';
import lightEuiTheme from '@elastic/eui/dist/eui_theme_light.json';
import darkEuiTheme from '@elastic/eui/dist/eui_theme_dark.json';

interface CurrentTimeProps {
isDarkMode: boolean;
domainEnd?: number | Moment;
}

/**
* Render current time line annotation on @elastic/charts `Chart`
*/
export const CurrentTime: FC<CurrentTimeProps> = ({ isDarkMode, domainEnd }) => {
const lineAnnotationStyle: Partial<LineAnnotationStyle> = {
line: {
strokeWidth: 2,
stroke: isDarkMode ? darkEuiTheme.euiColorDanger : lightEuiTheme.euiColorDanger,
opacity: 0.7,
},
};

// Domain end of 'now' will be milliseconds behind current time, so we extend time by 1 minute and check if
// the annotation is within this range; if so, the line annotation uses the domainEnd as its value
const now = moment();
const isAnnotationAtEdge = domainEnd
? moment(domainEnd).add(1, 'm').isAfter(now) && now.isAfter(domainEnd)
: false;
const lineAnnotationData = [
{
dataValue: isAnnotationAtEdge ? domainEnd : now.valueOf(),
},
];

return (
<LineAnnotation
id="__current-time__"
hideTooltips
domainType={AnnotationDomainTypes.XDomain}
dataValues={lineAnnotationData}
style={lineAnnotationStyle}
/>
);
};
Loading

0 comments on commit ddea10e

Please sign in to comment.