Skip to content

Commit

Permalink
[Feature]: Treemap chart support in Event Analytics (#693)
Browse files Browse the repository at this point in the history
* Initial commit for treemap visualization

Signed-off-by: Mrunal Zambre <[email protected]>

* changes to labelField, layout and config

Signed-off-by: Mrunal Zambre <[email protected]>

* reverted changes of layoutConfig

Signed-off-by: Mrunal Zambre <[email protected]>

* Cypress TestCase for TreeMap

Signed-off-by: Nidhi Singhai <[email protected]>

* added new line

Signed-off-by: Mrunal Zambre <[email protected]>

* updated test cases

Signed-off-by: Mrunal Zambre <[email protected]>

* reverted snapshots

Signed-off-by: Mrunal Zambre <[email protected]>

* implemented treemap config options

Signed-off-by: Mrunal Zambre <[email protected]>

* added multicolored theme option

Signed-off-by: Mrunal Zambre <[email protected]>

* updated snapshots

Signed-off-by: Mrunal Zambre <[email protected]>

* Updated test scripts for multicolored section

Signed-off-by: Pratibha Pandey <[email protected]>

* Fixed default selection for treemap

Signed-off-by: Mrunal Zambre <[email protected]>

Co-authored-by: Nidhi Singhai <[email protected]>
Co-authored-by: Pratibha Pandey <[email protected]>
  • Loading branch information
3 people authored Jun 9, 2022
1 parent 4fa6e82 commit ec75f52
Show file tree
Hide file tree
Showing 15 changed files with 1,607 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,34 @@ import {
landOnEventHome,
landOnEventExplorer,
landOnEventVisualizations,
landOnPanels
landOnPanels,
renderTreeMapchart
} from '../utils/event_constants';
import { supressResizeObserverIssue } from '../utils/constants';

const vis_name_sub_string = Math.floor(Math.random() * 100);
const saveVisualizationAndVerify = () => {
cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click();
cy.get('[data-test-subj="eventExplorer__querySaveComboBox"]').click()
cy.get('.euiComboBoxOptionsList__rowWrap .euiFilterSelectItem').eq(0).click();
cy.get('.euiPopover__panel .euiFormControlLayoutIcons [data-test-subj="comboBoxToggleListButton"]').eq(0).click();
cy.get('.euiPopover__panel input').eq(1).type(`Test visualization` + vis_name_sub_string);
cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
cy.wait(delay);
cy.get('.euiHeaderBreadcrumbs a').eq(1).click();
cy.get('.euiFlexGroup .euiFormControlLayout__childrenWrapper input').eq(0).type(`Test visualization` + vis_name_sub_string).type('{enter}');
cy.get('.euiBasicTable .euiTableCellContent button').eq(0).click();
}
const deleteVisualization = () => {
cy.get('a[href = "#/event_analytics"]').click();
cy.get('.euiFlexGroup .euiFormControlLayout__childrenWrapper input').eq(0).type(`Test visualization`).type('{enter}');
cy.get('input[data-test-subj = "checkboxSelectAll"]').click();
cy.get('.euiButtonContent.euiButtonContent--iconRight.euiButton__content').click();
cy.get('.euiContextMenuItem .euiContextMenuItem__text').eq(0).click();
cy.get('input[placeholder = "delete"]').clear().type('delete');
cy.get('button[data-test-subj = "popoverModal__deleteButton"]').click();
cy.get('.euiToastHeader').should('exist');
}
describe('Adding sample data and visualization', () => {
it('Adds sample flights data for event analytics', () => {
cy.visit(`${Cypress.env('opensearchDashboards')}/app/home#/tutorial_directory/sampleData`);
Expand Down Expand Up @@ -659,4 +683,133 @@ describe('Renders chart and verify Toast message if X-axis and Y-axis values are
cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click();
cy.get('[data-test-subj="euiToastHeader"]').contains('Invalid value options configuration selected.').should('exist');
});
});
});

