[Lens] Export nested types (#89868) (#90141)

This commit is contained in:
Joe Reuter 2021-02-03 14:25:22 +01:00 committed by GitHub
parent 83fe6feb1c
commit 2cab61f1e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 224 additions and 105 deletions

View file

@ -415,7 +415,7 @@ the infrastructure monitoring use-case within Kibana.
|{kib-repo}blob/{branch}/x-pack/plugins/lens/readme.md[lens]
|Run all tests from the x-pack root directory
|Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads.
|{kib-repo}blob/{branch}/x-pack/plugins/license_management/README.md[licenseManagement]

View file

@ -19,7 +19,11 @@ import {
} from '@elastic/eui';
import { IndexPattern } from 'src/plugins/data/public';
import { CoreStart } from 'kibana/public';
import { TypedLensByValueInput } from '../../../plugins/lens/public';
import {
TypedLensByValueInput,
PersistedIndexPatternLayer,
XYState,
} from '../../../plugins/lens/public';
import { StartDependencies } from './plugin';
// Generate a Lens state based on some app-specific input parameters.
@ -28,6 +32,48 @@ function getLensAttributes(
defaultIndexPattern: IndexPattern,
color: string
): TypedLensByValueInput['attributes'] {
const dataLayer: PersistedIndexPatternLayer = {
columnOrder: ['col1', 'col2'],
columns: {
col2: {
dataType: 'number',
isBucketed: false,
label: 'Count of records',
operationType: 'count',
scale: 'ratio',
sourceField: 'Records',
},
col1: {
dataType: 'date',
isBucketed: true,
label: '@timestamp',
operationType: 'date_histogram',
params: { interval: 'auto' },
scale: 'interval',
sourceField: defaultIndexPattern.timeFieldName!,
},
},
};
const xyConfig: XYState = {
axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true },
fittingFunction: 'None',
gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true },
layers: [
{
accessors: ['col2'],
layerId: 'layer1',
seriesType: 'bar_stacked',
xAccessor: 'col1',
yConfig: [{ forAccessor: 'col2', color }],
},
],
legend: { isVisible: true, position: 'right' },
preferredSeriesType: 'bar_stacked',
tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true },
valueLabels: 'hide',
};
return {
visualizationType: 'lnsXY',
title: 'Prefilled from example app',
@ -47,51 +93,13 @@ function getLensAttributes(
datasourceStates: {
indexpattern: {
layers: {
layer1: {
columnOrder: ['col1', 'col2'],
columns: {
col2: {
dataType: 'number',
isBucketed: false,
label: 'Count of records',
operationType: 'count',
scale: 'ratio',
sourceField: 'Records',
},
col1: {
dataType: 'date',
isBucketed: true,
label: '@timestamp',
operationType: 'date_histogram',
params: { interval: 'auto' },
scale: 'interval',
sourceField: defaultIndexPattern.timeFieldName!,
},
},
},
layer1: dataLayer,
},
},
},
filters: [],
query: { language: 'kuery', query: '' },
visualization: {
axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true },
fittingFunction: 'None',
gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true },
layers: [
{
accessors: ['col2'],
layerId: 'layer1',
seriesType: 'bar_stacked',
xAccessor: 'col1',
yConfig: [{ forAccessor: 'col2', color }],
},
],
legend: { isVisible: true, position: 'right' },
preferredSeriesType: 'bar_stacked',
tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true },
valueLabels: 'hide',
},
visualization: xyConfig,
},
};
}

View file

