Skip to content

Commit

Permalink
Support formatted tooltip for events (#4123)
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com>
  • Loading branch information
ohltyler authored May 24, 2023
1 parent 2f94a6d commit 570a1c4
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 33 deletions.
53 changes: 33 additions & 20 deletions src/plugins/vis_augmenter/public/test_constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const TEST_VALUE_AXIS_ID_DIRTY = 'test.value.axis.id';
const TEST_X_AXIS_TITLE = 'time';
const TEST_VALUE_AXIS_TITLE = 'avg value';
const TEST_PLUGIN = 'test-plugin';
const TEST_PLUGIN_EVENT_TYPE = 'test-plugin-event-type';
const TEST_PLUGIN_EVENT_TYPE_2 = 'test-plugin-event-type-2';
const TEST_PLUGIN_RESOURCE_TYPE = 'test-resource-type';
const TEST_PLUGIN_RESOURCE_ID = 'test-resource-id';
const TEST_PLUGIN_RESOURCE_ID_2 = 'test-resource-id-2';
Expand All @@ -25,18 +27,18 @@ const TEST_PLUGIN_RESOURCE_PATH_2 = `${TEST_PLUGIN}/${TEST_PLUGIN_RESOURCE_TYPE}
const TEST_VALUES_SINGLE_ROW_NO_VIS_LAYERS = [{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5 }];

const TEST_VALUES_SINGLE_ROW_SINGLE_VIS_LAYER = [
{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_RESOURCE_ID]: 3 },
{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_EVENT_TYPE]: 3 },
];

const TEST_VALUES_ONLY_VIS_LAYERS = [
{ [TEST_X_AXIS_ID]: 0 },
{ [TEST_X_AXIS_ID]: 5, [TEST_PLUGIN_RESOURCE_ID]: 2 },
{ [TEST_X_AXIS_ID]: 5, [TEST_PLUGIN_EVENT_TYPE]: 2 },
{ [TEST_X_AXIS_ID]: 10 },
{ [TEST_X_AXIS_ID]: 15 },
{ [TEST_X_AXIS_ID]: 20 },
{ [TEST_X_AXIS_ID]: 25 },
{ [TEST_X_AXIS_ID]: 30 },
{ [TEST_X_AXIS_ID]: 35, [TEST_PLUGIN_RESOURCE_ID]: 1 },
{ [TEST_X_AXIS_ID]: 35, [TEST_PLUGIN_EVENT_TYPE]: 1 },
{ [TEST_X_AXIS_ID]: 40 },
{ [TEST_X_AXIS_ID]: 45 },
{ [TEST_X_AXIS_ID]: 50 },
Expand Down Expand Up @@ -72,20 +74,20 @@ const TEST_VALUES_NO_VIS_LAYERS_DIRTY = [

const TEST_VALUES_SINGLE_VIS_LAYER = [
{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5 },
{ [TEST_X_AXIS_ID]: 5, [TEST_VALUE_AXIS_ID]: 10, [TEST_PLUGIN_RESOURCE_ID]: 2 },
{ [TEST_X_AXIS_ID]: 5, [TEST_VALUE_AXIS_ID]: 10, [TEST_PLUGIN_EVENT_TYPE]: 2 },
{ [TEST_X_AXIS_ID]: 10, [TEST_VALUE_AXIS_ID]: 6 },
{ [TEST_X_AXIS_ID]: 15, [TEST_VALUE_AXIS_ID]: 4 },
{ [TEST_X_AXIS_ID]: 20, [TEST_VALUE_AXIS_ID]: 5 },
{ [TEST_X_AXIS_ID]: 25 },
{ [TEST_X_AXIS_ID]: 30 },
{ [TEST_X_AXIS_ID]: 35, [TEST_PLUGIN_RESOURCE_ID]: 1 },
{ [TEST_X_AXIS_ID]: 35, [TEST_PLUGIN_EVENT_TYPE]: 1 },
{ [TEST_X_AXIS_ID]: 40 },
{ [TEST_X_AXIS_ID]: 45, [TEST_VALUE_AXIS_ID]: 3 },
{ [TEST_X_AXIS_ID]: 50, [TEST_VALUE_AXIS_ID]: 5 },
];

const TEST_VALUES_SINGLE_VIS_LAYER_ON_BOUNDS = [
{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_RESOURCE_ID]: 2 },
{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_EVENT_TYPE]: 2 },
{ [TEST_X_AXIS_ID]: 5, [TEST_VALUE_AXIS_ID]: 10 },
{ [TEST_X_AXIS_ID]: 10, [TEST_VALUE_AXIS_ID]: 6 },
{ [TEST_X_AXIS_ID]: 15, [TEST_VALUE_AXIS_ID]: 4 },
Expand All @@ -95,26 +97,26 @@ const TEST_VALUES_SINGLE_VIS_LAYER_ON_BOUNDS = [
{ [TEST_X_AXIS_ID]: 35 },
{ [TEST_X_AXIS_ID]: 40 },
{ [TEST_X_AXIS_ID]: 45, [TEST_VALUE_AXIS_ID]: 3 },
{ [TEST_X_AXIS_ID]: 50, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_RESOURCE_ID]: 1 },
{ [TEST_X_AXIS_ID]: 50, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_EVENT_TYPE]: 1 },
];

const TEST_VALUES_MULTIPLE_VIS_LAYERS = [
{ [TEST_X_AXIS_ID]: 0, [TEST_VALUE_AXIS_ID]: 5 },
{
[TEST_X_AXIS_ID]: 5,
[TEST_VALUE_AXIS_ID]: 10,
[TEST_PLUGIN_RESOURCE_ID]: 2,
[TEST_PLUGIN_RESOURCE_ID_2]: 1,
[TEST_PLUGIN_EVENT_TYPE]: 2,
[TEST_PLUGIN_EVENT_TYPE_2]: 1,
},
{ [TEST_X_AXIS_ID]: 10, [TEST_VALUE_AXIS_ID]: 6 },
{ [TEST_X_AXIS_ID]: 15, [TEST_VALUE_AXIS_ID]: 4, [TEST_PLUGIN_RESOURCE_ID_2]: 1 },
{ [TEST_X_AXIS_ID]: 15, [TEST_VALUE_AXIS_ID]: 4, [TEST_PLUGIN_EVENT_TYPE_2]: 1 },
{ [TEST_X_AXIS_ID]: 20, [TEST_VALUE_AXIS_ID]: 5 },
{ [TEST_X_AXIS_ID]: 25 },
{ [TEST_X_AXIS_ID]: 30 },
{ [TEST_X_AXIS_ID]: 35, [TEST_PLUGIN_RESOURCE_ID]: 1 },
{ [TEST_X_AXIS_ID]: 35, [TEST_PLUGIN_EVENT_TYPE]: 1 },
{ [TEST_X_AXIS_ID]: 40 },
{ [TEST_X_AXIS_ID]: 45, [TEST_VALUE_AXIS_ID]: 3 },
{ [TEST_X_AXIS_ID]: 50, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_RESOURCE_ID_2]: 2 },
{ [TEST_X_AXIS_ID]: 50, [TEST_VALUE_AXIS_ID]: 5, [TEST_PLUGIN_EVENT_TYPE_2]: 2 },
];

export const TEST_COLUMNS_NO_VIS_LAYERS = [
Expand Down Expand Up @@ -142,8 +144,8 @@ export const TEST_COLUMNS_NO_VIS_LAYERS_DIRTY = [
export const TEST_COLUMNS_SINGLE_VIS_LAYER = [
...TEST_COLUMNS_NO_VIS_LAYERS,
{
id: TEST_PLUGIN_RESOURCE_ID,
name: TEST_PLUGIN_RESOURCE_NAME,
id: TEST_PLUGIN_EVENT_TYPE,
name: `${TEST_PLUGIN_EVENT_TYPE} count`,
meta: {
type: VIS_LAYER_COLUMN_TYPE,
},
Expand All @@ -153,8 +155,8 @@ export const TEST_COLUMNS_SINGLE_VIS_LAYER = [
export const TEST_COLUMNS_MULTIPLE_VIS_LAYERS = [
...TEST_COLUMNS_SINGLE_VIS_LAYER,
{
id: TEST_PLUGIN_RESOURCE_ID_2,
name: TEST_PLUGIN_RESOURCE_NAME_2,
id: TEST_PLUGIN_EVENT_TYPE_2,
name: `${TEST_PLUGIN_EVENT_TYPE_2} count`,
meta: {
type: VIS_LAYER_COLUMN_TYPE,
},
Expand Down Expand Up @@ -322,6 +324,7 @@ export const TEST_VIS_LAYERS_SINGLE = [
name: TEST_PLUGIN_RESOURCE_NAME,
urlPath: TEST_PLUGIN_RESOURCE_PATH,
},
pluginEventType: TEST_PLUGIN_EVENT_TYPE,
events: [
{
timestamp: 4,
Expand Down Expand Up @@ -355,6 +358,7 @@ export const TEST_VIS_LAYERS_SINGLE_INVALID_BOUNDS = [
name: TEST_PLUGIN_RESOURCE_NAME,
urlPath: TEST_PLUGIN_RESOURCE_PATH,
},
pluginEventType: TEST_PLUGIN_EVENT_TYPE,
events: [
{
timestamp: -5,
Expand Down Expand Up @@ -388,6 +392,7 @@ export const TEST_VIS_LAYERS_SINGLE_EMPTY_EVENTS = [
name: TEST_PLUGIN_RESOURCE_NAME,
urlPath: TEST_PLUGIN_RESOURCE_PATH,
},
pluginEventType: TEST_PLUGIN_EVENT_TYPE,
},
];

Expand All @@ -401,6 +406,7 @@ export const TEST_VIS_LAYERS_SINGLE_ON_BOUNDS = [
name: TEST_PLUGIN_RESOURCE_NAME,
urlPath: TEST_PLUGIN_RESOURCE_PATH,
},
pluginEventType: TEST_PLUGIN_EVENT_TYPE,
events: [
{
timestamp: 0,
Expand Down Expand Up @@ -435,6 +441,7 @@ export const TEST_VIS_LAYERS_MULTIPLE = [
name: TEST_PLUGIN_RESOURCE_NAME_2,
urlPath: TEST_PLUGIN_RESOURCE_PATH_2,
},
pluginEventType: TEST_PLUGIN_EVENT_TYPE_2,
events: [
{
timestamp: 5,
Expand Down Expand Up @@ -466,7 +473,7 @@ export const TEST_VIS_LAYERS_MULTIPLE = [

const TEST_RULE_LAYER_SINGLE_VIS_LAYER = {
mark: { type: 'rule', color: 'red', opacity: 1 },
transform: [{ filter: `datum['${TEST_PLUGIN_RESOURCE_ID}'] > 0` }],
transform: [{ filter: `datum['${TEST_PLUGIN_EVENT_TYPE}'] > 0` }],
encoding: {
x: { field: TEST_X_AXIS_ID, type: 'temporal' },
opacity: { value: 0, condition: { empty: false, param: HOVER_PARAM, value: 1 } },
Expand All @@ -477,7 +484,7 @@ const TEST_RULE_LAYER_MULTIPLE_VIS_LAYERS = {
...TEST_RULE_LAYER_SINGLE_VIS_LAYER,
transform: [
{
filter: `datum['${TEST_PLUGIN_RESOURCE_ID}'] > 0 || datum['${TEST_PLUGIN_RESOURCE_ID_2}'] > 0`,
filter: `datum['${TEST_PLUGIN_EVENT_TYPE}'] > 0 || datum['${TEST_PLUGIN_EVENT_TYPE_2}'] > 0`,
},
],
};
Expand All @@ -491,9 +498,10 @@ const TEST_EVENTS_LAYER_SINGLE_VIS_LAYER = {
filled: true,
opacity: 1,
style: [`${VisAnnotationType.POINT_IN_TIME_ANNOTATION}`],
tooltip: true,
},
transform: [
{ filter: `datum['${TEST_PLUGIN_RESOURCE_ID}'] > 0` },
{ filter: `datum['${TEST_PLUGIN_EVENT_TYPE}'] > 0` },
{ calculate: `'${VisAnnotationType.POINT_IN_TIME_ANNOTATION}'`, as: 'annotationType' },
],
params: [{ name: HOVER_PARAM, select: { type: 'point', on: 'mouseover' } }],
Expand Down Expand Up @@ -532,17 +540,22 @@ const TEST_EVENTS_LAYER_SINGLE_VIS_LAYER = {
},
},
size: { condition: { empty: false, param: HOVER_PARAM, value: 140 }, value: 100 },
tooltip: [{ field: TEST_PLUGIN_EVENT_TYPE }],
},
};

const TEST_EVENTS_LAYER_MULTIPLE_VIS_LAYERS = {
...TEST_EVENTS_LAYER_SINGLE_VIS_LAYER,
transform: [
{
filter: `datum['${TEST_PLUGIN_RESOURCE_ID}'] > 0 || datum['${TEST_PLUGIN_RESOURCE_ID_2}'] > 0`,
filter: `datum['${TEST_PLUGIN_EVENT_TYPE}'] > 0 || datum['${TEST_PLUGIN_EVENT_TYPE_2}'] > 0`,
},
{ calculate: `'${VisAnnotationType.POINT_IN_TIME_ANNOTATION}'`, as: 'annotationType' },
],
encoding: {
...TEST_EVENTS_LAYER_SINGLE_VIS_LAYER.encoding,
tooltip: [{ field: TEST_PLUGIN_EVENT_TYPE }, { field: TEST_PLUGIN_EVENT_TYPE_2 }],
},
};

export const TEST_RESULT_SPEC_SINGLE_VIS_LAYER = {
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/vis_augmenter/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export type VisLayers = VisLayer[];

export interface EventMetadata {
pluginResourceId: string;
tooltip?: string;
}

export interface PointInTimeEvent {
Expand All @@ -47,6 +46,7 @@ export interface PointInTimeEvent {

export interface PointInTimeEventsVisLayer extends VisLayer {
events: PointInTimeEvent[];
pluginEventType: string;
}

export const isPointInTimeEventsVisLayer = (obj: any) => {
Expand Down
21 changes: 20 additions & 1 deletion src/plugins/vis_augmenter/public/vega/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
addMissingRowsToTableBounds,
addPointInTimeEventsLayersToTable,
addPointInTimeEventsLayersToSpec,
generateVisLayerTooltipFields,
} from './helpers';
import { VIS_LAYER_COLUMN_TYPE, VisLayerTypes, PointInTimeEventsVisLayer, VisLayer } from '../';
import {
Expand Down Expand Up @@ -178,6 +179,24 @@ describe('helpers', function () {
});
});

describe('generateVisLayerTooltipFields()', function () {
it('empty array returns empty', function () {
const visLayerColumnIds = [] as string[];
const tooltipFields = [] as Array<{ field: string }>;
expect(generateVisLayerTooltipFields(visLayerColumnIds)).toStrictEqual(tooltipFields);
});
it('array with one value returns correct array', function () {
const visLayerColumnIds = ['test-id-1'];
const tooltipFields = [{ field: 'test-id-1' }];
expect(generateVisLayerTooltipFields(visLayerColumnIds)).toStrictEqual(tooltipFields);
});
it('array with multiple values returns correct array', function () {
const visLayerColumnIds = ['test-id-1', 'test-id-2'];
const tooltipFields = [{ field: 'test-id-1' }, { field: 'test-id-2' }];
expect(generateVisLayerTooltipFields(visLayerColumnIds)).toStrictEqual(tooltipFields);
});
});

describe('addMissingRowsToTableBounds()', function () {
const columnId = 'test-id';
const columnName = 'test-name';
Expand Down Expand Up @@ -356,7 +375,7 @@ describe('helpers', function () {
TEST_VIS_LAYERS_SINGLE
)
).toStrictEqual({
...TEST_DATATABLE_SINGLE_VIS_LAYER_EMPTY,
...TEST_DATATABLE_NO_VIS_LAYERS,
rows: [],
});
});
Expand Down
37 changes: 26 additions & 11 deletions src/plugins/vis_augmenter/public/vega/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ export const generateVisLayerFilterString = (visLayerColumnIds: string[]): strin
}
};

export const generateVisLayerTooltipFields = (
visLayerColumnIds: string[]
): Array<{ field: string }> => {
return visLayerColumnIds.map((id) => {
return {
field: id,
};
});
};

/**
* By default, the source datatable will not include rows with empty data.
* For handling events that may belong in missing buckets that are not yet
Expand Down Expand Up @@ -195,28 +205,34 @@ export const addPointInTimeEventsLayersToTable = (
const augmentedTable = addMissingRowsToTableBounds(datatable, dimensions);
const xAxisId = getXAxisId(dimensions, augmentedTable.columns);

if (isEmpty(visLayers)) return augmentedTable;
if (isEmpty(visLayers) || augmentedTable.rows.length === 0) return augmentedTable;

visLayers.every((visLayer: PointInTimeEventsVisLayer) => {
const visLayerColumnId = `${visLayer.pluginResource.id}`;
const visLayerColumnName = `${visLayer.pluginResource.name}`;
// Create columns for every unique event type. This is so we can aggregate on the different event types
// (e.g., 'Anomalies', 'Alerts')
[
...new Set(visLayers.map((visLayer: PointInTimeEventsVisLayer) => visLayer.pluginEventType)),
].forEach((pluginEventType: string) => {
augmentedTable.columns.push({
id: visLayerColumnId,
name: visLayerColumnName,
id: pluginEventType,
name: `${pluginEventType} count`,
meta: {
type: VIS_LAYER_COLUMN_TYPE,
},
});
});

if (augmentedTable.rows.length === 0 || isEmpty(visLayer.events)) return false;
visLayers.forEach((visLayer: PointInTimeEventsVisLayer) => {
if (isEmpty(visLayer.events)) return;
const visLayerColumnId = `${visLayer.pluginEventType}`;

// if only one row / one datapoint, put all events into this bucket
if (augmentedTable.rows.length === 1) {
augmentedTable.rows[0] = {
...augmentedTable.rows[0],
[visLayerColumnId]: visLayer.events.length,
[visLayerColumnId]:
(get(augmentedTable.rows[0], visLayerColumnId, 0) as number) + visLayer.events.length,
};
return false;
return;
}

// Bin the timestamps to the closest x-axis key, adding
Expand Down Expand Up @@ -267,8 +283,6 @@ export const addPointInTimeEventsLayersToTable = (
break;
}
});

return true;
});
return augmentedTable;
};
Expand Down Expand Up @@ -372,6 +386,7 @@ export const addPointInTimeEventsLayersToSpec = (
condition: { empty: false, param: HOVER_PARAM, value: EVENT_MARK_SIZE_ENLARGED },
value: EVENT_MARK_SIZE,
},
tooltip: generateVisLayerTooltipFields(visLayerColumnIds),
},
});

Expand Down

0 comments on commit 570a1c4

Please sign in to comment.