Skip to content

Commit

Permalink
[Exploratory view] Core web vitals (#100320) (#101144)
Browse files Browse the repository at this point in the history
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Shahzad <shahzad.muhammad@elastic.co>
  • Loading branch information
kibanamachine and shahzad31 committed Jun 2, 2021
1 parent 4202cb4 commit 54b8d28
Show file tree
Hide file tree
Showing 20 changed files with 354 additions and 74 deletions.
1 change: 1 addition & 0 deletions x-pack/plugins/lens/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type {
ValueLabelConfig,
YAxisMode,
XYCurveType,
YConfig,
} from './xy_visualization/types';
export type { DataType, OperationMetadata } from './types';
export type {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
BROWSER_FAMILY_LABEL,
BROWSER_VERSION_LABEL,
CLS_LABEL,
CORE_WEB_VITALS_LABEL,
CPU_USAGE_LABEL,
DEVICE_LABEL,
ENVIRONMENT_LABEL,
Expand Down Expand Up @@ -92,6 +93,7 @@ export const DataViewLabels: Record<ReportViewTypeId, string> = {
logs: LOGS_FREQUENCY_LABEL,
mem: MEMORY_USAGE_LABEL,
nwk: NETWORK_ACTIVITY_LABEL,
cwv: CORE_WEB_VITALS_LABEL,
};

export const ReportToDataTypeMap: Record<ReportViewTypeId, AppDataType> = {
Expand All @@ -105,4 +107,9 @@ export const ReportToDataTypeMap: Record<ReportViewTypeId, AppDataType> = {
mem: 'infra_metrics',
logs: 'infra_logs',
cpu: 'infra_metrics',
cwv: 'ux',
};

export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN';
export const FILTER_RECORDS = 'FILTER_RECORDS';
export const OPERATION_COLUMN = 'operation';
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const TRANSACTION_URL = 'url.full';
export const CLIENT_GEO = 'client.geo';
export const USER_AGENT_DEVICE = 'user_agent.device.name';
export const USER_AGENT_OS = 'user_agent.os.name';
export const USER_AGENT_OS_VERSION = 'user_agent.os.version';

export const TRANSACTION_TIME_TO_FIRST_BYTE = 'transaction.marks.agent.timeToFirstByte';
export const TRANSACTION_DOM_INTERACTIVE = 'transaction.marks.agent.domInteractive';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ export const NETWORK_ACTIVITY_LABEL = i18n.translate(
defaultMessage: 'Network activity',
}
);

export const CORE_WEB_VITALS_LABEL = i18n.translate(
'xpack.observability.expView.fieldLabels.coreWebVitals',
{
defaultMessage: 'Core web vitals',
}
);

export const MEMORY_USAGE_LABEL = i18n.translate(
'xpack.observability.expView.fieldLabels.memoryUsage',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { getMemoryUsageLensConfig } from './metrics/memory_usage_config';
import { getNetworkActivityLensConfig } from './metrics/network_activity_config';
import { getLogsFrequencyLensConfig } from './logs/logs_frequency_config';
import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';
import { getCoreWebVitalsConfig } from './rum/core_web_vitals_config';

interface Props {
reportType: keyof typeof ReportViewTypes;
Expand All @@ -30,6 +31,8 @@ export const getDefaultConfigs = ({ reportType, seriesId, indexPattern }: Props)
return getPerformanceDistLensConfig({ seriesId, indexPattern });
case 'kpi-trends':
return getKPITrendsLensConfig({ seriesId, indexPattern });
case 'core-web-vitals':
return getCoreWebVitalsConfig({ seriesId, indexPattern });
case 'uptime-duration':
return getMonitorDurationConfig({ seriesId, indexPattern });
case 'uptime-pings':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ describe('Lens Attribute', () => {
orderBy: { columnId: 'y-axis-column', type: 'column' },
orderDirection: 'desc',
otherBucket: true,
size: 3,
size: 10,
},
scale: 'ordinal',
sourceField: 'user_agent.name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import {
OperationMetadata,
FieldBasedIndexPatternColumn,
SumIndexPatternColumn,
TermsIndexPatternColumn,
} from '../../../../../../lens/public';
import {
buildPhraseFilter,
buildPhrasesFilter,
IndexPattern,
} from '../../../../../../../../src/plugins/data/common';
import { FieldLabels } from './constants';
import { DataSeries, UrlFilter, URLReportDefinition } from '../types';
import { FieldLabels, FILTER_RECORDS, USE_BREAK_DOWN_COLUMN } from './constants';
import { ColumnFilter, DataSeries, UrlFilter, URLReportDefinition } from '../types';

function getLayerReferenceName(layerId: string) {
return `indexpattern-datasource-layer-${layerId}`;
Expand All @@ -53,6 +54,7 @@ export const parseCustomFieldName = (
) => {
let fieldName = sourceField;
let columnType;
let columnFilters;

const rdf = reportViewConfig.reportDefinitions ?? [];

Expand All @@ -61,17 +63,21 @@ export const parseCustomFieldName = (
if (customField) {
if (selectedDefinitions[fieldName]) {
fieldName = selectedDefinitions[fieldName][0];
if (customField?.options)
columnType = customField?.options?.find(({ field }) => field === fieldName)?.columnType;
} else if (customField.defaultValue) {
fieldName = customField.defaultValue;
} else if (customField.options?.[0].field) {
fieldName = customField.options?.[0].field;
if (customField?.options) {
const currField = customField?.options?.find(
({ field, id }) => field === fieldName || id === fieldName
);
columnType = currField?.columnType;
columnFilters = currField?.columnFilters;
}
} else if (customField.options?.[0].field || customField.options?.[0].id) {
fieldName = customField.options?.[0].field || customField.options?.[0].id;
columnType = customField.options?.[0].columnType;
columnFilters = customField.options?.[0].columnFilters;
}
}

return { fieldName, columnType };
return { fieldName, columnType, columnFilters };
};

export class LensAttributes {
Expand All @@ -82,19 +88,22 @@ export class LensAttributes {
seriesType: SeriesType;
reportViewConfig: DataSeries;
reportDefinitions: URLReportDefinition;
breakdownSource?: string;

constructor(
indexPattern: IndexPattern,
reportViewConfig: DataSeries,
seriesType?: SeriesType,
filters?: UrlFilter[],
operationType?: OperationType,
reportDefinitions?: URLReportDefinition
reportDefinitions?: URLReportDefinition,
breakdownSource?: string
) {
this.indexPattern = indexPattern;
this.layers = {};
this.filters = filters ?? [];
this.reportDefinitions = reportDefinitions ?? {};
this.breakdownSource = breakdownSource;

if (operationType) {
reportViewConfig.yAxisColumns.forEach((yAxisColumn) => {
Expand All @@ -109,24 +118,33 @@ export class LensAttributes {
this.visualization = this.getXyState();
}

addBreakdown(sourceField: string) {
getBreakdownColumn(sourceField: string): TermsIndexPatternColumn {
const fieldMeta = this.indexPattern.getFieldByName(sourceField);

this.layers.layer1.columns['break-down-column'] = {
return {
sourceField,
label: `Top values of ${FieldLabels[sourceField]}`,
dataType: fieldMeta?.type as DataType,
operationType: 'terms',
scale: 'ordinal',
isBucketed: true,
params: {
size: 3,
size: 10,
orderBy: { type: 'column', columnId: 'y-axis-column' },
orderDirection: 'desc',
otherBucket: true,
missingBucket: false,
},
};
}

addBreakdown(sourceField: string) {
const { xAxisColumn } = this.reportViewConfig;
if (xAxisColumn?.sourceField === USE_BREAK_DOWN_COLUMN) {
// do nothing since this will be used a x axis source
return;
}
this.layers.layer1.columns['break-down-column'] = this.getBreakdownColumn(sourceField);

this.layers.layer1.columnOrder = [
'x-axis-column',
Expand Down Expand Up @@ -229,15 +247,27 @@ export class LensAttributes {
getXAxis() {
const { xAxisColumn } = this.reportViewConfig;

if (xAxisColumn?.sourceField === USE_BREAK_DOWN_COLUMN) {
return this.getBreakdownColumn(this.breakdownSource || this.reportViewConfig.breakdowns[0]);
}

return this.getColumnBasedOnType(xAxisColumn.sourceField!, undefined, xAxisColumn.label);
}

getColumnBasedOnType(sourceField: string, operationType?: OperationType, label?: string) {
const { fieldMeta, columnType, fieldName } = this.getFieldMeta(sourceField);
getColumnBasedOnType(
sourceField: string,
operationType?: OperationType,
label?: string,
colIndex?: number
) {
const { fieldMeta, columnType, fieldName, columnFilters } = this.getFieldMeta(sourceField);
const { type: fieldType } = fieldMeta ?? {};

if (fieldName === 'Records') {
return this.getRecordsColumn();
if (fieldName === 'Records' || columnType === FILTER_RECORDS) {
return this.getRecordsColumn(
label,
colIndex !== undefined ? columnFilters?.[colIndex] : undefined
);
}

if (fieldType === 'date') {
Expand All @@ -256,11 +286,11 @@ export class LensAttributes {
}

getFieldMeta(sourceField: string) {
const { fieldName, columnType } = this.getCustomFieldName(sourceField);
const { fieldName, columnType, columnFilters } = this.getCustomFieldName(sourceField);

const fieldMeta = this.indexPattern.getFieldByName(fieldName);

return { fieldMeta, fieldName, columnType };
return { fieldMeta, fieldName, columnType, columnFilters };
}

getMainYAxis() {
Expand All @@ -270,7 +300,7 @@ export class LensAttributes {
return this.getRecordsColumn(label);
}

return this.getColumnBasedOnType(sourceField!, operationType, label);
return this.getColumnBasedOnType(sourceField!, operationType, label, 0);
}

getChildYAxises() {
Expand All @@ -286,20 +316,22 @@ export class LensAttributes {
lensColumns[`y-axis-column-${i}`] = this.getColumnBasedOnType(
sourceField!,
operationType,
label
label,
i
);
}
return lensColumns;
}

getRecordsColumn(label?: string): CountIndexPatternColumn {
getRecordsColumn(label?: string, columnFilter?: ColumnFilter): CountIndexPatternColumn {
return {
dataType: 'number',
isBucketed: false,
label: label || 'Count of records',
operationType: 'count',
scale: 'ratio',
sourceField: 'Records',
filter: columnFilter,
} as CountIndexPatternColumn;
}

Expand Down Expand Up @@ -331,7 +363,9 @@ export class LensAttributes {
layerId: 'layer1',
seriesType: this.seriesType ?? 'line',
palette: this.reportViewConfig.palette,
yConfig: [{ forAccessor: 'y-axis-column', color: 'green' }],
yConfig: this.reportViewConfig.yConfig || [
{ forAccessor: 'y-axis-column', color: 'green' },
],
xAccessor: 'x-axis-column',
},
],
Expand Down
Loading

0 comments on commit 54b8d28

Please sign in to comment.