describe('Renders Tree Map', () => {
beforeEach(() => {
landOnEventVisualizations();
});

it('Renders Tree Map', () => {
renderTreeMapchart();
cy.get('.euiFlexItem.euiFlexItem--flexGrowZero .euiButton__text').eq(2).click();
cy.get('path.surface').should('have.length', 176);
});

it('Renders Tree Map, add value parameters and verify Reset button click is working', () => {
renderTreeMapchart();
cy.get('.euiFlexItem.euiFlexItem--flexGrowZero .euiButton__text').eq(2).click();
cy.get('[data-test-subj="visualizeEditorResetButton"]').click();
cy.get('#configPanel__panelOptions .euiFieldText').should('have.value', '');
cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').should('have.value', '');
cy.get('.euiComboBox__inputWrap.euiComboBox__inputWrap-isClearable').eq(1).should('have.value', '');
cy.get('.euiComboBox__inputWrap.euiComboBox__inputWrap-isClearable').eq(2).should('have.value', '');
cy.get('.euiComboBox__inputWrap.euiComboBox__inputWrap-isClearable').eq(3).should('have.value', '');
});

it('Renders Tree Map, Save and Delete Visualization', () => {
renderTreeMapchart();
cy.get('.euiFlexItem.euiFlexItem--flexGrowZero .euiButton__text').eq(2).click();
saveVisualizationAndVerify();
cy.wait(delay * 4);
deleteVisualization();
});

it('Render Tree Map chart and verify color theme under Chart styles options', () =>{
renderTreeMapchart();
cy.get('.euiTitle.euiTitle--xxsmall').contains('Color Theme').should('exist');
cy.get('.euiSuperSelectControl').contains('Default').click();
cy.get('.euiContextMenuItem__text .euiColorPalettePicker__item').eq(1).contains('Single color').click();
cy.get('.euiFieldText.euiColorPicker__input.euiFieldText--withIcon').click();
cy.get('[aria-label="Select #D36086 as the color"]').click();
cy.get('.euiButton__text').contains('Preview').should('exist').click();
cy.get('path[style*="rgb(29, 30, 36)"]').eq(0).should('exist');
cy.get('.euiSuperSelectControl').click();
cy.get('.euiColorPalettePicker__itemTitle').eq(1).contains('Reds').click();
cy.get('.euiButton__text').contains('Preview').should('exist').click();
cy.get('path[style*="rgb(68, 68, 68)"]').eq(0).should('exist');
});

it('Traverse between root and parent node in Tree Map chart', () => {
querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM);
cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}');
cy.get('#configPanel__panelOptions .euiFieldText').click().type('Tree Map');
cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').click().type('This is the description for Tree Map');
cy.get('.euiComboBox__inputWrap.euiComboBox__inputWrap-isClearable').eq(0).click();
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(1).click();
cy.get('.euiComboBoxOption__content').eq(2).click();
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(2).click();
cy.get('.euiComboBoxOption__content').eq(1).click();
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(3).click();
cy.get('.euiComboBoxOption__content').eq(0).click();
cy.wait(delay);
cy.get('.euiSuperSelectControl').click();
cy.get('.euiColorPalettePicker__itemTitle').eq(1).contains('Reds').click();
cy.get('.euiButton__text').contains('Preview').should('exist').click();
cy.get('.slicetext[data-unformatted="US"]').click({force:true});
cy.wait(delay);
cy.get('.slicetext[data-unformatted*="Cleveland"]').click({force:true});
cy.get('text.slicetext').contains('100% of entry').should('exist');
cy.get('.pathbar.cursor-pointer .slicetext[data-unformatted="US"]').click({force:true});
cy.wait(delay);
cy.get('.pathbar.cursor-pointer .slicetext[data-unformatted=" "]').click({force:true});
});

it('"No results found" message when user fails to select proper fields', () =>{
querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM);
cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}');
cy.get('#configPanel__panelOptions .euiFieldText').click().type('Tree Map');
cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').click().type('This is the description for Tree Map');
cy.get('.euiComboBox__inputWrap.euiComboBox__inputWrap-isClearable').eq(0).click();
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(3).click();
cy.get('.euiComboBoxOption__content').eq(1).click();
cy.wait(delay);
cy.get('.euiSuperSelectControl').click();
cy.get('.euiColorPalettePicker__itemTitle').eq(1).contains('Reds').click();
cy.get('.euiButton__text').contains('Preview').should('exist').click();
cy.get('.euiTextColor.euiTextColor--subdued').contains('No results found').should('exist');
});

it('Verify multicolored option under color theme',() =>{
renderTreeMapchart();
cy.get('.euiTitle.euiTitle--xxsmall').contains('Color Theme').should('exist');
cy.get('.euiSuperSelectControl').contains('Default').click();
cy.get('.euiContextMenuItem__text .euiColorPalettePicker__item').eq(1).contains('Single color').click();
cy.get('.euiFieldText.euiColorPicker__input.euiFieldText--withIcon').click();
cy.get('[aria-label="Select #54B399 as the color"]').should('exist').click();
cy.get('.euiButton__text').contains('Preview').click();
cy.get('.euiSuperSelectControl').click();
cy.get('.euiContextMenuItem__text .euiColorPalettePicker__item').eq(2).contains('Multicolored').click();
cy.wait(delay);
cy.get('.euiFormHelpText.euiFormRow__text').eq(1).contains('Child field').should('exist');
cy.get('.euiFieldText.euiColorPicker__input.euiFieldText--withIcon').eq(0).click();
cy.get('[aria-label="Select #D36086 as the color"]').click();
cy.get('.euiFormHelpText.euiFormRow__text').eq(2).contains('Parent field').should('exist');
cy.get('.euiFieldText.euiColorPicker__input.euiFieldText--withIcon').eq(1).click();
cy.get('[aria-label="Select #CA8EAE as the color"]').click();
cy.get('.euiButton__text').contains('Preview').click();
cy.get('.trace.treemap path[style*="rgb(202, 142, 174)"]').should('exist');
});

it('Parent field not available under color theme', () => {
querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM);
cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}');
cy.get('#configPanel__panelOptions .euiFieldText').click().type('Tree Map');
cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').click().type('This is the description for Tree Map');
cy.get('.euiTitle.euiTitle--xxsmall').contains('Color Theme').should('exist');
cy.get('.euiSuperSelectControl').contains('Default').click();
cy.get('.euiContextMenuItem__text .euiColorPalettePicker__item').eq(1).contains('Single color').click();
cy.get('.euiFieldText.euiColorPicker__input.euiFieldText--withIcon').click();
cy.get('[aria-label="Select #54B399 as the color"]').should('exist').click();
cy.get('.euiButton__text').contains('Preview').click();
cy.get('.euiSuperSelectControl').click();
cy.get('.euiContextMenuItem__text .euiColorPalettePicker__item').eq(2).contains('Multicolored').click();
cy.wait(delay);
cy.get('.euiFormHelpText.euiFormRow__text').eq(1).contains('Child field').should('exist');
cy.get('.euiFieldText.euiColorPicker__input.euiFieldText--withIcon').eq(0).click();
cy.get('[aria-label="Select #D36086 as the color"]').click();
cy.get('.euiFormHelpText.euiFormRow__text').contains('Parent field').should('not.exist');
cy.get('.euiButton__text').contains('Preview').click();
cy.get('.trace.treemap path[style*="rgb(211, 96, 134)"]').should('exist');
});
});
25 changes: 23 additions & 2 deletions dashboards-observability/.cypress/utils/event_constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ export const TEST_QUERIES = [
query: 'source = opensearch_dashboards_sample_data_logs'
},
{
query: 'source = opensearch_dashboards_sample_data_logs | stats count() by host',
query: 'source=opensearch_dashboards_sample_data_flights | stats max(AvgTicketPrice) by DestCountry, DestCityName, Carrier',
dateRangeDOM: YEAR_TO_DATE_DOM_ID
},
{
query: 'source = opensearch_dashboards_sample_data_logs | stats count(), avg(bytes) by host, tags',
dateRangeDOM: YEAR_TO_DATE_DOM_ID
},
{
query: 'source=opensearch_dashboards_sample_data_flights | stats avg(FlightDelayMin) by DestCountry, DestCityName',
dateRangeDOM: YEAR_TO_DATE_DOM_ID
},
];

export const TESTING_PANEL = 'Mock Testing Panels';
Expand Down Expand Up @@ -70,4 +74,21 @@ export const landOnPanels = () => {
`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels`
);
cy.wait(delay);
};
};

export const renderTreeMapchart = () => {
querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM);
cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}');
cy.get('#configPanel__panelOptions .euiFieldText').click().type('Tree Map');
cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').click().type('This is the description for Tree Map');
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(1).click();
cy.get('.euiComboBoxOption__content').eq(2).click();
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(2).click();
cy.get('.euiComboBoxOption__content').eq(1).click();
cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(3).click();
cy.get('.euiComboBoxOption__content').eq(0).click();
cy.get('.euiIEFlexWrapFix').eq(2).contains('Treemap').should('exist');
cy.get('#configPanel__treemap_options').contains('Tiling Algorithm').should('exist');
cy.get('[data-test-subj = "comboBoxInput"]').eq(4).click();
cy.get('button[name="Slice Dice"]').click();
};
168 changes: 168 additions & 0 deletions dashboards-observability/common/constants/colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { colorPalette } from '@elastic/eui';

export const BLUES_PALETTE = {
name: 'Blues',
label: 'Blues',
colors: [
'rgb(5,10,172)',
'rgb(40,60,190)',
'rgb(70,100,245)',
'rgb(90,120,245)',
'rgb(106,137,247)',
'rgb(220,220,220)',
],
};

export const REDS_PALETTE = {
name: 'Reds',
label: 'Reds',
colors: ['rgb(220,220,220)', 'rgb(245,195,157)', 'rgb(245,160,105)', 'rgb(178,10,28)'],
};

export const GREENS_PALETTE = {
name: 'Greens',
label: 'Greens',
colors: [
'rgb(0,68,27)',
'rgb(0,109,44)',
'rgb(35,139,69)',
'rgb(65,171,93)',
'rgb(116,196,118)',
'rgb(161,217,155)',
'rgb(199,233,192)',
'rgb(229,245,224)',
'rgb(247,252,245)',
],
};

