Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Thresholds feature #11

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion x-pack/plugins/lens/common/expressions/xy_chart/axis_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,18 @@ interface AxisConfig {
hide?: boolean;
}

export type YAxisMode = 'auto' | 'left' | 'right';
export type YAxisMode = 'auto' | 'left' | 'right' | 'bottom';
export type LineStyle = 'solid' | 'dashed' | 'dotted';
export type FillStyle = 'none' | 'above' | 'below';

export interface YConfig {
forAccessor: string;
axisMode?: YAxisMode;
color?: string;
icon?: string;
lineWidth?: number;
lineStyle?: LineStyle;
fill?: FillStyle;
}

export type AxisTitlesVisibilityConfigResult = AxesSettingsConfig & {
Expand Down Expand Up @@ -161,6 +167,24 @@ export const yAxisConfig: ExpressionFunctionDefinition<
types: ['string'],
help: 'The color of the series',
},
lineStyle: {
types: ['string'],
options: ['solid', 'dotted', 'dashed'],
help: 'The style of the threshold line',
},
lineWidth: {
types: ['number'],
help: 'The width of the threshold line',
},
icon: {
types: ['string'],
help: 'An optional icon used for threshold lines',
},
fill: {
types: ['string'],
options: ['none', 'above', 'below'],
help: '',
},
},
fn: function fn(input: unknown, args: YConfig) {
return {
Expand Down
40 changes: 40 additions & 0 deletions x-pack/plugins/lens/public/assets/chart_bar_threshold.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 React from 'react';
import { EuiIconProps } from '@elastic/eui';

export const LensIconChartBarThreshold = ({
title,
titleId,
...props
}: Omit<EuiIconProps, 'type'>) => (
<svg
viewBox="0 0 16 12"
width={30}
height={22}
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-labelledby={titleId}
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<g>
<path
className="lensChartIcon__subdued"
d="M3.2 4.79997C3.2 4.50542 2.96122 4.26663 2.66667 4.26663H0.533333C0.238784 4.26663 0 4.50542 0 4.79997V6.39997H3.2V4.79997ZM3.2 9.59997H0V13.3333C0 13.6279 0.238784 13.8666 0.533333 13.8666H2.66667C2.96122 13.8666 3.2 13.6279 3.2 13.3333V9.59997ZM8.53333 9.59997H11.7333V13.3333C11.7333 13.6279 11.4946 13.8666 11.2 13.8666H9.06667C8.77211 13.8666 8.53333 13.6279 8.53333 13.3333V9.59997ZM11.7333 6.39997H8.53333V2.66663C8.53333 2.37208 8.77211 2.1333 9.06667 2.1333H11.2C11.4946 2.1333 11.7333 2.37208 11.7333 2.66663V6.39997ZM12.8 9.59997V13.3333C12.8 13.6279 13.0388 13.8666 13.3333 13.8666H15.4667C15.7612 13.8666 16 13.6279 16 13.3333V9.59997H12.8ZM16 6.39997V5.86663C16 5.57208 15.7612 5.3333 15.4667 5.3333H13.3333C13.0388 5.3333 12.8 5.57208 12.8 5.86663V6.39997H16ZM7.46667 11.2C7.46667 10.9054 7.22789 10.6666 6.93333 10.6666H4.8C4.50544 10.6666 4.26667 10.9054 4.26667 11.2V13.3333C4.26667 13.6279 4.50544 13.8666 4.8 13.8666H6.93333C7.22789 13.8666 7.46667 13.6279 7.46667 13.3333V11.2Z"
/>
<rect
y="7.4668"
width="16"
height="1.06667"
rx="0.533334"
className="lensChartIcon__accent"
/>
</g>
</svg>
);
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
updateVisualizationState,
setToggleFullscreen,
} from '../../../state_management';
import { AddLayerButton } from './add_layer';
import { AddLayerButton, getLayerType } from './add_layer';

export const ConfigPanelWrapper = memo(function ConfigPanelWrapper(props: ConfigPanelWrapperProps) {
return props.activeVisualization && props.visualizationState ? (
Expand Down Expand Up @@ -168,6 +168,16 @@ export function LayerPanels(
layerIds.length
) === 'clear'
}
onEmptyDimensionAdd={(columnId, { groupId }) => {
addMaybeDefaultThreshold({
...props,
layerId,
layerType: getLayerType(activeVisualization, visualizationState, layerId),
columnId,
updateAll,
groupId,
});
}}
onRemoveLayer={() => {
dispatchLens(
updateState({
Expand Down Expand Up @@ -234,10 +244,65 @@ export function LayerPanels(
}),
})
);

addMaybeDefaultThreshold({ ...props, layerId: id, layerType, updateAll });
setNextFocusedLayerId(id);
}}
/>
</EuiForm>
);
}

function addMaybeDefaultThreshold({
activeVisualization,
visualizationState,
framePublicAPI,
layerType,
activeDatasourceId,
datasourceMap,
updateAll,
layerId,
columnId,
groupId,
}: ConfigPanelWrapperProps & {
activeDatasourceId: string;
activeVisualization: Visualization;
layerId: string;
layerType: string;
columnId?: string;
groupId?: string;
updateAll: (
datasourceId: string,
newDatasourceState: unknown,
newVisualizationState: unknown
) => void;
}) {
const layerInfo = activeVisualization
.getLayerTypes(visualizationState, framePublicAPI)
.find(({ type }) => type === layerType);
if (layerInfo?.initialDimensions && datasourceMap[activeDatasourceId]?.initializeDimension) {
const info = groupId
? layerInfo.initialDimensions.find(({ groupId: id }) => id === groupId)
: // pick the first available one if not passed
layerInfo.initialDimensions[0];
if (info) {
updateAll(
activeDatasourceId,
(currentState: unknown) => {
return datasourceMap[activeDatasourceId].initializeDimension?.(currentState, layerId, {
...info,
columnId: columnId || info.columnId,
});
},
(currentState: unknown) => {
return activeVisualization.setDimension({
groupId: info.groupId,
layerId,
columnId: columnId || info.columnId,
prevState: currentState,
frame: framePublicAPI,
});
}
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ describe('LayerPanel', () => {
registerNewLayerRef: jest.fn(),
isFullscreen: false,
toggleFullscreen: jest.fn(),
onEmptyDimensionAdd: jest.fn(),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function LayerPanel(
registerNewLayerRef: (layerId: string, instance: HTMLDivElement | null) => void;
toggleFullscreen: () => void;
isFullscreen: boolean;
onEmptyDimensionAdd: (columnId: string, group: { groupId: string }) => void;
}
) {
const [activeDimension, setActiveDimension] = useState<ActiveDimensionState>(
Expand Down Expand Up @@ -469,6 +470,7 @@ export function LayerPanel(
layerDatasource={layerDatasource}
layerDatasourceDropProps={layerDatasourceDropProps}
onClick={(id) => {
props.onEmptyDimensionAdd(id, group);
setActiveDimension({
activeGroup: group,
activeId: id,
Expand Down Expand Up @@ -529,6 +531,7 @@ export function LayerPanel(
toggleFullscreen,
isFullscreen,
setState: updateDataLayerState,
supportStaticValue: Boolean(supportStaticValue),
layerType: activeVisualization.getLayerType(layerId, visualizationState),
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ describe('heatmap', () => {
const instance = getHeatmapVisualization({
paletteService,
});
expect(instance.getLayerType('test-layer', state)).toEqual(layerTypes.DATA);
expect(instance.getLayerType('first', state)).toEqual(layerTypes.DATA);
expect(instance.getLayerType('foo', state)).toBeUndefined();
});
});
Expand Down
Loading