@ -16,13 +16,13 @@ import type {
import type { DatatableColumnWidth } from './components/types';
import { LensIconChartDatatable } from '../assets/chart_datatable';
export interface LayerState {
export interface DatatableLayerState {
layerId: string;
columns: string[];
}
export interface DatatableVisualizationState {
layers: LayerState[];
layers: DatatableLayerState[];
sorting?: {
columnId: string | undefined;
direction: 'asc' | 'desc' | 'none';
@ -30,7 +30,7 @@ export interface DatatableVisualizationState {
columnWidth?: DatatableColumnWidth[];
}
function newLayerState(layerId: string): LayerState {
function newLayerState(layerId: string): DatatableLayerState {
return {
layerId,
columns: [],
@ -300,7 +300,7 @@ function getDataSourceAndSortedColumns(
datasourceLayers: Record<string, DatasourcePublicAPI>,
layerId: string
) {
const layer = state.layers.find((l: LayerState) => l.layerId === layerId);
const layer = state.layers.find((l: DatatableLayerState) => l.layerId === layerId);
if (!layer) {
return undefined;
}

View file

@ -14,7 +14,7 @@ import type { IndexPatternPersistedState } from '../../indexpattern_datasource/t
import type { XYState } from '../../xy_visualization/types';
import type { PieVisualizationState } from '../../pie_visualization/types';
import type { DatatableVisualizationState } from '../../datatable_visualization/visualization';
import type { State as MetricState } from '../../metric_visualization/types';
import type { MetricState } from '../../metric_visualization/types';
type LensAttributes<TVisType, TVisState> = Omit<
Document,

View file

@ -10,11 +10,49 @@ export {
EmbeddableComponentProps,
TypedLensByValueInput,
} from './editor_frame_service/embeddable/embeddable_component';
export type { XYState } from './xy_visualization/types';
export type { PieVisualizationState } from './pie_visualization/types';
export type { DatatableVisualizationState } from './datatable_visualization/visualization';
export type { State as MetricState } from './metric_visualization/types';
export type { IndexPatternPersistedState } from './indexpattern_datasource/types';
export type {
XYState,
AxesSettingsConfig,
XYLayerConfig,
LegendConfig,
SeriesType,
ValueLabelConfig,
YAxisMode,
} from './xy_visualization/types';
export type {
PieVisualizationState,
PieLayerState,
SharedPieLayerState,
} from './pie_visualization/types';
export type {
DatatableVisualizationState,
DatatableLayerState,
} from './datatable_visualization/visualization';
export type { MetricState } from './metric_visualization/types';
export type {
IndexPatternPersistedState,
PersistedIndexPatternLayer,
IndexPatternColumn,
OperationType,
IncompleteColumn,
FiltersIndexPatternColumn,
RangeIndexPatternColumn,
TermsIndexPatternColumn,
DateHistogramIndexPatternColumn,
MinIndexPatternColumn,
MaxIndexPatternColumn,
AvgIndexPatternColumn,
CardinalityIndexPatternColumn,
SumIndexPatternColumn,
MedianIndexPatternColumn,
PercentileIndexPatternColumn,
CountIndexPatternColumn,
LastValueIndexPatternColumn,
CumulativeSumIndexPatternColumn,
CounterRateIndexPatternColumn,
DerivativeIndexPatternColumn,
MovingAverageIndexPatternColumn,
} from './indexpattern_datasource/types';
export { LensPublicStart } from './plugin';
export const plugin = () => new LensPlugin();

View file

@ -71,6 +71,28 @@ export type FieldBasedIndexPatternColumn = Extract<IndexPatternColumn, { sourceF
export { IncompleteColumn } from './column_types';
export { TermsIndexPatternColumn } from './terms';
export { FiltersIndexPatternColumn } from './filters';
export { CardinalityIndexPatternColumn } from './cardinality';
export { PercentileIndexPatternColumn } from './percentile';
export {
MinIndexPatternColumn,
AvgIndexPatternColumn,
SumIndexPatternColumn,
MaxIndexPatternColumn,
MedianIndexPatternColumn,
} from './metrics';
export { DateHistogramIndexPatternColumn } from './date_histogram';
export {
CumulativeSumIndexPatternColumn,
CounterRateIndexPatternColumn,
DerivativeIndexPatternColumn,
MovingAverageIndexPatternColumn,
} from './calculations';
export { CountIndexPatternColumn } from './count';
export { LastValueIndexPatternColumn } from './last_value';
export { RangeIndexPatternColumn } from './ranges';
// List of all operation definitions registered to this data source.
// If you want to implement a new operation, add the definition to this array and
// the column type to the `IndexPatternColumn` union type below.

View file

@ -13,6 +13,23 @@ export {
FieldBasedIndexPatternColumn,
IncompleteColumn,
RequiredReference,
FiltersIndexPatternColumn,
RangeIndexPatternColumn,
TermsIndexPatternColumn,
DateHistogramIndexPatternColumn,
MinIndexPatternColumn,
MaxIndexPatternColumn,
AvgIndexPatternColumn,
CardinalityIndexPatternColumn,
SumIndexPatternColumn,
MedianIndexPatternColumn,
PercentileIndexPatternColumn,
CountIndexPatternColumn,
LastValueIndexPatternColumn,
CumulativeSumIndexPatternColumn,
CounterRateIndexPatternColumn,
DerivativeIndexPatternColumn,
MovingAverageIndexPatternColumn,
} from './definitions';
export { createMockedReferenceOperation } from './mocks';

View file

@ -8,6 +8,29 @@ import { IFieldType } from 'src/plugins/data/common';
import { IndexPatternColumn, IncompleteColumn } from './operations';
import { IndexPatternAggRestrictions } from '../../../../../src/plugins/data/public';
export {
IndexPatternColumn,
OperationType,
IncompleteColumn,
FiltersIndexPatternColumn,
RangeIndexPatternColumn,
TermsIndexPatternColumn,
DateHistogramIndexPatternColumn,
MinIndexPatternColumn,
MaxIndexPatternColumn,
AvgIndexPatternColumn,
CardinalityIndexPatternColumn,
SumIndexPatternColumn,
MedianIndexPatternColumn,
PercentileIndexPatternColumn,
CountIndexPatternColumn,
LastValueIndexPatternColumn,
CumulativeSumIndexPatternColumn,
CounterRateIndexPatternColumn,
DerivativeIndexPatternColumn,
MovingAverageIndexPatternColumn,
} from './operations';
export interface IndexPattern {
id: string;
fields: IndexPatternField[];
@ -43,6 +66,7 @@ export interface IndexPatternPersistedState {
layers: Record<string, Omit<IndexPatternLayer, 'indexPatternId'>>;
}
export type PersistedIndexPatternLayer = Omit<IndexPatternLayer, 'indexPatternId'>;
export interface IndexPatternPrivateState {
currentIndexPatternId: string;
layers: Record<string, IndexPatternLayer>;

View file

@ -5,7 +5,7 @@
*/
import { SuggestionRequest, VisualizationSuggestion, TableSuggestion } from '../types';
import { State } from './types';
import { MetricState } from './types';
import { LensIconChartMetric } from '../assets/chart_metric';
/**
@ -17,7 +17,7 @@ export function getSuggestions({
table,
state,
keptLayerIds,
}: SuggestionRequest<State>): Array<VisualizationSuggestion<State>> {
}: SuggestionRequest<MetricState>): Array<VisualizationSuggestion<MetricState>> {
// We only render metric charts for single-row queries. We require a single, numeric column.
if (
table.isMultiRow ||
@ -37,7 +37,7 @@ export function getSuggestions({
return [getSuggestion(table)];
}
function getSuggestion(table: TableSuggestion): VisualizationSuggestion<State> {
function getSuggestion(table: TableSuggestion): VisualizationSuggestion<MetricState> {
const col = table.columns[0];
const title = table.label || col.operation.label;

View file

@ -4,12 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
export interface State {
export interface MetricState {
layerId: string;
accessor?: string;
}
export interface MetricConfig extends State {
export interface MetricConfig extends MetricState {
title: string;
description: string;
metricTitle: string;

View file

@ -5,14 +5,14 @@
*/
import { metricVisualization } from './visualization';
import { State } from './types';
import { MetricState } from './types';
import { createMockDatasource, createMockFramePublicAPI } from '../editor_frame_service/mocks';
import { generateId } from '../id_generator';
import { DatasourcePublicAPI, FramePublicAPI } from '../types';
jest.mock('../id_generator');
function exampleState(): State {
function exampleState(): MetricState {
return {
accessor: 'a',
layerId: 'l1',

View file

@ -9,10 +9,10 @@ import { Ast } from '@kbn/interpreter/target/common';
import { getSuggestions } from './metric_suggestions';
import { LensIconChartMetric } from '../assets/chart_metric';
import { Visualization, OperationMetadata, DatasourcePublicAPI } from '../types';
import { State } from './types';
import { MetricState } from './types';
const toExpression = (
state: State,
state: MetricState,
datasourceLayers: Record<string, DatasourcePublicAPI>,
attributes?: { mode?: 'reduced' | 'full'; title?: string; description?: string }
): Ast | null => {
@ -41,7 +41,7 @@ const toExpression = (
};
};
export const metricVisualization: Visualization<State> = {
export const metricVisualization: Visualization<MetricState> = {
id: 'lnsMetric',
visualizationTypes: [

View file

@ -17,12 +17,15 @@ import {
} from '@elastic/eui';
import { Position } from '@elastic/charts';
import { DEFAULT_PERCENT_DECIMALS } from './constants';
import { PieVisualizationState, SharedLayerState } from './types';
import { PieVisualizationState, SharedPieLayerState } from './types';
import { VisualizationDimensionEditorProps, VisualizationToolbarProps } from '../types';
import { ToolbarPopover, LegendSettingsPopover } from '../shared_components';
import { PalettePicker } from '../shared_components';
const numberOptions: Array<{ value: SharedLayerState['numberDisplay']; inputDisplay: string }> = [
const numberOptions: Array<{
value: SharedPieLayerState['numberDisplay'];
inputDisplay: string;
}> = [
{
value: 'hidden',
inputDisplay: i18n.translate('xpack.lens.pieChart.hiddenNumbersLabel', {
@ -44,7 +47,7 @@ const numberOptions: Array<{ value: SharedLayerState['numberDisplay']; inputDisp
];
const categoryOptions: Array<{
value: SharedLayerState['categoryDisplay'];
value: SharedPieLayerState['categoryDisplay'];
inputDisplay: string;
}> = [
{
@ -68,7 +71,7 @@ const categoryOptions: Array<{
];
const categoryOptionsTreemap: Array<{
value: SharedLayerState['categoryDisplay'];
value: SharedPieLayerState['categoryDisplay'];
inputDisplay: string;
}> = [
{
@ -86,7 +89,7 @@ const categoryOptionsTreemap: Array<{
];
const legendOptions: Array<{
value: SharedLayerState['legendDisplay'];
value: SharedPieLayerState['legendDisplay'];
label: string;
id: string;
}> = [

View file

@ -7,7 +7,7 @@
import { PaletteOutput } from 'src/plugins/charts/public';
import { LensMultiTable } from '../types';
export interface SharedLayerState {
export interface SharedPieLayerState {
groups: string[];
metric?: string;
numberDisplay: 'hidden' | 'percent' | 'value';
@ -18,17 +18,17 @@ export interface SharedLayerState {
percentDecimals?: number;
}
export type LayerState = SharedLayerState & {
export type PieLayerState = SharedPieLayerState & {
layerId: string;
};
export interface PieVisualizationState {
shape: 'donut' | 'pie' | 'treemap';
layers: LayerState[];
layers: PieLayerState[];
palette?: PaletteOutput;
}
export type PieExpressionArgs = SharedLayerState & {
export type PieExpressionArgs = SharedPieLayerState & {
title?: string;
description?: string;
shape: 'pie' | 'donut' | 'treemap';

View file

@ -11,12 +11,12 @@ import { I18nProvider } from '@kbn/i18n/react';
import { PaletteRegistry } from 'src/plugins/charts/public';
import { Visualization, OperationMetadata, AccessorConfig } from '../types';
import { toExpression, toPreviewExpression } from './to_expression';
import { LayerState, PieVisualizationState } from './types';
import { PieLayerState, PieVisualizationState } from './types';
import { suggestions } from './suggestions';
import { CHART_NAMES, MAX_PIE_BUCKETS, MAX_TREEMAP_BUCKETS } from './constants';
import { DimensionEditor, PieToolbar } from './toolbar';
function newLayerState(layerId: string): LayerState {
function newLayerState(layerId: string): PieLayerState {
return {
layerId,
groups: [],

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { LayerConfig } from './types';
import { XYLayerConfig } from './types';
import { Datatable, SerializedFieldFormat } from '../../../../../src/plugins/expressions/public';
import { IFieldFormat } from '../../../../../src/plugins/data/public';
@ -29,7 +29,7 @@ export function isFormatterCompatible(
}
export function getAxesConfiguration(
layers: LayerConfig[],
layers: XYLayerConfig[],
shouldRotate: boolean,
tables?: Record<string, Datatable>,
formatFactory?: (mapping: SerializedFieldFormat) => IFieldFormat

View file

@ -15,7 +15,7 @@ import {
IconType,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { LayerConfig, AxesSettingsConfig } from './types';
import { XYLayerConfig, AxesSettingsConfig } from './types';
import { ToolbarPopover } from '../shared_components';
import { isHorizontalChart } from './state_helpers';
import { EuiIconAxisBottom } from '../assets/axis_bottom';
@ -33,7 +33,7 @@ export interface AxisSettingsPopoverProps {
/**
* Contains the chart layers
*/
layers?: LayerConfig[];
layers?: XYLayerConfig[];
/**
* Determines the axis title
*/

View file

@ -9,7 +9,7 @@ import { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public';
import { Datatable } from 'src/plugins/expressions';
import { AccessorConfig, FormatFactory, FramePublicAPI } from '../types';
import { getColumnToLabelMap } from './state_helpers';
import { LayerConfig } from './types';
import { XYLayerConfig } from './types';
const isPrimitive = (value: unknown): boolean => value != null && typeof value !== 'object';
@ -95,7 +95,7 @@ export function getColorAssignments(
export function getAccessorColorConfig(
colorAssignments: ColorAssignments,
frame: FramePublicAPI,
layer: LayerConfig,
layer: XYLayerConfig,
paletteService: PaletteRegistry
): AccessorConfig[] {
const layerContainsSplits = Boolean(layer.splitAccessor);

View file

@ -6,7 +6,7 @@
import { EuiIconType } from '@elastic/eui/src/components/icon/icon';
import { FramePublicAPI, DatasourcePublicAPI } from '../types';
import { SeriesType, visualizationTypes, LayerConfig, YConfig, ValidLayer } from './types';
import { SeriesType, visualizationTypes, XYLayerConfig, YConfig, ValidLayer } from './types';
export function isHorizontalSeries(seriesType: SeriesType) {
return (
@ -30,7 +30,7 @@ export function getIconForSeries(type: SeriesType): EuiIconType {
return (definition.icon as EuiIconType) || 'empty';
}
export const getSeriesColor = (layer: LayerConfig, accessor: string) => {
export const getSeriesColor = (layer: XYLayerConfig, accessor: string) => {
if (layer.splitAccessor) {
return null;
}
@ -39,7 +39,7 @@ export const getSeriesColor = (layer: LayerConfig, accessor: string) => {
);
};
export const getColumnToLabelMap = (layer: LayerConfig, datasource: DatasourcePublicAPI) => {
export const getColumnToLabelMap = (layer: XYLayerConfig, datasource: DatasourcePublicAPI) => {
const columnToLabel: Record<string, string> = {};
layer.accessors.concat(layer.splitAccessor ? [layer.splitAccessor] : []).forEach((accessor) => {

View file

@ -7,11 +7,11 @@
import { Ast } from '@kbn/interpreter/common';
import { ScaleType } from '@elastic/charts';
import { PaletteRegistry } from 'src/plugins/charts/public';
import { State, ValidLayer, LayerConfig } from './types';
import { State, ValidLayer, XYLayerConfig } from './types';
import { OperationMetadata, DatasourcePublicAPI } from '../types';
import { getColumnToLabelMap } from './state_helpers';
export const getSortedAccessors = (datasource: DatasourcePublicAPI, layer: LayerConfig) => {
export const getSortedAccessors = (datasource: DatasourcePublicAPI, layer: XYLayerConfig) => {
const originalOrder = datasource
.getTableSpec()
.map(({ columnId }: { columnId: string }) => columnId)

View file

@ -372,7 +372,7 @@ export interface YConfig {
color?: string;
}
export interface LayerConfig {
export interface XYLayerConfig {
hide?: boolean;
layerId: string;
xAccessor?: string;
@ -383,11 +383,11 @@ export interface LayerConfig {
palette?: PaletteOutput;
}
export interface ValidLayer extends LayerConfig {
xAccessor: NonNullable<LayerConfig['xAccessor']>;
export interface ValidLayer extends XYLayerConfig {
xAccessor: NonNullable<XYLayerConfig['xAccessor']>;
}
export type LayerArgs = LayerConfig & {
export type LayerArgs = XYLayerConfig & {
columnToLabel?: string; // Actually a JSON key-value pair
yScaleType: 'time' | 'linear' | 'log' | 'sqrt';
xScaleType: 'time' | 'linear' | 'ordinal';
@ -420,7 +420,7 @@ export interface XYState {
legend: LegendConfig;
valueLabels?: ValueLabelConfig;
fittingFunction?: FittingFunction;
layers: LayerConfig[];
layers: XYLayerConfig[];
xTitle?: string;
yTitle?: string;
yRightTitle?: string;

View file

@ -7,7 +7,7 @@
import { getXyVisualization } from './visualization';
import { Position } from '@elastic/charts';
import { Operation } from '../types';
import { State, SeriesType, LayerConfig } from './types';
import { State, SeriesType, XYLayerConfig } from './types';
import { createMockDatasource, createMockFramePublicAPI } from '../editor_frame_service/mocks';
import { LensIconChartBar } from '../assets/chart_bar';
import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks';
@ -422,7 +422,7 @@ describe('xy_visualization', () => {
});
describe('color assignment', () => {
function callConfig(layerConfigOverride: Partial<LayerConfig>) {
function callConfig(layerConfigOverride: Partial<XYLayerConfig>) {
const baseState = exampleState();
const options = xyVisualization.getConfiguration({
state: {
@ -441,16 +441,16 @@ describe('xy_visualization', () => {
return options;
}
function callConfigForYConfigs(layerConfigOverride: Partial<LayerConfig>) {
function callConfigForYConfigs(layerConfigOverride: Partial<XYLayerConfig>) {
return callConfig(layerConfigOverride).find(({ groupId }) => groupId === 'y');
}
function callConfigForBreakdownConfigs(layerConfigOverride: Partial<LayerConfig>) {
function callConfigForBreakdownConfigs(layerConfigOverride: Partial<XYLayerConfig>) {
return callConfig(layerConfigOverride).find(({ groupId }) => groupId === 'breakdown');
}
function callConfigAndFindYConfig(
layerConfigOverride: Partial<LayerConfig>,
layerConfigOverride: Partial<XYLayerConfig>,
assertionAccessor: string
) {
const accessorConfig = callConfigForYConfigs(layerConfigOverride)?.accessors.find(

View file

@ -15,7 +15,7 @@ import { DataPublicPluginStart } from 'src/plugins/data/public';
import { getSuggestions } from './xy_suggestions';
import { LayerContextMenu, XyToolbar, DimensionEditor } from './xy_config_panel';
import { Visualization, OperationMetadata, VisualizationType, AccessorConfig } from '../types';
import { State, SeriesType, visualizationTypes, LayerConfig } from './types';
import { State, SeriesType, visualizationTypes, XYLayerConfig } from './types';
import { isHorizontalChart } from './state_helpers';
import { toExpression, toPreviewExpression, getSortedAccessors } from './to_expression';
import { LensIconChartBarStacked } from '../assets/chart_bar_stacked';
@ -341,9 +341,9 @@ export const getXyVisualization = ({
getErrorMessages(state, frame) {
// Data error handling below here
const hasNoAccessors = ({ accessors }: LayerConfig) =>
const hasNoAccessors = ({ accessors }: XYLayerConfig) =>
accessors == null || accessors.length === 0;
const hasNoSplitAccessor = ({ splitAccessor, seriesType }: LayerConfig) =>
const hasNoSplitAccessor = ({ splitAccessor, seriesType }: XYLayerConfig) =>
seriesType.includes('percentage') && splitAccessor == null;
const errors: Array<{
@ -354,14 +354,14 @@ export const getXyVisualization = ({
// check if the layers in the state are compatible with this type of chart
if (state && state.layers.length > 1) {
// Order is important here: Y Axis is fundamental to exist to make it valid
const checks: Array<[string, (layer: LayerConfig) => boolean]> = [
const checks: Array<[string, (layer: XYLayerConfig) => boolean]> = [
['Y', hasNoAccessors],
['Break down', hasNoSplitAccessor],
];
// filter out those layers with no accessors at all
const filteredLayers = state.layers.filter(
({ accessors, xAccessor, splitAccessor }: LayerConfig) =>
({ accessors, xAccessor, splitAccessor }: XYLayerConfig) =>
accessors.length > 0 || xAccessor != null || splitAccessor != null
);
for (const [dimension, criteria] of checks) {
@ -382,7 +382,7 @@ export const getXyVisualization = ({
const layers = state.layers;
const filteredLayers = layers.filter(({ accessors }: LayerConfig) => accessors.length > 0);
const filteredLayers = layers.filter(({ accessors }: XYLayerConfig) => accessors.length > 0);
const accessorsWithArrayValues = [];
for (const layer of filteredLayers) {
const { layerId, accessors } = layer;
@ -409,8 +409,8 @@ export const getXyVisualization = ({
function validateLayersForDimension(
dimension: string,
layers: LayerConfig[],
missingCriteria: (layer: LayerConfig) => boolean
layers: XYLayerConfig[],
missingCriteria: (layer: XYLayerConfig) => boolean
):
| { valid: true }
| {
@ -480,7 +480,7 @@ function getMessageIdsForDimension(dimension: string, layers: number[], isHorizo
return { shortMessage: '', longMessage: '' };
}
function newLayerState(seriesType: SeriesType, layerId: string): LayerConfig {
function newLayerState(seriesType: SeriesType, layerId: string): XYLayerConfig {
return {
layerId,
seriesType,

View file

@ -15,7 +15,7 @@ import {
TableSuggestion,
TableChangeType,
} from '../types';
import { State, SeriesType, XYState, visualizationTypes, LayerConfig } from './types';
import { State, SeriesType, XYState, visualizationTypes, XYLayerConfig } from './types';
import { getIconForSeries } from './state_helpers';
const columnSortOrder = {
@ -485,7 +485,7 @@ function buildSuggestion({
splitBy = xValue;
xValue = undefined;
}
const existingLayer: LayerConfig | {} = getExistingLayer(currentState, layerId) || {};
const existingLayer: XYLayerConfig | {} = getExistingLayer(currentState, layerId) || {};
const accessors = yValues.map((col) => col.columnId);
const newLayer = {
...existingLayer,

View file

@ -1,5 +1,12 @@
# Lens
Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads.
## Embedding
It's possible to embed Lens visualizations in other apps using `EmbeddableComponent` and `navigateToPrefilledEditor`
exposed via contract. For more information check out the example in `x-pack/examples/embedded_lens_example`.
## Testing
Run all tests from the `x-pack` root directory