export const GREYS_PALETTE = {
name: 'Greys',
label: 'Greys',
colors: ['rgb(0,0,0)', 'rgb(255,255,255)'],
};

export const BLUE_RED_PALETTE = {
name: 'Bluered',
label: 'Blue-Red',
colors: ['rgb(0,0,255)', 'rgb(255,0,0)'],
};

export const RED_BLUE_PALETTE = {
name: 'RdBu',
label: 'Red-Blue',
colors: [
'rgb(5,10,172)',
'rgb(106,137,247)',
'rgb(190,190,190)',
'rgb(220,170,132)',
'rgb(230,145,90)',
'rgb(178,10,28)',
],
};

export const YELLOW_ORANGE_RED_PALETTE = {
name: 'YlOrRd',
label: 'Yellow-Orange-Red',
colors: [
'rgb(128,0,38)',
'rgb(189,0,38)',
'rgb(227,26,28)',
'rgb(252,78,42)',
'rgb(253,141,60)',
'rgb(254,178,76)',
'rgb(254,217,118)',
'rgb(255,237,160)',
'rgb(255,255,204)',
],
};

export const YELLOW_GREEN_BLUE_PALETTE = {
name: 'YlGnBu',
label: 'Yellow-Green-Blue',
colors: [
'rgb(8,29,88)',
'rgb(37,52,148)',
'rgb(34,94,168)',
'rgb(29,145,192)',
'rgb(65,182,196)',
'rgb(127,205,187)',
'rgb(199,233,180)',
'rgb(237,248,217)',
'rgb(255,255,217)',
],
};

export const DEFAULT_PALETTE = 'default';
export const SINGLE_COLOR_PALETTE = 'singleColor';
export const MULTI_COLOR_PALETTE = 'multicolor';

export const COLOR_PALETTES = [
{
value: DEFAULT_PALETTE,
title: 'Default',
type: 'text',
},
{
value: SINGLE_COLOR_PALETTE,
title: 'Single color',
type: 'text',
},
{
value: MULTI_COLOR_PALETTE,
title: 'Multicolored',
type: 'text',
},
{
value: BLUES_PALETTE.name,
title: BLUES_PALETTE.label,
palette: colorPalette(BLUES_PALETTE.colors, 20),
type: 'gradient',
},
{
value: REDS_PALETTE.name,
title: REDS_PALETTE.label,
palette: colorPalette(REDS_PALETTE.colors, 20),
type: 'gradient',
},
{
value: GREENS_PALETTE.name,
title: GREENS_PALETTE.label,
palette: colorPalette(GREENS_PALETTE.colors, 20),
type: 'gradient',
},
{
value: GREYS_PALETTE.name,
title: GREYS_PALETTE.label,
palette: colorPalette(GREYS_PALETTE.colors, 20),
type: 'gradient',
},
{
value: BLUE_RED_PALETTE.name,
title: BLUE_RED_PALETTE.label,
palette: colorPalette(BLUE_RED_PALETTE.colors, 20),
type: 'gradient',
},
{
value: RED_BLUE_PALETTE.name,
title: RED_BLUE_PALETTE.label,
palette: colorPalette(RED_BLUE_PALETTE.colors, 20, true),
type: 'gradient',
},
{
value: YELLOW_ORANGE_RED_PALETTE.name,
title: YELLOW_ORANGE_RED_PALETTE.label,
palette: colorPalette(YELLOW_ORANGE_RED_PALETTE.colors, 20),
type: 'gradient',
},
{
value: YELLOW_GREEN_BLUE_PALETTE.name,
title: YELLOW_GREEN_BLUE_PALETTE.label,
palette: colorPalette(YELLOW_GREEN_BLUE_PALETTE.colors, 20),
type: 'gradient',
},
];
2 changes: 1 addition & 1 deletion dashboards-observability/common/constants/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export interface ValueOptionsAxes {

export const NUMERICAL_FIELDS = ['short', 'integer', 'long', 'float', 'double'];

export const ENABLED_VIS_TYPES = [visChartTypes.Bar, visChartTypes.HorizontalBar, visChartTypes.Line, visChartTypes.Pie, visChartTypes.HeatMap, visChartTypes.Text];
export const ENABLED_VIS_TYPES = [visChartTypes.Bar, visChartTypes.HorizontalBar, visChartTypes.Line, visChartTypes.Pie, visChartTypes.HeatMap, visChartTypes.Text, visChartTypes.TreeMap];

//Live tail constants
export const LIVE_OPTIONS = [
Expand Down
Loading

0 comments on commit ec75f52

Please sign in to comment.