mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Lens] fix displaying position options for ref lines (#128778)
* [Lens] fix displaying position options for ref lines * fix types * move annotation config panel * annotations functional tests * fix dark theme style Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
09218a8fed
commit
47c861bbad
15 changed files with 198 additions and 82 deletions
|
@ -76,7 +76,11 @@ export function MarkerBody({
|
|||
}
|
||||
if (isHorizontal) {
|
||||
return (
|
||||
<div className="eui-textTruncate" style={{ maxWidth: LINES_MARKER_SIZE * 3 }}>
|
||||
<div
|
||||
className="eui-textTruncate"
|
||||
style={{ maxWidth: LINES_MARKER_SIZE * 3 }}
|
||||
data-test-subj="xyVisAnnotationText"
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
);
|
||||
|
@ -84,6 +88,7 @@ export function MarkerBody({
|
|||
return (
|
||||
<div
|
||||
className="xyDecorationRotatedWrapper"
|
||||
data-test-subj="xyVisAnnotationText"
|
||||
style={{
|
||||
width: LINES_MARKER_SIZE,
|
||||
}}
|
||||
|
@ -105,6 +110,7 @@ function NumberIcon({ number }: { number: number }) {
|
|||
<EuiFlexGroup
|
||||
justifyContent="spaceAround"
|
||||
className="xyAnnotationNumberIcon"
|
||||
data-test-subj="xyVisGroupedAnnotationIcon"
|
||||
gutterSize="none"
|
||||
alignItems="center"
|
||||
>
|
||||
|
@ -139,6 +145,7 @@ export const AnnotationIcon = ({
|
|||
return (
|
||||
<EuiIcon
|
||||
{...rest}
|
||||
data-test-subj="xyVisAnnotationIcon"
|
||||
type={iconConfig.icon || type}
|
||||
className={classnames(
|
||||
{ [rotateClassName]: iconConfig.shouldRotate },
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
}
|
||||
|
||||
.lensAnnotationIconFill {
|
||||
fill: $euiColorGhost;
|
||||
fill: $euiColorEmptyShade;
|
||||
}
|
||||
|
||||
// Less-than-ideal styles to add a vertical divider after this button. Consider restructuring markup for better semantics and styling options in the future.
|
||||
|
|
|
@ -21,4 +21,8 @@
|
|||
left: -$euiSize;
|
||||
border-top: 1px solid $euiColorLightShade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lnsDimensionEditorSection__heading {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export const DimensionEditorSection = ({
|
|||
<div className="lnsDimensionEditorSection">
|
||||
<div className="lnsDimensionEditorSection__border" />
|
||||
{title && (
|
||||
<EuiTitle size="xxs" className="lnsXyConfigHeading">
|
||||
<EuiTitle size="xxs" className="lnsDimensionEditorSection__heading">
|
||||
<h3>{title}</h3>
|
||||
</EuiTitle>
|
||||
)}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
.lnsXyConfigHeading {
|
||||
padding-bottom: 16px;
|
||||
}
|
|
@ -21,11 +21,14 @@ import {
|
|||
import { LensIconChartBarAnnotations } from '../../assets/chart_bar_annotations';
|
||||
import { generateId } from '../../id_generator';
|
||||
import { defaultAnnotationColor } from '../../../../../../src/plugins/event_annotation/public';
|
||||
import { defaultAnnotationLabel } from './config_panel';
|
||||
|
||||
const MAX_DATE = 8640000000000000;
|
||||
const MIN_DATE = -8640000000000000;
|
||||
|
||||
export const defaultAnnotationLabel = i18n.translate('xpack.lens.xyChart.defaultAnnotationLabel', {
|
||||
defaultMessage: 'Event',
|
||||
});
|
||||
|
||||
export function getStaticDate(
|
||||
dataLayers: XYDataLayerConfig[],
|
||||
activeData: FramePublicAPI['activeData']
|
||||
|
|
|
@ -31,8 +31,7 @@ import {
|
|||
getReferenceLayers,
|
||||
getAnnotationsLayers,
|
||||
} from './visualization_helpers';
|
||||
import { defaultAnnotationLabel } from './annotations/config_panel';
|
||||
import { getUniqueLabels } from './annotations/helpers';
|
||||
import { getUniqueLabels, defaultAnnotationLabel } from './annotations/helpers';
|
||||
import { layerTypes } from '../../common';
|
||||
|
||||
export const getSortedAccessors = (
|
||||
|
|
|
@ -67,8 +67,9 @@ import {
|
|||
import { groupAxesByType } from './axes_configuration';
|
||||
import { XYState } from './types';
|
||||
import { ReferenceLinePanel } from './xy_config_panel/reference_line_panel';
|
||||
import { AnnotationsPanel } from './xy_config_panel/annotations_config_panel';
|
||||
import { DimensionTrigger } from '../shared_components/dimension_trigger';
|
||||
import { AnnotationsPanel, defaultAnnotationLabel } from './annotations/config_panel';
|
||||
import { defaultAnnotationLabel } from './annotations/helpers';
|
||||
|
||||
export const getXyVisualization = ({
|
||||
paletteService,
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import './index.scss';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiDatePicker, EuiFormRow, EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
|
||||
import type { PaletteRegistry } from 'src/plugins/charts/public';
|
||||
|
@ -15,18 +14,15 @@ import { EventAnnotationConfig } from 'src/plugins/event_annotation/common/types
|
|||
import type { VisualizationDimensionEditorProps } from '../../../types';
|
||||
import { State, XYState, XYAnnotationLayerConfig } from '../../types';
|
||||
import { FormatFactory } from '../../../../common';
|
||||
import { ColorPicker } from '../../xy_config_panel/color_picker';
|
||||
import { DimensionEditorSection, NameInput, useDebouncedValue } from '../../../shared_components';
|
||||
import { isHorizontalChart } from '../../state_helpers';
|
||||
import { MarkerDecorationSettings } from '../../xy_config_panel/shared/marker_decoration_settings';
|
||||
import { LineStyleSettings } from '../../xy_config_panel/shared/line_style_settings';
|
||||
import { updateLayer } from '../../xy_config_panel';
|
||||
import { defaultAnnotationLabel } from '../../annotations/helpers';
|
||||
import { ColorPicker } from '../color_picker';
|
||||
import { IconSelectSetting, TextDecorationSetting } from '../shared/marker_decoration_settings';
|
||||
import { LineStyleSettings } from '../shared/line_style_settings';
|
||||
import { updateLayer } from '..';
|
||||
import { annotationsIconSet } from './icon_set';
|
||||
|
||||
export const defaultAnnotationLabel = i18n.translate('xpack.lens.xyChart.defaultAnnotationLabel', {
|
||||
defaultMessage: 'Event',
|
||||
});
|
||||
|
||||
export const AnnotationsPanel = (
|
||||
props: VisualizationDimensionEditorProps<State> & {
|
||||
formatFactory: FormatFactory;
|
||||
|
@ -101,8 +97,7 @@ export const AnnotationsPanel = (
|
|||
setAnnotations({ label: value });
|
||||
}}
|
||||
/>
|
||||
<MarkerDecorationSettings
|
||||
isHorizontal={isHorizontal}
|
||||
<IconSelectSetting
|
||||
setConfig={setAnnotations}
|
||||
currentConfig={{
|
||||
axisMode: 'bottom',
|
||||
|
@ -110,6 +105,13 @@ export const AnnotationsPanel = (
|
|||
}}
|
||||
customIconSet={annotationsIconSet}
|
||||
/>
|
||||
<TextDecorationSetting
|
||||
setConfig={setAnnotations}
|
||||
currentConfig={{
|
||||
axisMode: 'bottom',
|
||||
...currentAnnotations,
|
||||
}}
|
||||
/>
|
||||
<LineStyleSettings
|
||||
isHorizontal={isHorizontal}
|
||||
setConfig={setAnnotations}
|
|
@ -21,7 +21,7 @@ import { ColorPicker } from './color_picker';
|
|||
import { PalettePicker, useDebouncedValue } from '../../shared_components';
|
||||
import { isAnnotationsLayer, isReferenceLayer } from '../visualization_helpers';
|
||||
import { ReferenceLinePanel } from './reference_line_panel';
|
||||
import { AnnotationsPanel } from '../annotations/config_panel';
|
||||
import { AnnotationsPanel } from './annotations_config_panel';
|
||||
|
||||
type UnwrapArray<T> = T extends Array<infer P> ? P : T;
|
||||
|
||||
|
|
|
@ -22,7 +22,11 @@ import { updateLayer } from '.';
|
|||
import { useDebouncedValue } from '../../shared_components';
|
||||
import { idPrefix } from './dimension_editor';
|
||||
import { isHorizontalChart } from '../state_helpers';
|
||||
import { MarkerDecorationSettings } from './shared/marker_decoration_settings';
|
||||
import {
|
||||
IconSelectSetting,
|
||||
MarkerDecorationPosition,
|
||||
TextDecorationSetting,
|
||||
} from './shared/marker_decoration_settings';
|
||||
import { LineStyleSettings } from './shared/line_style_settings';
|
||||
|
||||
export const ReferenceLinePanel = (
|
||||
|
@ -72,8 +76,9 @@ export const ReferenceLinePanel = (
|
|||
|
||||
return (
|
||||
<>
|
||||
{' '}
|
||||
<MarkerDecorationSettings
|
||||
<TextDecorationSetting setConfig={setConfig} currentConfig={localConfig} />
|
||||
<IconSelectSetting setConfig={setConfig} currentConfig={localConfig} />
|
||||
<MarkerDecorationPosition
|
||||
isHorizontal={isHorizontal}
|
||||
setConfig={setConfig}
|
||||
currentConfig={localConfig}
|
||||
|
|
|
@ -81,73 +81,96 @@ interface MarkerDecorationConfig {
|
|||
textVisibility?: boolean;
|
||||
}
|
||||
|
||||
export const MarkerDecorationSettings = ({
|
||||
export const TextDecorationSetting = ({
|
||||
currentConfig,
|
||||
setConfig,
|
||||
isHorizontal,
|
||||
customIconSet,
|
||||
}: {
|
||||
currentConfig?: MarkerDecorationConfig;
|
||||
setConfig: (config: MarkerDecorationConfig) => void;
|
||||
isHorizontal: boolean;
|
||||
customIconSet?: IconSet;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.lens.lineMarker.textVisibility', {
|
||||
<EuiFormRow
|
||||
label={i18n.translate('xpack.lens.lineMarker.textVisibility', {
|
||||
defaultMessage: 'Text decoration',
|
||||
})}
|
||||
display="columnCompressed"
|
||||
fullWidth
|
||||
>
|
||||
<EuiButtonGroup
|
||||
legend={i18n.translate('xpack.lens.lineMarker.textVisibility', {
|
||||
defaultMessage: 'Text decoration',
|
||||
})}
|
||||
display="columnCompressed"
|
||||
fullWidth
|
||||
>
|
||||
<EuiButtonGroup
|
||||
legend={i18n.translate('xpack.lens.lineMarker.textVisibility', {
|
||||
defaultMessage: 'Text decoration',
|
||||
})}
|
||||
data-test-subj="lns-lineMarker-text-visibility"
|
||||
name="textVisibilityStyle"
|
||||
buttonSize="compressed"
|
||||
options={[
|
||||
{
|
||||
id: `${idPrefix}none`,
|
||||
label: i18n.translate('xpack.lens.xyChart.lineMarker.textVisibility.none', {
|
||||
defaultMessage: 'None',
|
||||
}),
|
||||
'data-test-subj': 'lnsXY_textVisibility_none',
|
||||
},
|
||||
{
|
||||
id: `${idPrefix}name`,
|
||||
label: i18n.translate('xpack.lens.xyChart.lineMarker.textVisibility.name', {
|
||||
defaultMessage: 'Name',
|
||||
}),
|
||||
'data-test-subj': 'lnsXY_textVisibility_name',
|
||||
},
|
||||
]}
|
||||
idSelected={`${idPrefix}${Boolean(currentConfig?.textVisibility) ? 'name' : 'none'}`}
|
||||
onChange={(id) => {
|
||||
setConfig({ textVisibility: id === `${idPrefix}name` });
|
||||
}}
|
||||
isFullWidth
|
||||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow
|
||||
display="columnCompressed"
|
||||
fullWidth
|
||||
label={i18n.translate('xpack.lens.xyChart.lineMarker.icon', {
|
||||
defaultMessage: 'Icon decoration',
|
||||
})}
|
||||
>
|
||||
<IconSelect
|
||||
customIconSet={customIconSet}
|
||||
value={currentConfig?.icon}
|
||||
onChange={(newIcon) => {
|
||||
setConfig({ icon: newIcon });
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
{currentConfig?.iconPosition &&
|
||||
(hasIcon(currentConfig?.icon) || currentConfig?.textVisibility) ? (
|
||||
data-test-subj="lns-lineMarker-text-visibility"
|
||||
name="textVisibilityStyle"
|
||||
buttonSize="compressed"
|
||||
options={[
|
||||
{
|
||||
id: `${idPrefix}none`,
|
||||
label: i18n.translate('xpack.lens.xyChart.lineMarker.textVisibility.none', {
|
||||
defaultMessage: 'None',
|
||||
}),
|
||||
'data-test-subj': 'lnsXY_textVisibility_none',
|
||||
},
|
||||
{
|
||||
id: `${idPrefix}name`,
|
||||
label: i18n.translate('xpack.lens.xyChart.lineMarker.textVisibility.name', {
|
||||
defaultMessage: 'Name',
|
||||
}),
|
||||
'data-test-subj': 'lnsXY_textVisibility_name',
|
||||
},
|
||||
]}
|
||||
idSelected={`${idPrefix}${Boolean(currentConfig?.textVisibility) ? 'name' : 'none'}`}
|
||||
onChange={(id) => {
|
||||
setConfig({ textVisibility: id === `${idPrefix}name` });
|
||||
}}
|
||||
isFullWidth
|
||||
/>
|
||||
</EuiFormRow>
|
||||
);
|
||||
};
|
||||
|
||||
export const IconSelectSetting = ({
|
||||
currentConfig,
|
||||
setConfig,
|
||||
customIconSet,
|
||||
}: {
|
||||
currentConfig?: MarkerDecorationConfig;
|
||||
setConfig: (config: MarkerDecorationConfig) => void;
|
||||
customIconSet?: IconSet;
|
||||
}) => {
|
||||
return (
|
||||
<EuiFormRow
|
||||
display="columnCompressed"
|
||||
fullWidth
|
||||
label={i18n.translate('xpack.lens.xyChart.lineMarker.icon', {
|
||||
defaultMessage: 'Icon decoration',
|
||||
})}
|
||||
>
|
||||
<IconSelect
|
||||
customIconSet={customIconSet}
|
||||
value={currentConfig?.icon}
|
||||
onChange={(newIcon) => {
|
||||
setConfig({ icon: newIcon });
|
||||
}}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
);
|
||||
};
|
||||
|
||||
export const MarkerDecorationPosition = ({
|
||||
currentConfig,
|
||||
setConfig,
|
||||
isHorizontal,
|
||||
}: {
|
||||
currentConfig?: MarkerDecorationConfig;
|
||||
setConfig: (config: MarkerDecorationConfig) => void;
|
||||
isHorizontal: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{hasIcon(currentConfig?.icon) || currentConfig?.textVisibility ? (
|
||||
<EuiFormRow
|
||||
display="columnCompressed"
|
||||
fullWidth
|
||||
|
|
74
x-pack/test/functional/apps/lens/annotations.ts
Normal file
74
x-pack/test/functional/apps/lens/annotations.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header']);
|
||||
const find = getService('find');
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
describe('lens annotations tests', () => {
|
||||
it('should show a disabled annotation layer button if there is no date histogram in data layer', async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.dragFieldToWorkspace('geo.src', 'xyVisChart');
|
||||
await testSubjects.click('lnsLayerAddButton');
|
||||
await retry.waitFor('wait for layer popup to appear', async () =>
|
||||
testSubjects.exists(`lnsLayerAddButton-annotations`)
|
||||
);
|
||||
expect(
|
||||
await (await testSubjects.find(`lnsLayerAddButton-annotations`)).getAttribute('disabled')
|
||||
).to.be('true');
|
||||
});
|
||||
|
||||
it('should add manual annotation layer with static date and allow edition', async () => {
|
||||
await PageObjects.lens.removeLayer();
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
await PageObjects.lens.dragFieldToWorkspace('@timestamp', 'xyVisChart');
|
||||
|
||||
await PageObjects.lens.createLayer('annotations');
|
||||
|
||||
expect((await find.allByCssSelector(`[data-test-subj^="lns-layerPanel-"]`)).length).to.eql(2);
|
||||
expect(
|
||||
await (
|
||||
await testSubjects.find('lnsXY_xAnnotationsPanel > lns-dimensionTrigger')
|
||||
).getVisibleText()
|
||||
).to.eql('Event');
|
||||
await testSubjects.click('lnsXY_xAnnotationsPanel > lns-dimensionTrigger');
|
||||
await testSubjects.click('lnsXY_textVisibility_name');
|
||||
await PageObjects.lens.closeDimensionEditor();
|
||||
|
||||
await testSubjects.existOrFail('xyVisAnnotationIcon');
|
||||
await testSubjects.existOrFail('xyVisAnnotationText');
|
||||
});
|
||||
|
||||
it('should duplicate the style when duplicating an annotation and group them in the chart', async () => {
|
||||
// drag and drop to the empty field to generate a duplicate
|
||||
await PageObjects.lens.dragDimensionToDimension(
|
||||
'lnsXY_xAnnotationsPanel > lns-dimensionTrigger',
|
||||
'lnsXY_xAnnotationsPanel > lns-empty-dimension'
|
||||
);
|
||||
|
||||
await (
|
||||
await find.byCssSelector(
|
||||
'[data-test-subj="lnsXY_xAnnotationsPanel"]:nth-child(2) [data-test-subj="lns-dimensionTrigger"]'
|
||||
)
|
||||
).click();
|
||||
expect(
|
||||
await find.existsByCssSelector(
|
||||
'[data-test-subj="lnsXY_textVisibility_name"][class$="isSelected"]'
|
||||
)
|
||||
).to.be(true);
|
||||
await PageObjects.lens.closeDimensionEditor();
|
||||
await testSubjects.existOrFail('xyVisAnnotationText');
|
||||
await testSubjects.existOrFail('xyVisGroupedAnnotationIcon');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -75,6 +75,7 @@ export default function ({ getService, loadTestFile, getPageObjects }: FtrProvid
|
|||
loadTestFile(require.resolve('./gauge'));
|
||||
loadTestFile(require.resolve('./metrics'));
|
||||
loadTestFile(require.resolve('./reference_lines'));
|
||||
loadTestFile(require.resolve('./annotations'));
|
||||
loadTestFile(require.resolve('./inspector'));
|
||||
loadTestFile(require.resolve('./error_handling'));
|
||||
loadTestFile(require.resolve('./lens_tagging'));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue