From bf81e3518ab7e024176a6a571ecb0d927d89ca30 Mon Sep 17 00:00:00 2001 From: Kavitha Conjeevaram Mohan Date: Wed, 6 Jul 2022 16:19:55 -0700 Subject: [PATCH 1/9] 2.1 release notes (#839) Signed-off-by: Kavitha Conjeevaram Mohan --- ...ensearch-observability.release-notes-2.1.0.0.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 release-notes/opensearch-observability.release-notes-2.1.0.0.md diff --git a/release-notes/opensearch-observability.release-notes-2.1.0.0.md b/release-notes/opensearch-observability.release-notes-2.1.0.0.md new file mode 100644 index 000000000..ea38b04f3 --- /dev/null +++ b/release-notes/opensearch-observability.release-notes-2.1.0.0.md @@ -0,0 +1,14 @@ +## Version 2.1.0.0 Release Notes +Compatible with OpenSearch and OpenSearch Dashboards Version 2.1.0 + +### Enhancements +* Add availability help flyout ([#734](https://github.com/opensearch-project/observability/pull/734)) + +### Infrastructure +* bump version to 2.1.0 and gradle version to 7.4.2 ([#817](https://github.com/opensearch-project/observability/pull/817)) +* Uses custom plugin to publish zips to maven ([#786](https://github.com/opensearch-project/observability/pull/786)) + +### Refactoring +* Make common delete modal for components ([#766](https://github.com/opensearch-project/observability/pull/766)) +* Sync app and app list types ([#763](https://github.com/opensearch-project/observability/pull/763)) + From 4bebc60f49f6f4be41e726ace5dbe76cb7a077b1 Mon Sep 17 00:00:00 2001 From: Kavitha Conjeevaram Mohan Date: Wed, 6 Jul 2022 18:35:31 -0700 Subject: [PATCH 2/9] change 2.1 version bump PR under maintenance (#841) * change version bump to maintenance Signed-off-by: Kavitha Conjeevaram Mohan * change version bump to maintenance Signed-off-by: Kavitha Conjeevaram Mohan --- .../opensearch-observability.release-notes-2.1.0.0.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/release-notes/opensearch-observability.release-notes-2.1.0.0.md b/release-notes/opensearch-observability.release-notes-2.1.0.0.md index ea38b04f3..fc8bc299a 100644 --- a/release-notes/opensearch-observability.release-notes-2.1.0.0.md +++ b/release-notes/opensearch-observability.release-notes-2.1.0.0.md @@ -5,10 +5,11 @@ Compatible with OpenSearch and OpenSearch Dashboards Version 2.1.0 * Add availability help flyout ([#734](https://github.com/opensearch-project/observability/pull/734)) ### Infrastructure -* bump version to 2.1.0 and gradle version to 7.4.2 ([#817](https://github.com/opensearch-project/observability/pull/817)) * Uses custom plugin to publish zips to maven ([#786](https://github.com/opensearch-project/observability/pull/786)) ### Refactoring * Make common delete modal for components ([#766](https://github.com/opensearch-project/observability/pull/766)) * Sync app and app list types ([#763](https://github.com/opensearch-project/observability/pull/763)) +### Maintenance +* Bump version to 2.1.0 and gradle version to 7.4.2 ([#817](https://github.com/opensearch-project/observability/pull/817)) \ No newline at end of file From bf98d97b8d5150177462250a4a8b84023161e3a2 Mon Sep 17 00:00:00 2001 From: abasatwar Date: Fri, 8 Jul 2022 23:17:18 +0530 Subject: [PATCH 3/9] Sprint1 : combine PR for visualization from Sprint1 (#824) * graph style section UI schema Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts * changes for style mode and interpolation Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts * lineWidth integration for line mode Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * changes for Legend and Orientation in Line Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_legend.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * point size and Bar Alignment changes Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/common/types/explorer.ts * implemented fill opacity for line chart Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx * changes for line width and fill opacity in bar mode and removed mode from chartOption Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/common/constants/shared.ts * updated bar mode opacity in line chart Signed-off-by: rinku-kumar-psl * refactored the config chart style code Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/common/types/explorer.ts * snapshot updated and code refactored Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx * type added to new component Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group.tsx # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * review comments addressed Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx # Conflicts: # dashboards-observability/common/constants/shared.ts * cypress test case added and resolve button label wraping issue Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js # dashboards-observability/.cypress/utils/event_constants.js # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js * multi matrices changes for Line Signed-off-by: rinku-kumar-psl * dimensions and metrics UI changes for time-series Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/common/constants/explorer.ts # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx * made data config pannel collapsable and initial fields render Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx * code refactored Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx * snapshot updated and handled corner cases Signed-off-by: rinku-kumar-psl * code styling fixes and added TODO comment Signed-off-by: rinku-kumar-psl * table view: eui table replaced with ag-grid Signed-off-by: Ramneet Chopra * drag-drop issue fixed Signed-off-by: Ramneet Chopra * test case of data_table updated Signed-off-by: Ramneet Chopra * feedback comments resolved Signed-off-by: Ramneet Chopra * grid height issue:fixed Signed-off-by: Ramneet Chopra * column height, value getter for type double Signed-off-by: Ramneet Chopra * data_table elements moved to separate Signed-off-by: Ramneet Chopra * footer components Signed-off-by: Ramneet Chopra * cypress test cases for table view Signed-off-by: Ramneet Chopra * data config reviewed code added Signed-off-by: Deepak Nevde * Text correction Signed-off-by: Deepak Nevde * Conflicts resolved Signed-off-by: Deepak Nevde * enhancement for heatmap with new UI Signed-off-by: Shankha Das * line chart test cases Signed-off-by: Shankha Das * console logs removed Signed-off-by: Shankha Das * updated value options ui for treemap Signed-off-by: Mrunal Zambre * removed console Signed-off-by: Mrunal Zambre * sprint1-visualization-fixes. Signed-off-by: abasatwar * initialize default params for DimensonComponent and formatted the codes Signed-off-by: rinku-kumar-psl * code review changes done Signed-off-by: rinku-kumar-psl * added empty line at end. Signed-off-by: abasatwar Co-authored-by: rinku-kumar-psl Co-authored-by: Ramneet Chopra Co-authored-by: Deepak Nevde Co-authored-by: Shankha Das Co-authored-by: Mrunal Zambre --- .../integration/1_event_analytics.spec.js | 529 +++--- .../.cypress/utils/event_constants.js | 28 + .../common/constants/explorer.ts | 13 + .../common/types/explorer.ts | 14 + dashboards-observability/package.json | 3 + .../__snapshots__/utils.test.tsx.snap | 486 +++++- .../__snapshots__/config_panel.test.tsx.snap | 1490 +++++++++-------- .../config_controls/config_button_group.tsx | 35 +- .../config_line_chart_styles.tsx | 95 ++ .../config_treemap_parents.tsx | 50 +- .../data_config_panel_item.tsx | 123 +- .../config_panes/config_controls/index.ts | 1 + .../treemap_config_panel_item.tsx | 160 ++ .../explorer/visualizations/index.tsx | 35 +- .../workspace_panel/workspace_panel.tsx | 16 +- .../event_analytics/utils/utils.tsx | 4 +- .../__snapshots__/data_table.test.tsx.snap | 730 ++------ .../__snapshots__/line.test.tsx.snap | 76 +- .../charts/__tests__/data_table.test.tsx | 17 +- .../charts/data_table/data_table.scss | 63 + .../charts/data_table/data_table.tsx | 277 ++- .../charts/data_table/data_table_footer.tsx | 126 ++ .../charts/data_table/data_table_header.tsx | 195 +++ .../visualizations/charts/lines/line.tsx | 80 +- .../visualizations/charts/lines/line_type.ts | 109 +- .../visualizations/charts/maps/heatmap.tsx | 30 +- .../charts/maps/heatmap_type.ts | 14 - .../charts/maps/treemap_type.ts | 27 - .../visualizations/charts/maps/treemaps.tsx | 19 +- .../visualizations/charts/pie/pie.tsx | 8 +- dashboards-observability/yarn.lock | 30 +- 31 files changed, 2832 insertions(+), 2051 deletions(-) create mode 100644 dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_line_chart_styles.tsx create mode 100644 dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/treemap_config_panel_item.tsx create mode 100644 dashboards-observability/public/components/visualizations/charts/data_table/data_table.scss create mode 100644 dashboards-observability/public/components/visualizations/charts/data_table/data_table_footer.tsx create mode 100644 dashboards-observability/public/components/visualizations/charts/data_table/data_table_header.tsx diff --git a/dashboards-observability/.cypress/integration/1_event_analytics.spec.js b/dashboards-observability/.cypress/integration/1_event_analytics.spec.js index e237252c3..f2b0db3c6 100644 --- a/dashboards-observability/.cypress/integration/1_event_analytics.spec.js +++ b/dashboards-observability/.cypress/integration/1_event_analytics.spec.js @@ -19,33 +19,47 @@ import { landOnEventVisualizations, landOnPanels, renderTreeMapchart, - renderPieChart + renderPieChart, + renderLineChartForDataConfig, + DataConfigLineChart } 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('[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( + '.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('.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('.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`); @@ -80,11 +94,14 @@ describe('Search a query on event home', () => { cy.get('[data-test-subj="superDatePickerToggleQuickMenuButton"]').click(); cy.get('[data-test-subj="superDatePickerCommonlyUsed_Year_to date"]').click(); cy.get('[data-test-subj="superDatePickerApplyTimeButton"]').contains('Refresh').click(); - cy.window().its('store').invoke('getState').then((state) => { - expect(Object.values(state.queries)[0]['rawQuery'].trim()).equal(TEST_QUERIES[0].query) - expect(Object.values(state.queries)[0]['selectedDateRange'][0]).equal("now/y"); - expect(Object.values(state.queries)[0]['selectedDateRange'][1]).equal("now"); - }); + cy.window() + .its('store') + .invoke('getState') + .then((state) => { + expect(Object.values(state.queries)[0]['rawQuery'].trim()).equal(TEST_QUERIES[0].query); + expect(Object.values(state.queries)[0]['selectedDateRange'][0]).equal('now/y'); + expect(Object.values(state.queries)[0]['selectedDateRange'][1]).equal('now'); + }); cy.wait(delay); cy.url().should('contain', '#/event_analytics/explorer'); @@ -101,16 +118,26 @@ describe('Open flyout for a data row to see details', () => { it('Should be able to open flyout and see data, json and traces', () => { cy.get('[data-test-subj="docTable"] tbody tr button.euiButtonIcon').first().click(); cy.get('.observability-flyout').should('exist'); - cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content').contains('JSON').click(); - cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content').contains('Traces').click(); - cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content').contains('Table').click(); + cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content') + .contains('JSON') + .click(); + cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content') + .contains('Traces') + .click(); + cy.get('.observability-flyout .osdDocViewer .euiTabs span.euiTab__content') + .contains('Table') + .click(); }); it('Should be able to see srrounding docs', () => { cy.get('[data-test-subj="docTable"] tbody tr button.euiButtonIcon').first().click(); cy.get('.observability-flyout').should('exist'); - cy.get('.observability-flyout span.euiButton__text').contains('View surrounding events').click(); - cy.get('.observability-flyout #surroundingFyout').contains('View surrounding events').should('exist'); + cy.get('.observability-flyout span.euiButton__text') + .contains('View surrounding events') + .click(); + cy.get('.observability-flyout #surroundingFyout') + .contains('View surrounding events') + .should('exist'); }); }); @@ -277,7 +304,9 @@ describe('Saves a query on explorer page', () => { cy.get('button[id="main-content-vis"]').contains('Visualizations').click(); cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click(); cy.wait(delay * 2); - cy.get('[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]').click(); + cy.get( + '[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]' + ).click(); cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY2); cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click(); cy.wait(delay * 2); @@ -307,11 +336,15 @@ describe('Saves a query on explorer page', () => { cy.get('button[id="main-content-vis"]').contains('Visualizations').click(); cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click(); cy.wait(delay * 2); - cy.get('[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]').click(); + cy.get( + '[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]' + ).click(); cy.get('[data-test-subj="eventExplorer__querySaveName"]').type(SAVE_QUERY3); cy.get('[data-test-subj="eventExplorer__querySaveComboBox"]').type(TESTING_PANEL); cy.get(`input[value="${TESTING_PANEL}"]`).click(); - cy.get('[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]').click(); + cy.get( + '[data-test-subj="eventExplorer__querySaveComboBox"] [data-test-subj="comboBoxToggleListButton"]' + ).click(); cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click(); cy.wait(delay); @@ -330,8 +363,11 @@ describe('Override timestamp for an index', () => { cy.wait(delay); cy.get('[data-attr-field="utc_time"] [data-test-subj="eventFields__default-timestamp-mark"') - .contains('Default Timestamp').should('exist'); - cy.get('[data-attr-field="timestamp"] [data-test-subj="eventFields__default-timestamp-mark"').should('not.exist'); + .contains('Default Timestamp') + .should('exist'); + cy.get( + '[data-attr-field="timestamp"] [data-test-subj="eventFields__default-timestamp-mark"' + ).should('not.exist'); }); }); @@ -394,20 +430,40 @@ describe('Click to view field insights', () => { it('Click a numerical field to view field insights', () => { cy.get('[data-test-subj="field-bytes-showDetails"]').click(); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Top values').should('exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Rare values').should('exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Average overtime').should('exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Maximum overtime').should('exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Minimum overtime').should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Top values') + .should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Rare values') + .should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Average overtime') + .should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Maximum overtime') + .should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Minimum overtime') + .should('exist'); }); it('Click a non-numerical field to view insights', () => { cy.get('[data-test-subj="field-host-showDetails"]').click(); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Top values').should('exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Rare values').should('exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Average overtime').should('not.exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Maximum overtime').should('not.exist'); - cy.get('[data-test-subj="sidebarField__fieldInsights"] button').contains('Minimum overtime').should('not.exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Top values') + .should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Rare values') + .should('exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Average overtime') + .should('not.exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Maximum overtime') + .should('not.exist'); + cy.get('[data-test-subj="sidebarField__fieldInsights"] button') + .contains('Minimum overtime') + .should('not.exist'); }); }); @@ -494,7 +550,9 @@ describe('Renders noresult chart', () => { }); it('It should render no result when there is no data', () => { - cy.get('[data-test-subj="vizWorkspace__noData"] p').contains('No results found').should('exist'); + cy.get('[data-test-subj="vizWorkspace__noData"] p') + .contains('No results found') + .should('exist'); }); }); @@ -505,7 +563,9 @@ describe('Renders bar charts', () => { it('Renders vertical bar chart', () => { querySearch(TEST_QUERIES[3].query, TEST_QUERIES[3].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); + cy.get( + '[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]' + ).click(); cy.wait(delay * 2); cy.get('[data-test-subj="comboBoxOptionsList "] span').contains('Bar').click(); cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').first().click(); @@ -522,12 +582,16 @@ describe('Renders bar charts', () => { cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Group').click(); cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); cy.wait(delay * 2); - cy.get('g.xaxislayer-above > g.xtick text[data-unformatted|="artifacts.opensearch.org"]').should('exist'); + cy.get( + 'g.xaxislayer-above > g.xtick text[data-unformatted|="artifacts.opensearch.org"]' + ).should('exist'); }); it('Renders horiztontal bar chart', () => { querySearch(TEST_QUERIES[3].query, TEST_QUERIES[3].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); + cy.get( + '[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]' + ).click(); cy.wait(delay * 2); cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Bar').click(); cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').first().click(); @@ -544,7 +608,9 @@ describe('Renders bar charts', () => { cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Group').click(); cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); cy.wait(delay * 2); - cy.get('g.yaxislayer-above > g.ytick text[data-unformatted|="artifacts.opensearch.org"]').should('exist'); + cy.get( + 'g.yaxislayer-above > g.ytick text[data-unformatted|="artifacts.opensearch.org"]' + ).should('exist'); }); }); @@ -555,7 +621,9 @@ describe('Renders line charts', () => { it('Renders line chart with threshold', () => { querySearch(TEST_QUERIES[3].query, TEST_QUERIES[3].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); + cy.get( + '[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]' + ).click(); cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Line').click(); cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').first().click(); cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('host').click(); @@ -569,7 +637,9 @@ describe('Renders line charts', () => { cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); cy.wait(delay * 2); cy.get('g.text > g.textpoint text[data-unformatted|="Max"]').should('exist'); - cy.get('g.xaxislayer-above > g.xtick text[data-unformatted|="artifacts.opensearch.org"]').should('exist'); + cy.get( + 'g.xaxislayer-above > g.xtick text[data-unformatted|="artifacts.opensearch.org"]' + ).should('exist'); }); }); @@ -580,7 +650,9 @@ describe('Renders pie charts', () => { it('Renders pie chart', () => { querySearch(TEST_QUERIES[3].query, TEST_QUERIES[3].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); + cy.get( + '[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]' + ).click(); cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Pie').click(); cy.wait(delay); cy.get('g.pielayer').should('exist'); @@ -594,7 +666,9 @@ describe('Renders heatmap chart', () => { it('Renders heatmap chart with different z-axes', () => { querySearch(TEST_QUERIES[4].query, TEST_QUERIES[4].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); + cy.get( + '[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]' + ).click(); cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Heatmap').click(); cy.wait(delay * 2); cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').click(); @@ -618,13 +692,17 @@ describe('Renders markdown chart', () => { it('Renders markdown chart with test title', () => { querySearch(TEST_QUERIES[3].query, TEST_QUERIES[3].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); + cy.get( + '[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]' + ).click(); cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Text').click(); cy.get('[data-test-subj="workspace__viz_markdown"] h2').contains('Text').should('exist'); cy.get('textarea.euiMarkdownEditorTextArea').type('## testing title'); cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); cy.wait(delay * 2); - cy.get('[data-test-subj="workspace__viz_markdown"] h2').contains('testing title').should('exist'); + cy.get('[data-test-subj="workspace__viz_markdown"] h2') + .contains('testing title') + .should('exist'); }); }); @@ -652,15 +730,25 @@ describe('Renders chart and verify Toast message if X-axis and Y-axis values are .type('Bar') .type('{enter}'); cy.wait(delay); - cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]').eq(0).click({ force: true }); + cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]') + .eq(0) + .click({ force: true }); cy.get('#configPanel__value_options [data-test-subj="comboBoxToggleListButton"]').eq(0).click(); - cy.wait(delay) - cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]').click({ multiple: true }); + cy.wait(delay); + cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]').click({ + multiple: true, + }); cy.get('#configPanel__value_options [data-test-subj="comboBoxToggleListButton"]').eq(1).click(); - cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').eq(0).should('have.value', ''); - cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').eq(1).should('have.value', ''); + cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]') + .eq(0) + .should('have.value', ''); + cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]') + .eq(1) + .should('have.value', ''); cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - cy.get('[data-test-subj="euiToastHeader"]').contains('Invalid value options configuration selected.').should('exist'); + cy.get('[data-test-subj="euiToastHeader"]') + .contains('Invalid value options configuration selected.') + .should('exist'); }); it('Renders chart, clear X-axis and Y-axis value and try to save visulization, Toast message should display with error message', () => { @@ -669,304 +757,103 @@ describe('Renders chart and verify Toast message if X-axis and Y-axis values are .type('Bar') .type('{enter}'); cy.wait(delay); - cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]').eq(0).click({ force: true }); + cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]') + .eq(0) + .click({ force: true }); cy.get('#configPanel__value_options [data-test-subj="comboBoxToggleListButton"]').eq(0).click(); - cy.wait(delay) - cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]').click({ multiple: true }); - cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').eq(0).should('have.value', ''); - cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').eq(1).should('have.value', ''); + cy.wait(delay); + cy.get('#configPanel__value_options [data-test-subj="comboBoxClearButton"]').click({ + multiple: true, + }); + cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]') + .eq(0) + .should('have.value', ''); + cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]') + .eq(1) + .should('have.value', ''); 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 .euiFormControlLayoutIcons [data-test-subj="comboBoxToggleListButton"]' + ) + .eq(0) + .click(); cy.get('.euiPopover__panel input').eq(1).type(`Test visulization_`); cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]').click(); - cy.get('[data-test-subj="euiToastHeader"]').contains('Invalid value options configuration selected.').should('exist'); + cy.get('[data-test-subj="euiToastHeader"]') + .contains('Invalid value options configuration selected.') + .should('exist'); }); }); -describe('Renders Tree Map', () => { +describe('Render Table View', () => { beforeEach(() => { landOnEventVisualizations(); + querySearch(TEST_QUERIES[3].query, TEST_QUERIES[3].dateRangeDOM); + cy.get('[data-test-subj="workspace__dataTableViewSwitch"]').click(); }); - it('Renders Tree Map', () => { - renderTreeMapchart(); - cy.get('.euiFlexItem.euiFlexItem--flexGrowZero .euiButton__text').eq(2).click(); - cy.get('path.surface').should('have.length', 176); + it('Switch visualization for table view and verify table data', () => { + cy.get('.ag-header-cell-text').contains('max(AvgTicketPrice)').should('exist'); + cy.get('.ag-header-cell-text').contains('DestCountry').should('exist'); + cy.get('.ag-header-cell-text').contains('DestCityName').should('exist'); + cy.get('.ag-header-cell-text').contains('Carrier').should('exist'); }); - 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('Switch visualization for table view and change data table density', () => { + cy.get('.euiButtonEmpty__text').contains('Density').click(); + cy.get('.euiButtonIcon.euiButtonIcon--primary.euiButtonIcon--xSmall').eq(1).click(); + cy.get('.euiButtonIcon.euiButtonIcon--primary.euiButtonIcon--xSmall').eq(2).click(); }); - 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'); - }) -}); - -describe('Render Pie chart for Legend and single color contrast change', () => { - beforeEach(() => { - landOnEventVisualizations(); - }); - it('Render Pie chart and verify legends for Position Right and Bottom', () => { - renderPieChart(); - cy.get('[data-text="Right"]').should('have.text', 'Right'); - cy.get('[data-text="Right"] [data-test-subj="v"]').should('have.attr', 'checked'); - cy.get('[data-text="Bottom"]').should('have.text', 'Bottom').click(); - cy.get('[data-text="Bottom"] [data-test-subj="h"]').should('not.have.attr', 'checked'); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click({ force: true }); - }); - - it('Render Pie chart and verify legends for Show and Hidden', () => { - renderPieChart(); - cy.get('[data-text="Show"]').should('have.text', 'Show'); - cy.get('[data-text="Show"] [data-test-subj="show"]').should('have.attr', 'checked'); - cy.get('[data-text="Hidden"]').should('have.text', 'Hidden').click(); - cy.get('[data-text="Hidden"] [data-test-subj="hidden"]').should('not.have.attr', 'checked'); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click({ force: true }); + it('Switch visualization for table view and show and hide column', () => { + cy.get('.euiButtonEmpty__text').contains('Columns').click(); + cy.get('.euiSwitch__label').contains('DestCountry').click(); + cy.get('.ag-header-cell-text').contains('DestCountry').should('not.exist'); + cy.get('.euiSwitch__label').contains('Carrier').click(); + cy.get('.ag-header-cell-text').contains('Carrier').should('not.exist'); + cy.get('.euiSwitch__label').contains('DestCountry').click(); + cy.get('.ag-header-cell-text').contains('DestCountry').should('exist'); }); - it('Renders Pie chart with single color', () => { - renderPieChart(); - cy.get('.euiIEFlexWrapFix').eq(3).contains('Chart Styles').should('exist'); - cy.get('[data-test-subj="comboBoxInput"]').eq(3).click(); - cy.get('[name="Pie"]').click(); - cy.get('.euiSuperSelectControl').click(); - cy.get('.euiContextMenuItem.euiSuperSelect__item.euiSuperSelect__item--hasDividers').eq(1).click(); - cy.get('.euiFlexItem.euiFlexItem--flexGrowZero .euiButton__text').eq(2).click(); + it('Switch visualization for table view and see data in full screen', () => { + cy.get('.ag-header-cell-text').contains('max(AvgTicketPrice)').should('exist'); + cy.get('.ag-header-cell-text').contains('DestCountry').should('exist'); + cy.get('.ag-header-cell-text').contains('DestCityName').should('exist'); + cy.get('.ag-header-cell-text').contains('Carrier').should('exist'); + cy.get('.euiButtonEmpty__text').contains('Full screen').click(); + cy.wait(delay); + cy.get('body').type('{esc}'); cy.wait(delay); - }); -}); - -describe('Renders heatmap chart for Chart Style', () => { - beforeEach(() => { - landOnEventVisualizations(); - querySearch(TEST_QUERIES[4].query, TEST_QUERIES[4].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').click(); - cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('Heatmap').click(); - }); - - it('Renders heatmap chart with default Color Mode and Scheme', () => { - cy.get('.ewdrag.drag.cursor-ew-resize').should('be.visible'); - cy.get('g.g-gtitle text[data-unformatted|="avg(bytes)"]').should('exist'); - }); - - it('Renders heatmap chart with default Chart Style and Z-axis count()', () => { - cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').click(); - cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('count()').click(); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - cy.get('.ewdrag.drag.cursor-ew-resize').should('be.visible'); - cy.get('g.g-gtitle text[data-unformatted|="count()"]').should('exist'); - }); - - it('Renders heatmap chart with default Chart Style and Z-axis avg(bytes)', () => { - cy.get('#configPanel__value_options [data-test-subj="comboBoxInput"]').click(); - cy.get('[data-test-subj="comboBoxOptionsList "] button span').contains('avg(bytes)').click(); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - cy.get('.ewdrag.drag.cursor-ew-resize').should('be.visible'); - cy.get('g.g-gtitle text[data-unformatted|="avg(bytes)"]').should('exist'); - }); - - it('Renders heatmap chart and Verify if Color Mode is Spectrum then by default Scheme is Reds', () => { - cy.get('[data-test-subj="comboBoxInput"]').eq(2).should('contain', 'Spectrum'); - cy.get('[aria-haspopup="true"]').eq(1).should('contain', 'Reds'); - cy.get('stop[stop-color="rgb(178, 10, 28)"]').should('exist'); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - }); - - it('Renders heatmap chart and Verify if Color Mode is opacity then by default Scheme is Color', () => { - cy.get('[data-test-subj="comboBoxInput"]').eq(2).click(); - cy.get('.euiComboBoxOption__content').contains('opacity').click(); - cy.get('.euiTitle.euiTitle--xxsmall').eq(2).should('contain', 'Color'); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - cy.get('stop[stop-color="rgb(19, 19, 19)"]').should('exist'); }); - it('Renders heatmap chart for Color Mode Spectrum and Change color of Scheme', () => { - cy.get('[aria-haspopup="true"]').eq(1).click(); - cy.get('.euiColorPalettePicker__itemTitle').contains('Red-Blue').click(); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - cy.get('stop[stop-color="rgb(5, 10, 172)"]').should('exist'); - cy.get('stop[stop-color="rgb(178, 10, 28)"]').should('exist'); + it('Switch visualization for table view and sort the column data', () => { + cy.get('.ag-header-cell-text').contains('max(AvgTicketPrice)').click(); + cy.get('.ag-cell-value').contains('125.49737').should('exist'); + cy.get('.ag-header-cell-text').contains('max(AvgTicketPrice)').click(); + cy.get('.ag-cell-value').contains('1199.729').should('exist'); + cy.get('.ag-header-cell-text').contains('DestCountry').click(); + cy.get('.ag-cell-value').contains('AE').should('exist'); }); - it('Renders heatmap chart for Color Mode opacity and Change color', () => { - cy.get('[data-test-subj="comboBoxInput"]').eq(2).click(); - cy.get('.euiComboBoxOption__content').contains('opacity').click(); - cy.get('[data-test-subj="euiColorPickerAnchor"]').click(); - cy.get('.euiTitle.euiTitle--xxsmall').eq(2).should('contain', 'Color'); - cy.get('[aria-label="Select #D6BF57 as the color"]').click(); - cy.get('[data-test-subj="visualizeEditorRenderButton"]').click(); - cy.get('stop[stop-color="rgb(255, 255, 214)"]').should('exist'); - cy.get('stop[stop-color="rgb(214, 191, 87)"]').should('exist'); + it('Switch visualization for table view and verify pagination link', () => { + cy.get('[aria-label="Next page"]').click(); + cy.get('.ag-cell-value').contains('Vienna').should('exist'); + cy.get('[aria-label="Previous page"]').click(); + cy.get('.ag-cell-value').contains('Dubai').should('exist'); + cy.get('[aria-label="Page 4"]').contains('4').click(); + cy.get('.ag-cell-value').contains('Edmonton').should('exist'); }); -}); - -describe('Renders Tree Map for Parent Fields ', () => { - beforeEach(() => { - landOnEventVisualizations(); - }); - - it('Renders Tree Map and Add Multiple Parent', () => { - querySearch(TEST_QUERIES[7].query, TEST_QUERIES[7].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}'); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').contains('Select a field').should('exist'); - cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(3).click(); - cy.get('.euiComboBoxOption__content').eq(2).click(); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').contains('Select a field').should('exist'); - cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(4).click(); - cy.get('.euiComboBoxOption__content').eq(1).click(); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').contains('Select a field').should('exist'); - cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(5).click(); - cy.get('.euiComboBoxOption__content').eq(3).click(); - cy.get('.euiButton__text').contains('Preview').click(); - }); - - it('Renders Tree Map and Check Add/Delete Parent', () => { - querySearch(TEST_QUERIES[7].query, TEST_QUERIES[7].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}'); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').contains('Select a field').should('exist'); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').eq(1).contains('Select a field').should('exist'); - cy.get('.euiFormRow__fieldWrapper .euiFlexItem').eq(1).click(); - cy.get('.euiFormRow__fieldWrapper .euiFlexItem').eq(1).click(); + it('Switch visualization for table view and rows per page data', () => { + cy.get('.euiButtonEmpty__text').eq('6').click(); + cy.get('.euiContextMenuItem__text').eq(1).click(); }); }); -describe('Renders Tree Map for Parent Fields Multicolor Option', () => { - beforeEach(() => { - landOnEventVisualizations(); - }); - - it('Renders Tree Map For Multiple Parent and Check Color Theme', () => { - querySearch(TEST_QUERIES[7].query, TEST_QUERIES[7].dateRangeDOM); - cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Tree Map').type('{enter}'); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').contains('Select a field').should('exist'); - cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(3).click(); - cy.get('.euiComboBoxOption__content').eq(2).click(); - cy.get('.euiButton__text').contains('+ Add Parent').click(); - cy.get('.euiComboBoxPlaceholder').contains('Select a field').should('exist'); - cy.get('.euiFormControlLayoutIcons [data-test-subj ="comboBoxToggleListButton"]').eq(4).click(); - cy.get('.euiComboBoxOption__content').eq(1).click(); - cy.get('.euiSuperSelectControl').contains('Default').click(); - cy.get('.euiColorPalettePicker__item').contains('Multicolored').click(); - cy.get('.euiButton__text').contains('Preview').click(); - cy.get('.euiFormHelpText.euiFormRow__text').contains('Parent 1 field').should('exist'); - cy.get('.euiFormHelpText.euiFormRow__text').contains('Parent 2 field').should('exist'); +describe('Render Time series chart/Line chart and verify Data configurations UI ', () => { + it('Render line chart and verify Data Configuration Panel', () => { + renderLineChartForDataConfig(); + DataConfigLineChart(); }); }); diff --git a/dashboards-observability/.cypress/utils/event_constants.js b/dashboards-observability/.cypress/utils/event_constants.js index 0dd369922..4db8c146d 100644 --- a/dashboards-observability/.cypress/utils/event_constants.js +++ b/dashboards-observability/.cypress/utils/event_constants.js @@ -110,3 +110,31 @@ export const renderPieChart = () => { cy.get('[data-test-subj="comboBoxToggleListButton"]').eq(0).click(); cy.get('[data-test-subj="comboBoxInput"]').eq(2).click(); }; + +export const renderDataConfig = () => { + cy.get('.euiResizablePanel.euiResizablePanel--middle').contains('Data Cofigurations'); + cy.get('.euiTitle.euiTitle--xxsmall').eq(1).contains('Dimensions').should('exist'); + cy.get('.first-division .euiFormLabel.euiFormRow__label').eq(0).contains('Aggregation'); + cy.get('[data-test-subj="comboBoxSearchInput"]').eq(0).click(); + cy.get('.euiComboBoxOption__content').eq(2).click(); + cy.get('.first-division .euiFormLabel.euiFormRow__label').eq(1).contains('Field'); + cy.get('[data-test-subj="comboBoxSearchInput"]').eq(1).click(); + cy.get('.euiComboBoxOption__content').eq(1).click(); + cy.get('.euiFieldText[placeholder="Custom label"]').eq(0).type('Average field'); + cy.get('.euiTitle.euiTitle--xxsmall').eq(2).contains('Metrics').should('exist'); + cy.get('.first-division .euiFormLabel.euiFormRow__label').eq(0).contains('Aggregation'); + cy.get('.euiFormRow__fieldWrapper .euiComboBox').eq(2).click(); + cy.get('.euiComboBoxOption__content').eq(4).click(); + cy.get('.first-division .euiFormLabel.euiFormRow__label').eq(4).click(); + cy.get('.euiComboBoxOption__content').eq(0).click(); + cy.get('.euiFieldText[placeholder="Custom label"]').eq(1).type('Min field'); + cy.get('.euiButton__text').contains('Right').click(); + cy.get('[data-test-subj="visualizeEditorRenderButton"]').contains('Update chart').click(); + cy.get('.js-plotly-plot').should('exist'); +}; + +export const renderLineChart = () => { + landOnEventVisualizations(); + querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM); + cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Line').type('{enter}'); +}; diff --git a/dashboards-observability/common/constants/explorer.ts b/dashboards-observability/common/constants/explorer.ts index 056007d9c..17612c44e 100644 --- a/dashboards-observability/common/constants/explorer.ts +++ b/dashboards-observability/common/constants/explorer.ts @@ -117,3 +117,16 @@ export const AGGREGATION_OPTIONS = [ label: 'STDDEV_POP', }, ]; + +// Data table constants +export const GRID_HEADER_COLUMN_MAX_WIDTH = '150px'; +export const GRID_PAGE_RANGE_DISPLAY = 5; +export const COLUMN_DEFAULT_MIN_WIDTH = 100; +export const GRID_PAGE_SIZES = [10, 50, 100]; +export const ROW_DENSITIES = [ + { icon: 'tableDensityExpanded', height: 55, selected: false }, + { icon: 'tableDensityNormal', height: 45, selected: false }, + { icon: 'tableDensityCompact', height: 35, selected: true }, +]; + +export const HEADER_HEIGHT = 35; diff --git a/dashboards-observability/common/types/explorer.ts b/dashboards-observability/common/types/explorer.ts index 3220add36..2204a6ab4 100644 --- a/dashboards-observability/common/types/explorer.ts +++ b/dashboards-observability/common/types/explorer.ts @@ -230,3 +230,17 @@ export interface LiveTailProps { isLiveTailPopoverOpen: boolean; dataTestSubj: string; } + +export interface ConfigListEntry { + label: string; + aggregation: string; + custom_label: string; + name: string; + side: string; + type: string; +} + +export interface ConfigList { + dimensions?: ConfigListEntry[]; + metrics?: ConfigListEntry[]; +} diff --git a/dashboards-observability/package.json b/dashboards-observability/package.json index 1bfdf7b80..d068e60c4 100644 --- a/dashboards-observability/package.json +++ b/dashboards-observability/package.json @@ -17,8 +17,11 @@ "@nteract/outputs": "^3.0.11", "@nteract/presentational-components": "^3.4.3", "@reduxjs/toolkit": "^1.6.1", + "ag-grid-community": "^27.3.0", + "ag-grid-react": "^27.3.0", "plotly.js-dist": "^2.2.0", "react-graph-vis": "^1.0.5", + "react-paginate": "^8.1.3", "react-plotly.js": "^2.5.1" }, "devDependencies": { diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap index 126ff2374..3feb1f635 100644 --- a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap +++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap @@ -1377,58 +1377,158 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "sections": Array [ Object { "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", + "id": "legend", + "mapTo": "legend", + "name": "Legend", "schemas": Array [ Object { "component": null, - "isSingleSelection": true, - "mapTo": "xaxis", - "name": "X-axis", + "mapTo": "showLegend", + "name": "Show Legend", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, }, Object { "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", + "mapTo": "position", + "name": "Position", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "v", + "name": "Right", + }, + ], + "options": Array [ + Object { + "id": "v", + "name": "Right", + }, + Object { + "id": "h", + "name": "Bottom", + }, + ], + }, }, ], }, Object { "editor": [Function], - "id": "chart_options", - "mapTo": "chartOptions", - "name": "Chart options", + "id": "chart_styles", + "mapTo": "chartStyles", + "name": "Chart styles", "schemas": Array [ Object { - "component": null, - "isSingleSelection": true, - "mapTo": "mode", + "component": [Function], + "eleType": "buttons", + "mapTo": "style", "name": "Mode", "props": Object { "defaultSelections": Array [ Object { - "modeId": "lines", + "id": "lines", "name": "Lines", }, ], - "dropdownList": Array [ + "options": Array [ Object { - "modeId": "markers", - "name": "Markers", + "id": "lines", + "name": "Lines", }, Object { - "modeId": "lines", - "name": "Lines", + "id": "bar", + "name": "Bars", + }, + Object { + "id": "markers", + "name": "Points", + }, + Object { + "id": "lines+markers", + "name": "Lines + Points", + }, + ], + }, + }, + Object { + "component": [Function], + "eleType": "buttons", + "mapTo": "interpolation", + "name": "Interpolation", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "spline", + "name": "Smooth", + }, + ], + "options": Array [ + Object { + "id": "linear", + "name": "Linear", + }, + Object { + "id": "spline", + "name": "Smooth", + }, + Object { + "id": "hv", + "name": "Step before", }, Object { - "modeId": "lines+markers", - "name": "Lines + Markers", + "id": "vh", + "name": "Step after", }, ], }, }, + Object { + "component": [Function], + "defaultState": 2, + "eleType": "slider", + "mapTo": "lineWidth", + "name": "Line width", + "props": Object { + "max": 10, + }, + }, + Object { + "component": [Function], + "defaultState": 40, + "eleType": "slider", + "mapTo": "fillOpacity", + "name": "Fill Opacity", + "props": Object { + "max": 100, + }, + }, + Object { + "component": [Function], + "defaultState": 5, + "eleType": "slider", + "mapTo": "pointSize", + "name": "Point Size", + "props": Object { + "max": 40, + }, + }, ], }, Object { @@ -1610,58 +1710,158 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "sections": Array [ Object { "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", + "id": "legend", + "mapTo": "legend", + "name": "Legend", "schemas": Array [ Object { "component": null, - "isSingleSelection": true, - "mapTo": "xaxis", - "name": "X-axis", + "mapTo": "showLegend", + "name": "Show Legend", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, }, Object { "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", + "mapTo": "position", + "name": "Position", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "v", + "name": "Right", + }, + ], + "options": Array [ + Object { + "id": "v", + "name": "Right", + }, + Object { + "id": "h", + "name": "Bottom", + }, + ], + }, }, ], }, Object { "editor": [Function], - "id": "chart_options", - "mapTo": "chartOptions", - "name": "Chart options", + "id": "chart_styles", + "mapTo": "chartStyles", + "name": "Chart styles", "schemas": Array [ Object { - "component": null, - "isSingleSelection": true, - "mapTo": "mode", + "component": [Function], + "eleType": "buttons", + "mapTo": "style", "name": "Mode", "props": Object { "defaultSelections": Array [ Object { - "modeId": "lines", + "id": "lines", "name": "Lines", }, ], - "dropdownList": Array [ + "options": Array [ Object { - "modeId": "markers", - "name": "Markers", + "id": "lines", + "name": "Lines", }, Object { - "modeId": "lines", - "name": "Lines", + "id": "bar", + "name": "Bars", + }, + Object { + "id": "markers", + "name": "Points", }, Object { - "modeId": "lines+markers", - "name": "Lines + Markers", + "id": "lines+markers", + "name": "Lines + Points", }, ], }, }, + Object { + "component": [Function], + "eleType": "buttons", + "mapTo": "interpolation", + "name": "Interpolation", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "spline", + "name": "Smooth", + }, + ], + "options": Array [ + Object { + "id": "linear", + "name": "Linear", + }, + Object { + "id": "spline", + "name": "Smooth", + }, + Object { + "id": "hv", + "name": "Step before", + }, + Object { + "id": "vh", + "name": "Step after", + }, + ], + }, + }, + Object { + "component": [Function], + "defaultState": 2, + "eleType": "slider", + "mapTo": "lineWidth", + "name": "Line width", + "props": Object { + "max": 10, + }, + }, + Object { + "component": [Function], + "defaultState": 40, + "eleType": "slider", + "mapTo": "fillOpacity", + "name": "Fill Opacity", + "props": Object { + "max": 100, + }, + }, + Object { + "component": [Function], + "defaultState": 5, + "eleType": "slider", + "mapTo": "pointSize", + "name": "Point Size", + "props": Object { + "max": 40, + }, + }, ], }, Object { @@ -1897,58 +2097,158 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "sections": Array [ Object { "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", + "id": "legend", + "mapTo": "legend", + "name": "Legend", "schemas": Array [ Object { "component": null, - "isSingleSelection": true, - "mapTo": "xaxis", - "name": "X-axis", + "mapTo": "showLegend", + "name": "Show Legend", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, }, Object { "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", + "mapTo": "position", + "name": "Position", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "v", + "name": "Right", + }, + ], + "options": Array [ + Object { + "id": "v", + "name": "Right", + }, + Object { + "id": "h", + "name": "Bottom", + }, + ], + }, }, ], }, Object { "editor": [Function], - "id": "chart_options", - "mapTo": "chartOptions", - "name": "Chart options", + "id": "chart_styles", + "mapTo": "chartStyles", + "name": "Chart styles", "schemas": Array [ Object { - "component": null, - "isSingleSelection": true, - "mapTo": "mode", + "component": [Function], + "eleType": "buttons", + "mapTo": "style", "name": "Mode", "props": Object { "defaultSelections": Array [ Object { - "modeId": "lines", + "id": "lines", "name": "Lines", }, ], - "dropdownList": Array [ + "options": Array [ + Object { + "id": "lines", + "name": "Lines", + }, Object { - "modeId": "markers", - "name": "Markers", + "id": "bar", + "name": "Bars", }, Object { - "modeId": "lines", - "name": "Lines", + "id": "markers", + "name": "Points", + }, + Object { + "id": "lines+markers", + "name": "Lines + Points", + }, + ], + }, + }, + Object { + "component": [Function], + "eleType": "buttons", + "mapTo": "interpolation", + "name": "Interpolation", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "spline", + "name": "Smooth", + }, + ], + "options": Array [ + Object { + "id": "linear", + "name": "Linear", }, Object { - "modeId": "lines+markers", - "name": "Lines + Markers", + "id": "spline", + "name": "Smooth", + }, + Object { + "id": "hv", + "name": "Step before", + }, + Object { + "id": "vh", + "name": "Step after", }, ], }, }, + Object { + "component": [Function], + "defaultState": 2, + "eleType": "slider", + "mapTo": "lineWidth", + "name": "Line width", + "props": Object { + "max": 10, + }, + }, + Object { + "component": [Function], + "defaultState": 40, + "eleType": "slider", + "mapTo": "fillOpacity", + "name": "Fill Opacity", + "props": Object { + "max": 100, + }, + }, + Object { + "component": [Function], + "defaultState": 5, + "eleType": "slider", + "mapTo": "pointSize", + "name": "Point Size", + "props": Object { + "max": 40, + }, + }, ], }, Object { @@ -2060,9 +2360,19 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` data={ Array [ Object { - "mode": "line", + "fill": "tozeroy", + "fillcolor": "rgba(60,161,199,0.2)", + "line": Object { + "color": "#3CA1C7", + "shape": "spline", + "width": 2, + }, + "marker": Object { + "size": 5, + }, + "mode": "lines", "name": "avg(FlightDelayMin)", - "type": "line", + "type": "scatter", "x": Array [ "BeatsWest", "Logstash Airways", @@ -2118,6 +2428,16 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "showgrid": false, "visible": true, }, + "yaxis1": Object { + "overlaying": "y", + "side": "left", + "tickfont": Object { + "color": "#3CA1C7", + }, + "titlefont": Object { + "color": "#3CA1C7", + }, + }, } } > @@ -2139,9 +2459,19 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` data={ Array [ Object { - "mode": "line", + "fill": "tozeroy", + "fillcolor": "rgba(60,161,199,0.2)", + "line": Object { + "color": "#3CA1C7", + "shape": "spline", + "width": 2, + }, + "marker": Object { + "size": 5, + }, + "mode": "lines", "name": "avg(FlightDelayMin)", - "type": "line", + "type": "scatter", "x": Array [ "BeatsWest", "Logstash Airways", @@ -2202,6 +2532,16 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "showgrid": false, "visible": true, }, + "yaxis1": Object { + "overlaying": "y", + "side": "left", + "tickfont": Object { + "color": "#3CA1C7", + }, + "titlefont": Object { + "color": "#3CA1C7", + }, + }, } } style={ diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap index f09eccbdf..435c32d43 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap @@ -820,58 +820,158 @@ exports[`Config panel component Renders config panel with visualization data 1`] "sections": Array [ Object { "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", + "id": "legend", + "mapTo": "legend", + "name": "Legend", "schemas": Array [ Object { "component": null, - "isSingleSelection": true, - "mapTo": "xaxis", - "name": "X-axis", + "mapTo": "showLegend", + "name": "Show Legend", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, }, Object { "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", + "mapTo": "position", + "name": "Position", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "v", + "name": "Right", + }, + ], + "options": Array [ + Object { + "id": "v", + "name": "Right", + }, + Object { + "id": "h", + "name": "Bottom", + }, + ], + }, }, ], }, Object { "editor": [Function], - "id": "chart_options", - "mapTo": "chartOptions", - "name": "Chart options", + "id": "chart_styles", + "mapTo": "chartStyles", + "name": "Chart styles", "schemas": Array [ Object { - "component": null, - "isSingleSelection": true, - "mapTo": "mode", + "component": [Function], + "eleType": "buttons", + "mapTo": "style", "name": "Mode", "props": Object { "defaultSelections": Array [ Object { - "modeId": "lines", + "id": "lines", "name": "Lines", }, ], - "dropdownList": Array [ + "options": Array [ Object { - "modeId": "markers", - "name": "Markers", + "id": "lines", + "name": "Lines", }, Object { - "modeId": "lines", - "name": "Lines", + "id": "bar", + "name": "Bars", + }, + Object { + "id": "markers", + "name": "Points", + }, + Object { + "id": "lines+markers", + "name": "Lines + Points", + }, + ], + }, + }, + Object { + "component": [Function], + "eleType": "buttons", + "mapTo": "interpolation", + "name": "Interpolation", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "spline", + "name": "Smooth", + }, + ], + "options": Array [ + Object { + "id": "linear", + "name": "Linear", + }, + Object { + "id": "spline", + "name": "Smooth", + }, + Object { + "id": "hv", + "name": "Step before", }, Object { - "modeId": "lines+markers", - "name": "Lines + Markers", + "id": "vh", + "name": "Step after", }, ], }, }, + Object { + "component": [Function], + "defaultState": 2, + "eleType": "slider", + "mapTo": "lineWidth", + "name": "Line width", + "props": Object { + "max": 10, + }, + }, + Object { + "component": [Function], + "defaultState": 40, + "eleType": "slider", + "mapTo": "fillOpacity", + "name": "Fill Opacity", + "props": Object { + "max": 100, + }, + }, + Object { + "component": [Function], + "defaultState": 5, + "eleType": "slider", + "mapTo": "pointSize", + "name": "Point Size", + "props": Object { + "max": 40, + }, + }, ], }, Object { @@ -1177,20 +1277,6 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": true, - "mapTo": "zaxis", - "name": "Z-axis", - }, - ], - }, Object { "editor": [Function], "id": "chart_styles", @@ -1606,32 +1692,6 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": true, - "mapTo": "valueField", - "name": "Value Field", - }, - Object { - "component": null, - "isSingleSelection": true, - "mapTo": "childField", - "name": "Child Field", - }, - Object { - "component": [Function], - "defaultState": Array [], - "mapTo": "parentFields", - "name": "Parent Fields", - }, - ], - }, Object { "editor": [Function], "id": "treemap_options", @@ -9274,207 +9334,215 @@ exports[`Config panel component Renders config panel with visualization data 1`] className="euiSpacer euiSpacer--s" /> - -
- - - Show Legend - - -
- + + Show Legend + + +
- - - - - - + + + + - - - -
-
-
+ + + + + + + + - -
- - - Position - - -
- + + Position + + +
- - - - - - + + + + - - - -
-
-
+ + + + + + + + - -
- - - Orientation - - -
- + + Orientation + + +
- - - - - - + + + + - - - -
-
-
+ + + + + + + + - -
- - - Mode - - -
- + + Mode + + +
- - - - - - + + + + - - - -
-
-
+ + + + + + + + = ({ title, legend, groupOptions, idSelected, handleButtonChange }) => ( - <> - -

{title}

-
- - - - + <> + +

{title}

+
+ +
+ +
+ ); diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_line_chart_styles.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_line_chart_styles.tsx new file mode 100644 index 000000000..23fde5433 --- /dev/null +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_line_chart_styles.tsx @@ -0,0 +1,95 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useMemo, useCallback } from 'react'; +import { EuiAccordion, EuiSpacer } from '@elastic/eui'; +import { ButtonGroupItem } from './config_button_group'; +import { IConfigPanelOptionSection } from '../../../../../../../../common/types/explorer'; + +export const ConfigLineChartStyles = ({ + visualizations, + schemas, + vizState, + handleConfigChange, + sectionName, + sectionId = 'chartStyles' +}: any) => { + const { data } = visualizations; + const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData; + + const handleConfigurationChange = useCallback( + (stateFiledName) => { + return (changes) => { + handleConfigChange({ + ...vizState, + [stateFiledName]: changes, + }); + }; + }, + [handleConfigChange, vizState] + ); + + /* To update the schema options based on current style mode selection */ + const currentSchemas = useMemo(() => { + if (!vizState?.style || vizState?.style === "lines") { + return schemas.filter((schema: IConfigPanelOptionSection) => schema.mapTo !== 'pointSize'); + } + if (vizState?.style === "bar") { + return schemas.filter((schema: IConfigPanelOptionSection) => !["interpolation", "pointSize"].includes(schema.mapTo)); + } + if (vizState?.style === "markers") { + return schemas.filter((schema: IConfigPanelOptionSection) => ["style", "pointSize"].includes(schema.mapTo)); + } + if (vizState?.style === 'lines+markers') { + return schemas.filter((schema: IConfigPanelOptionSection) => schema.mapTo !== 'interpolation'); + } + }, [vizState]); + + const dimensions = useMemo(() => + currentSchemas && currentSchemas.map((schema: IConfigPanelOptionSection, index: string) => { + const DimensionComponent = schema.component || ButtonGroupItem; + let params = { + title: schema.name, + vizState, + ...schema.props + }; + + if (schema.eleType === 'buttons') { + params = { + ...params, + legend: schema.name, + groupOptions: schema?.props?.options.map((btn: { name: string }) => ({ ...btn, label: btn.name })), + idSelected: vizState[schema.mapTo] || schema?.props?.defaultSelections[0]?.id, + handleButtonChange: handleConfigurationChange(schema.mapTo), + }; + } else if (schema.eleType === 'slider') { + params = { + ...params, + maxRange: schema?.props?.max, + currentRange: vizState[schema.mapTo] || schema?.defaultState, + handleSliderChange: handleConfigurationChange(schema.mapTo), + }; + } + + return ( + <> + + + + ) + }) + , [currentSchemas, vizState, handleConfigurationChange]); + + return ( + + {dimensions} + + ); +}; diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_treemap_parents.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_treemap_parents.tsx index b5bcaf16f..f92f9db1b 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_treemap_parents.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_treemap_parents.tsx @@ -9,11 +9,9 @@ import { EuiFormRow, EuiSpacer, EuiIcon, - EuiFlexGroup, - EuiFlexItem, - EuiTitle, EuiComboBox, EuiComboBoxOptionOption, + EuiText, } from '@elastic/eui'; import { isEmpty, uniqueId } from 'lodash'; @@ -61,37 +59,33 @@ export const ConfigTreemapParentFields = ({ dropdownList, selectedAxis, onSelect return ( <> - -

{`Parent Fields`}

-
- {!isEmpty(selectedAxis) && selectedAxis.map((_, index: number) => { return ( <> - -

{`Parent ${index + 1}`}

-
- - - - handleParentChange(options, index)} - aria-label="Use aria labels when no actual label is in use" + + handleParentDelete(index)} /> - - - handleParentDelete(index)} /> - - + + } + > + handleParentChange(options, index)} + aria-label="Use aria labels when no actual label is in use" + /> ); diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx index f5df572fe..865164c5e 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useContext } from 'react'; import { EuiTitle, EuiComboBox, @@ -24,39 +24,68 @@ import { import { AGGREGATION_OPTIONS } from '../../../../../../../../common/constants/explorer'; import { ButtonGroupItem } from './config_button_group'; import { visChartTypes } from '../../../../../../../../common/constants/shared'; +import { ConfigList } from '../../../../../../../../common/types/explorer'; +import { TabContext } from '../../../../../hooks'; -export const DataConfigPanelItem = ({ fieldOptionList, visualizations, tabID }: any) => { +export const DataConfigPanelItem = ({ fieldOptionList, visualizations }: any) => { const dispatch = useDispatch(); - const explorerVisualizations = useSelector(selectExplorerVisualization)[tabID]; - + const { tabId } = useContext(TabContext); + const explorerVisualizations = useSelector(selectExplorerVisualization)[tabId]; const { data } = visualizations; + const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData; - const newEntry = { label: '', aggregation: '', custom_label: '', name: '', side: 'right' }; + const initialConfigEntry = { + label: '', + aggregation: '', + custom_label: '', + name: '', + side: 'right', + type: '', + }; - const [configList, setConfigList] = useState({ - dimensions: [{ ...newEntry }], - metrics: [{ ...newEntry }], - }); + const [configList, setConfigList] = useState({}); useEffect(() => { - if (data.rawVizData?.dataConfig) { + if ( + data.rawVizData?.[visualizations.vis.name] && + data.rawVizData?.[visualizations.vis.name].dataConfig + ) { setConfigList({ - ...data.rawVizData?.dataConfig, + ...data.rawVizData[visualizations.vis.name].dataConfig, }); - } else if (data.defaultAxes.xaxis || data.defaultAxes.yaxis) { + } else if ( + visualizations.vis.name !== visChartTypes.HeatMap && + (data.defaultAxes.xaxis || data.defaultAxes.yaxis) + ) { const { xaxis, yaxis } = data.defaultAxes; setConfigList({ dimensions: [...(xaxis && xaxis)], metrics: [...(yaxis && yaxis)], }); + } else { + setConfigList({ + dimensions: [initialConfigEntry, initialConfigEntry], + metrics: [initialConfigEntry], + }); } - }, [data.defaultAxes, data.rawVizData?.dataConfig]); + }, [ + data.defaultAxes, + data.rawVizData?.[visualizations.vis.name]?.dataConfig, + visualizations.vis.name, + ]); const updateList = (value: string, index: number, name: string, field: string) => { let list = { ...configList }; let listItem = { ...list[name][index] }; - listItem = { ...listItem, [field]: value }; + listItem = { + ...listItem, + [field]: value, + }; + if (field === 'label') { + listItem.type = value !== '' ? fields.find((x) => x.name === value)?.type : ''; + listItem.name = value; + } const newList = { ...list, [name]: [ @@ -68,59 +97,57 @@ export const DataConfigPanelItem = ({ fieldOptionList, visualizations, tabID }: setConfigList(newList); }; - const onFieldOptionChange = (e, index: number, name: string) => { - updateList(e[0]?.label, index, name, 'label'); - }; - - const onAggregationChange = (e, index: number, name: string) => { - updateList(e[0]?.label, index, name, 'aggregation'); - }; - - const onCustomLabelChange = (e, index: number, name: string) => { - updateList(e.target.value, index, name, 'custom_label'); - }; - - const handleSideChange = (id, value, index: number, name: string) => { - updateList(id, index, name, 'side'); - }; - const handleServiceRemove = (index: number, name: string) => { const list = { ...configList }; const arr = [...list[name]]; arr.splice(index, 1); - const newList = { ...list, [name]: arr }; - setConfigList(newList); + const y = { ...list, [name]: arr }; + setConfigList(y); }; const handleServiceAdd = (name: string) => { - let newList = { ...configList, [name]: [...configList[name], newEntry] }; + let newList = { ...configList, [name]: [...configList[name], initialConfigEntry] }; setConfigList(newList); }; const updateChart = () => { dispatch( renderExplorerVis({ - tabId: tabID, + tabId, data: { ...explorerVisualizations, - dataConfig: { - metrics: configList.metrics, - dimensions: configList.dimensions, + [visualizations.vis.name]: { + dataConfig: { + metrics: configList.metrics, + dimensions: configList.dimensions, + }, }, }, }) ); }; + const isPositionButtonVisible = (sectionName: string) => + sectionName === 'metrics' && + (visualizations.vis.name === visChartTypes.Line || + visualizations.vis.name === visChartTypes.Bar); + const getCommonUI = (lists, sectionName: string) => + lists && lists.map((singleField, index: number) => ( <>
+ {sectionName === 'dimensions' && visualizations.vis.name === visChartTypes.HeatMap && ( + +
{index === 0 ? 'X-Axis' : 'Y-Axis'}
+
+ )} onAggregationChange(e, index, sectionName)} + onChange={(e) => + updateList(e.length > 0 ? e[0].label : '', index, sectionName, 'aggregation') + } /> @@ -150,7 +179,9 @@ export const DataConfigPanelItem = ({ fieldOptionList, visualizations, tabID }: singleSelection={{ asPlainText: true }} options={fieldOptionList} selectedOptions={singleField.label ? [{ label: singleField.label }] : []} - onChange={(e) => onFieldOptionChange(e, index, sectionName)} + onChange={(e) => + updateList(e.length > 0 ? e[0].label : '', index, sectionName, 'label') + } /> @@ -158,12 +189,12 @@ export const DataConfigPanelItem = ({ fieldOptionList, visualizations, tabID }: onCustomLabelChange(e, index, sectionName)} + onChange={(e) => updateList(e.target.value, index, sectionName, 'custom_label')} aria-label="Use aria labels when no actual label is in use" /> - {sectionName === 'metrics' && visualizations.vis.name === visChartTypes.Line && ( + {isPositionButtonVisible(sectionName) && ( - handleSideChange(id, value, index, sectionName) - } + idSelected={singleField.side || 'right'} + handleButtonChange={(id: string) => updateList(id, index, sectionName, 'side')} /> )} - {lists.length - 1 === index && ( - + {visualizations.vis.name !== visChartTypes.HeatMap && lists.length - 1 === index && ( + { + const dispatch = useDispatch(); + const explorerVisualizations = useSelector(selectExplorerVisualization)[tabID]; + + const { data } = visualizations; + const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData; + + const newEntry = { label: '', name: '' }; + + const [configList, setConfigList] = useState({ + dimensions: [{ childField: { ...newEntry }, parentFields: [] }], + metrics: [{ valueField: { ...newEntry } }], + }); + + useEffect(() => { + if ( + data.rawVizData?.[visualizations.vis.name] && + data.rawVizData?.[visualizations.vis.name].dataConfig + ) { + setConfigList({ + ...data.rawVizData[visualizations.vis.name].dataConfig, + }); + } else if (data.defaultAxes.xaxis || data.defaultAxes.yaxis) { + const { xaxis, yaxis } = data.defaultAxes; + setConfigList({ + dimensions: [{ childField: { ...xaxis[0] }, parentFields: [] }], + metrics: [{ valueField: { ...yaxis[0] } }], + }); + } + }, [ + data.defaultAxes, + data.rawVizData?.[visualizations.vis.name]?.dataConfig, + visualizations.vis.name, + ]); + + const updateList = (configName: string, fieldName: string, value: string | any[]) => { + let list = { ...configList }; + let listItem = { ...list[configName][0] }; + + const newField = { + label: value, + name: value, + type: value !== '' ? fields.find((x) => x.name === value)?.type : '', + }; + listItem = { ...listItem, [fieldName]: typeof value === 'string' ? newField : value }; + const newList = { + ...list, + [configName]: [listItem], + }; + setConfigList(newList); + }; + + const updateChart = () => { + dispatch( + renderExplorerVis({ + tabId: tabID, + data: { + ...explorerVisualizations, + [visualizations.vis.name]: { + dataConfig: { + metrics: configList.metrics, + dimensions: configList.dimensions, + }, + }, + }, + }) + ); + }; + + return ( + <> + +

Data Configurations

+
+ + +

Dimensions

+
+
+ + + + updateList('dimensions', 'childField', val.length > 0 ? val[0].label : '') + } + /> + + + + ({ label: opt.label, name: opt.label }))} + selectedAxis={configList.dimensions[0].parentFields} + onSelectChange={(val) => updateList('dimensions', 'parentFields', val)} + /> + + +
+ +

Metrics

+
+
+ + + + updateList('metrics', 'valueField', val.length > 0 ? val[0].label : '') + } + /> + + +
+ + + + + Update chart + + + + ); +}; diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx index c5763cbb0..8c4163647 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx @@ -16,6 +16,8 @@ import { ConfigPanel } from './config_panel'; import { Sidebar } from '../sidebar'; import { DataConfigPanelItem } from './config_panel/config_panes/config_controls/data_config_panel_item'; import { TabContext } from '../../hooks'; +import { visChartTypes } from '../../../../../common/constants/shared'; +import { TreemapConfigPanelItem } from './config_panel/config_panes/config_controls/treemap_config_panel_item'; interface IExplorerVisualizationsProps { query: IQuery; curVisId: string; @@ -51,13 +53,13 @@ export const ExplorerVisualizations = ({ const fieldOptionList = fields.map((name) => { return { label: name.name }; - }); + }) return ( {(EuiResizablePanel, EuiResizableButton) => ( <> - +
- +
- + {curVisId === visChartTypes.TreeMap ? ( + + ) : ( + + )}
diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/workspace_panel/workspace_panel.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/workspace_panel/workspace_panel.tsx index aaf9a4542..0fa68e4eb 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/workspace_panel/workspace_panel.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/workspace_panel/workspace_panel.tsx @@ -21,7 +21,9 @@ interface IWorkSpacePanel { export function WorkspacePanel({ visualizations }: IWorkSpacePanel) { const [isTableViewOn, setIsTableViewOn] = useState(false); const VisualizationPanel = useMemo(() => { - return ; + return ( + + ); }, [visualizations]); return ( @@ -64,11 +66,13 @@ export function WorkspacePanel({ visualizations }: IWorkSpacePanel) { - - {isTableViewOn ? - : VisualizationPanel} + + {isTableViewOn ? : VisualizationPanel} diff --git a/dashboards-observability/public/components/event_analytics/utils/utils.tsx b/dashboards-observability/public/components/event_analytics/utils/utils.tsx index 35272fe5a..dd16885aa 100644 --- a/dashboards-observability/public/components/event_analytics/utils/utils.tsx +++ b/dashboards-observability/public/components/event_analytics/utils/utils.tsx @@ -120,8 +120,8 @@ export const populateDataGrid = ( )} {explorerFields?.queriedFields && - explorerFields?.queriedFields?.length > 0 && - explorerFields.selectedFields?.length === 0 ? null : ( + explorerFields?.queriedFields?.length > 0 && + explorerFields.selectedFields?.length === 0 ? null : ( {header2}{body2} diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/data_table.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/data_table.test.tsx.snap index 6031f476d..d9be0e68b 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/data_table.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/data_table.test.tsx.snap @@ -1,649 +1,127 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Data table component Renders data table component 1`] = ` - + - + - - - - -
- -
-
-
- -
- - - - - - + rowHeight={35} + suppressPaginationPanel={true} + /> + + `; diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/line.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/line.test.tsx.snap index 8a061dfd6..94701f7db 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/line.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/line.test.tsx.snap @@ -494,9 +494,19 @@ exports[`Line component Renders line component 1`] = ` data={ Array [ Object { - "mode": "line", - "name": "count()", - "type": "line", + "fill": "tozeroy", + "fillcolor": "rgba(60,161,199,0.2)", + "line": Object { + "color": "#3CA1C7", + "shape": "spline", + "width": 2, + }, + "marker": Object { + "size": 5, + }, + "mode": "lines", + "name": undefined, + "type": "scatter", "x": Array [ "error", "info", @@ -505,14 +515,7 @@ exports[`Line component Renders line component 1`] = ` "success", "warning", ], - "y": Array [ - 154, - 1753, - 116, - 468, - 1964, - 219, - ], + "y": undefined, }, ] } @@ -522,6 +525,9 @@ exports[`Line component Renders line component 1`] = ` "#8C55A3", ], "height": 220, + "legend": Object { + "orientation": "v", + }, "margin": Object { "b": 15, "l": 60, @@ -531,6 +537,16 @@ exports[`Line component Renders line component 1`] = ` }, "showlegend": true, "title": "", + "yaxis1": Object { + "overlaying": "y", + "side": "left", + "tickfont": Object { + "color": "#3CA1C7", + }, + "titlefont": Object { + "color": "#3CA1C7", + }, + }, } } > @@ -543,9 +559,19 @@ exports[`Line component Renders line component 1`] = ` data={ Array [ Object { - "mode": "line", - "name": "count()", - "type": "line", + "fill": "tozeroy", + "fillcolor": "rgba(60,161,199,0.2)", + "line": Object { + "color": "#3CA1C7", + "shape": "spline", + "width": 2, + }, + "marker": Object { + "size": 5, + }, + "mode": "lines", + "name": undefined, + "type": "scatter", "x": Array [ "error", "info", @@ -554,14 +580,7 @@ exports[`Line component Renders line component 1`] = ` "success", "warning", ], - "y": Array [ - 154, - 1753, - 116, - 468, - 1964, - 219, - ], + "y": undefined, }, ] } @@ -577,8 +596,7 @@ exports[`Line component Renders line component 1`] = ` "height": 220, "hovermode": "closest", "legend": Object { - "orientation": "h", - "traceorder": "normal", + "orientation": "v", }, "margin": Object { "b": 15, @@ -600,6 +618,16 @@ exports[`Line component Renders line component 1`] = ` "showgrid": true, "zeroline": false, }, + "yaxis1": Object { + "overlaying": "y", + "side": "left", + "tickfont": Object { + "color": "#3CA1C7", + }, + "titlefont": Object { + "color": "#3CA1C7", + }, + }, } } style={ diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/data_table.test.tsx b/dashboards-observability/public/components/visualizations/charts/__tests__/data_table.test.tsx index e6826ac2a..216a3fa29 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/data_table.test.tsx +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/data_table.test.tsx @@ -3,27 +3,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { configure, mount } from 'enzyme'; +import { configure, mount, shallow } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import React from 'react'; import { waitFor } from '@testing-library/react'; import { DataTable } from '../data_table/data_table'; import { TEST_VISUALIZATIONS_DATA } from '../../../../../test/event_analytics_constants'; +import { AgGridReact } from 'ag-grid-react'; describe('Data table component', () => { configure({ adapter: new Adapter() }); it('Renders data table component', async () => { - const wrapper = mount( - - ); - - wrapper.update(); - + const gridWrapper = shallow(); + const agGridReactObj = gridWrapper.find(AgGridReact); + agGridReactObj.simulate('gridReady'); + expect(agGridReactObj).toBeTruthy(); await waitFor(() => { - expect(wrapper).toMatchSnapshot(); + expect(gridWrapper).toMatchSnapshot(); }); }); }); diff --git a/dashboards-observability/public/components/visualizations/charts/data_table/data_table.scss b/dashboards-observability/public/components/visualizations/charts/data_table/data_table.scss new file mode 100644 index 000000000..86cb0b90e --- /dev/null +++ b/dashboards-observability/public/components/visualizations/charts/data_table/data_table.scss @@ -0,0 +1,63 @@ +.pagination-wrapper { + display: flex; + justify-content: space-between; +} +.custom-pagination-container { + display: inline-flex; + padding: 10px 5px; +} + +.custom-pagination-container li { + font-size: 14px; + padding: 0 5px; + display: flex; + align-items: flex-end; + font-weight: 600; +} + +.custom-pagination-container .euiIcon:focus { + background: transparent !important; +} +.custom-pagination-container a:focus { + animation: none !important; +} +.custom-pagination-container a { + cursor: pointer; +} + +.custom-pagination-container .disabled { + cursor: default; +} +.custom-pagination-container a { + color: #343741; +} +.dark-theme a { + color: #dfe5ef; +} +.custom-pagination-container .selected a { + color: #1ba9f5; + text-decoration: underline; + cursor: default; +} + +.custom-overlay { + display: flex; + align-items: flex-start; + padding: 10px; + position: fixed; + top: 100px; + left: 0; + right: 0; + bottom: 0; + z-index: 99999 !important; + overflow-y: scroll; + overflow-x: hidden; +} + +.custom-overlay-light { + background-color: #fff; +} + +.custom-overlay-dark { + background-color: #16171c; +} diff --git a/dashboards-observability/public/components/visualizations/charts/data_table/data_table.tsx b/dashboards-observability/public/components/visualizations/charts/data_table/data_table.tsx index 912a9dc2c..e6121c21f 100644 --- a/dashboards-observability/public/components/visualizations/charts/data_table/data_table.tsx +++ b/dashboards-observability/public/components/visualizations/charts/data_table/data_table.tsx @@ -3,102 +3,225 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React, { useState, useMemo, useCallback } from 'react'; -import { EuiInMemoryTable, EuiDataGrid } from '@elastic/eui'; +import React, { + useState, + useMemo, + useCallback, + useRef, + useEffect, +} from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, +} from '@elastic/eui'; -export const DataTable = ({ visualizations }: any) => { +// ag-data-grid +import { AgGridReact } from 'ag-grid-react'; +import 'ag-grid-community/dist/styles/ag-grid.css'; +import 'ag-grid-community/dist/styles/ag-theme-alpine.css'; +import 'ag-grid-community/dist/styles/ag-theme-alpine-dark.css'; + +// styles +import './data_table.scss'; + +// grid elements +import { CustomOverlay, RowConfigType, GridHeader, } from "./data_table_header" +import { GridFooter } from "./data_table_footer" + +// constants +import { + COLUMN_DEFAULT_MIN_WIDTH, + HEADER_HEIGHT, +} from '../../../../../common/constants/explorer'; + + +const doubleValueGetter = (params) => { + return params.data[params.column.colId]; +}; + +export const DataTable = ({ visualizations, layout, config }: any) => { const { data: vizData, jsonData, metadata: { fields = [] }, } = visualizations.data.rawVizData; + useEffect(() => { + document.addEventListener('keydown', hideGridFullScreenHandler); + return () => { + document.removeEventListener('keydown', hideGridFullScreenHandler); + }; + }, []); + + // rows and columns const raw_data = [...jsonData]; - // Pagination - const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); - const onChangeItemsPerPage = useCallback( - (pageSize) => - setPagination((pagination) => ({ - ...pagination, - pageSize, - pageIndex: 0, - })), - [setPagination] - ); - const onChangePage = useCallback( - (pageIndex) => setPagination((pagination) => ({ ...pagination, pageIndex })), - [setPagination] - ); + const columns = fields.map((field: any) => { + return { + lockVisible: true, + columnsMenuParams: { + suppressColumnFilter: true, + suppressColumnSelectAll: true, + suppressColumnExpandAll: true, + }, + headerName: field.name, + field: field.name, + colId: field.name, + ...(field.type === 'double' && { + valueGetter: doubleValueGetter, + }), + }; + }); - // Sorting - const [sortingColumns, setSortingColumns] = useState([]); - const onSort = useCallback( - (sortingColumns) => { - setSortingColumns(sortingColumns); - }, - [setSortingColumns] - ); + // ag-grid-react bindings + const gridRef = useRef(); + const gridRefFullScreen = useRef(); + const [pageSize, setPageSize] = useState(10); + const [columnVisibility, setColumnVisibility] = useState([]); + const [isFullScreen, setIsFullScreen] = useState(false); + const [selectedRowDensity, setSelectedRowDensity] = useState({ + icon: 'tableDensityCompact', + height: 35, + selected: true, + }); + // pagination + const [activePage, setActivePage] = useState(0); + const pageCount = Math.ceil(raw_data.length / pageSize); - // Sort data - let data = useMemo(() => { - return [...raw_data].sort((a, b) => { - for (let i = 0; i < sortingColumns.length; i++) { - const column = sortingColumns[i]; - const aValue = a[column.id]; - const bValue = b[column.id]; + const defaultColDef = useMemo(() => { + return { + sortable: true, + resizable: true, + filter: true, + flex: 1, + suppressMenu: true, + minWidth: COLUMN_DEFAULT_MIN_WIDTH, + headerHeight: 400, + }; + }, []); - if (aValue < bValue) return column.direction === 'asc' ? -1 : 1; - if (aValue > bValue) return column.direction === 'asc' ? 1 : -1; + const onPageSizeChanged = useCallback( + (val: number) => { + setPageSize(val); + gridRef.current.api.paginationSetPageSize(val); + setActivePage(0); + gridRef.current.api.paginationGoToPage(0); + if (isFullScreen) { + gridRefFullScreen.current.api.paginationSetPageSize(val); + gridRefFullScreen.current.api.paginationGoToPage(0); } + }, + [isFullScreen] + ); - return 0; + const selectDensityHandler = useCallback((value: RowConfigType) => { + setSelectedRowDensity({ ...value }); + gridRef.current.api.forEachNode((rowNode) => { + if (rowNode.data) { + rowNode.setRowHeight(value.height); + } }); - }, [sortingColumns]); - - // Pagination - data = useMemo(() => { - const rowStart = pagination.pageIndex * pagination.pageSize; - const rowEnd = Math.min(rowStart + pagination.pageSize, data.length); - return data.slice(rowStart, rowEnd); - }, [data, pagination]); - - const columns = fields.map((field) => { - return { - id: field.name, - }; - }); - - // Column visibility - const [visibleColumns, setVisibleColumns] = useState(columns.map(({ id }) => id)); + gridRef.current.api.onRowHeightChanged(); + }, []); - const renderCellValue = useMemo(() => { - return ({ rowIndex, columnId }) => { - let adjustedRowIndex = rowIndex; + const columnVisiblityHandler = useCallback((visible: boolean, field: string) => { + const isExisting = columnVisibility.findIndex((column) => column === field); + if (visible) { + if (isExisting > -1) { + columnVisibility.splice(isExisting, 1); + gridRef?.current?.columnApi?.setColumnsVisible([field], true); + } + } else { + columnVisibility.push(field); + gridRef?.current?.columnApi?.setColumnsVisible([field], false); + } + setColumnVisibility([...columnVisibility]); + }, []); - // If we are doing the pagination (instead of leaving that to the grid) - // then the row index must be adjusted as `data` has already been pruned to the page size - adjustedRowIndex = rowIndex - pagination.pageIndex * pagination.pageSize; + const goToPage = ({ selected }: { selected: number }) => { + setActivePage(selected); + gridRef.current.api.paginationGoToPage(selected); + if (isFullScreen) { + gridRefFullScreen.current.api.paginationGoToPage(selected); + } + }; - return data.hasOwnProperty(adjustedRowIndex) ? data[adjustedRowIndex][columnId] : null; - }; - }, [data, pagination.pageIndex, pagination.pageSize]); + const setIsFullScreenHandler = (val: boolean) => { + setIsFullScreen(val); + }; + const hideGridFullScreenHandler = (e: any) => { + if (e.key === 'Escape') { + setIsFullScreen(false); + } + }; return ( - + <> + + { + gridRef?.current?.api.setHeaderHeight(HEADER_HEIGHT); + }} + /> + + {isFullScreen && ( + + + + { + gridRefFullScreen?.current?.api.setHeaderHeight(HEADER_HEIGHT); + }} + /> + + + + + + + )} + ); }; + + diff --git a/dashboards-observability/public/components/visualizations/charts/data_table/data_table_footer.tsx b/dashboards-observability/public/components/visualizations/charts/data_table/data_table_footer.tsx new file mode 100644 index 000000000..f8350ddd2 --- /dev/null +++ b/dashboards-observability/public/components/visualizations/charts/data_table/data_table_footer.tsx @@ -0,0 +1,126 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useState } from 'react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiPopover, + EuiIcon, + EuiContextMenuPanel, + EuiContextMenuItem, +} from '@elastic/eui'; + +// pagination +import ReactPaginate from 'react-paginate'; + +// theme +import { uiSettingsService } from '../../../../../common/utils'; + +// constants +import { + GRID_PAGE_RANGE_DISPLAY, + GRID_PAGE_SIZES, +} from '../../../../../common/constants/explorer'; + +export const GridFooter = ({ + onPageSizeChanged, + pageSize, + activePage, + goToPage, + pageCount, +}: { + onPageSizeChanged: (val: number) => void; + goToPage: ({ selected }: { selected: number }) => void; + pageSize: number; + activePage: number; + pageCount: number; +}) => { + return ( + + + + + + } + forcePage={activePage} + onPageChange={goToPage} + pageRangeDisplayed={GRID_PAGE_RANGE_DISPLAY} + pageCount={pageCount} + previousLabel={} + renderOnZeroPageCount={null} + /> + + + ); +}; + +export const PageSizePopover = ({ + onPageSizeChanged, + pageSize, +}: { + onPageSizeChanged: (size: number) => void; + pageSize: number; +}) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = () => setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen); + const closePopover = () => setIsPopoverOpen(false); + + const button = ( + + Rows per page: {pageSize} + + ); + + const items = () => { + return GRID_PAGE_SIZES.map((i: number) => ( + { + onPageSizeChanged(i); + closePopover(); + }} + > + {i} rows + + )); + }; + + return ( + + + + ); +}; diff --git a/dashboards-observability/public/components/visualizations/charts/data_table/data_table_header.tsx b/dashboards-observability/public/components/visualizations/charts/data_table/data_table_header.tsx new file mode 100644 index 000000000..1c2d2b034 --- /dev/null +++ b/dashboards-observability/public/components/visualizations/charts/data_table/data_table_header.tsx @@ -0,0 +1,195 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useState, ReactChildren, ReactChild } from 'react'; +import { + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiPopover, + EuiSwitch, + EuiIcon, +} from '@elastic/eui'; + +// theme +import { uiSettingsService } from '../../../../../common/utils'; + +// constants +import { + GRID_HEADER_COLUMN_MAX_WIDTH, + ROW_DENSITIES, +} from '../../../../../common/constants/explorer'; + +export interface RowConfigType { + icon: string; + height: number; + selected: boolean; +} + +export const CustomOverlay = ({ + children, +}: { + children: ReactChild | ReactChild[] | ReactChildren | ReactChildren[]; +}) => { + return ( +
+ {children} +
+ ); +}; + +export const GridHeader = ({ + isFullScreen, + setIsFullScreenHandler, + selectedRowDensity, + selectDensityHandler, + columnVisiblityHandler, + columns, + columnVisibility, +}: { + isFullScreen: boolean; + setIsFullScreenHandler: (v: boolean) => void; + selectedRowDensity: any; + selectDensityHandler: (v: RowConfigType) => void; + columnVisiblityHandler: (visible: boolean, field: string) => void; + columns: any; + columnVisibility: any; +}) => { + return ( + + + + + + + + + setIsFullScreenHandler(true)} + > + Full screen + + + {isFullScreen && ( + setIsFullScreenHandler(false)} + style={{ position: 'absolute', right: 20, cursor: 'pointer', top: 20 }} + /> + )} + + ); +}; + +export const DensityPopover = ({ + selectDensityHandler, + selectedDensity, +}: { + selectedDensity: any; + selectDensityHandler: (data: RowConfigType) => void; +}) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = () => setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen); + const closePopover = () => setIsPopoverOpen(false); + + const button = ( + + Density + + ); + + return ( + + + {ROW_DENSITIES.map((i: RowConfigType, index: number) => ( + + selectDensityHandler(i)} + display={selectedDensity.icon === i.icon ? 'fill' : 'base'} + iconType={i.icon} + aria-label="Next" + /> + + ))} + + + ); +}; + +export const ColumnVisiblityPopover = ({ + columnVisibility, + columns, + columnVisiblityHandler, +}: { + columns: any; + columnVisibility: any; + columnVisiblityHandler: (visible: boolean, field: string) => void; +}) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = () => setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen); + const closePopover = () => setIsPopoverOpen(false); + + const button = ( + + Columns + + ); + + return ( + + + {columns.map((i: any, index: number) => { + return ( + + { + columnVisiblityHandler(e.target.checked, i.field); + }} + compressed + /> + + ); + })} + + + ); +}; diff --git a/dashboards-observability/public/components/visualizations/charts/lines/line.tsx b/dashboards-observability/public/components/visualizations/charts/lines/line.tsx index 4ce620efd..5d21eead1 100644 --- a/dashboards-observability/public/components/visualizations/charts/lines/line.tsx +++ b/dashboards-observability/public/components/visualizations/charts/lines/line.tsx @@ -8,8 +8,11 @@ import { take, isEmpty, last } from 'lodash'; import { Plt } from '../../plotly/plot'; import { AvailabilityUnitType } from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_availability'; import { ThresholdUnitType } from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_thresholds'; +import { DefaultChartStyles, FILLOPACITY_DIV_FACTOR, PLOTLY_COLOR } from '../../../../../common/constants/shared'; +import { hexToRgb } from '../../../../components/event_analytics/utils/utils'; export const Line = ({ visualizations, layout, config }: any) => { + const { DefaultMode, Interpolation, LineWidth, FillOpacity, MarkerSize, LegendPosition, ShowLegend } = DefaultChartStyles; const { data = {}, metadata: { fields }, @@ -20,15 +23,20 @@ export const Line = ({ visualizations, layout, config }: any) => { layoutConfig = {}, availabilityConfig = {}, } = visualizations?.data?.userConfigs; - const xaxis = - dataConfig?.valueOptions && dataConfig.valueOptions.xaxis ? dataConfig.valueOptions.xaxis : []; - const yaxis = - dataConfig?.valueOptions && dataConfig.valueOptions.xaxis ? dataConfig.valueOptions.yaxis : []; + + const dataConfigTab = visualizations.data?.rawVizData?.line?.dataConfig && visualizations.data.rawVizData.line.dataConfig; + const xaxis = dataConfigTab?.dimensions ? dataConfigTab?.dimensions : []; + const yaxis = dataConfigTab?.metrics ? dataConfigTab?.metrics : []; + const lastIndex = fields.length - 1; - const mode = - dataConfig?.chartOptions && dataConfig.chartOptions.mode && dataConfig.chartOptions.mode[0] - ? dataConfig.chartOptions.mode[0].modeId - : 'line'; + + const mode = dataConfig?.chartStyles?.style || DefaultMode; + const lineShape = dataConfig?.chartStyles?.interpolation || Interpolation; + const lineWidth = dataConfig?.chartStyles?.lineWidth || LineWidth; + const showLegend = !(dataConfig?.legend?.showLegend && dataConfig.legend.showLegend !== ShowLegend); + const legendPosition = dataConfig?.legend?.position || LegendPosition; + const markerSize = dataConfig?.chartStyles?.pointSize || MarkerSize; + const fillOpacity = dataConfig?.chartStyles?.fillOpacity !== undefined ? dataConfig?.chartStyles?.fillOpacity / FILLOPACITY_DIV_FACTOR : FillOpacity / FILLOPACITY_DIV_FACTOR; let valueSeries; if (!isEmpty(xaxis) && !isEmpty(yaxis)) { @@ -37,21 +45,69 @@ export const Line = ({ visualizations, layout, config }: any) => { valueSeries = defaultAxes.yaxis || take(fields, lastIndex > 0 ? lastIndex : 1); } + let multiMetrics = {}; const [calculatedLayout, lineValues] = useMemo(() => { - let calculatedLineValues = valueSeries.map((field: any) => { + const isBarMode = mode === 'bar'; + + let calculatedLineValues = valueSeries.map((field: any, index: number) => { + const fillColor = hexToRgb(PLOTLY_COLOR[index % PLOTLY_COLOR.length], fillOpacity); + const barMarker = { + color: fillColor, + line: { + color: PLOTLY_COLOR[index], + width: lineWidth + } + }; + const fillProperty = { + fill: 'tozeroy', + fillcolor: fillColor, + }; + const multiYaxis = { yaxis: `y${index + 1}` }; + multiMetrics = { + ...multiMetrics, + [`yaxis${index + 1}`]: { + // title: `yaxis${index + 1} title`, TODO: need to add title + titlefont: { color: PLOTLY_COLOR[index] }, + tickfont: { color: PLOTLY_COLOR[index] }, + overlaying: 'y', + side: index === 0 ? 'left' : field.side || "right" + } + } + return { x: data[!isEmpty(xaxis) ? xaxis[0]?.label : fields[lastIndex].name], - y: data[field.name], - type: 'line', - name: field.name, + y: data[field.label], + type: isBarMode ? 'bar' : 'scatter', + name: field.label, mode, + ...!['bar', 'markers'].includes(mode) && fillProperty, + line: { + shape: lineShape, + width: lineWidth, + color: PLOTLY_COLOR[index], + }, + marker: { + size: markerSize, + ...isBarMode && barMarker, + }, + ...(index >= 1 && multiYaxis) }; }); + let layoutForBarMode = { + barmode: 'group', + }; const mergedLayout = { ...layout, ...layoutConfig.layout, title: dataConfig?.panelOptions?.title || layoutConfig.layout?.title || '', + legend: { + ...layout.legend, + orientation: legendPosition, + }, + showlegend: showLegend, + ...isBarMode && layoutForBarMode, + ...multiMetrics && multiMetrics, }; if (dataConfig.thresholds || availabilityConfig.level) { diff --git a/dashboards-observability/public/components/visualizations/charts/lines/line_type.ts b/dashboards-observability/public/components/visualizations/charts/lines/line_type.ts index 20e452388..ed8e1ed8d 100644 --- a/dashboards-observability/public/components/visualizations/charts/lines/line_type.ts +++ b/dashboards-observability/public/components/visualizations/charts/lines/line_type.ts @@ -12,11 +12,16 @@ import { ConfigEditor } from '../../../event_analytics/explorer/visualizations/c import { ConfigValueOptions, ConfigThresholds, + ConfigLineChartStyles, + ConfigLegend, } from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls'; import { ConfigAvailability } from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_availability'; - +import { DefaultChartStyles } from '../../../../../common/constants/shared'; +import { ButtonGroupItem } from '../../../../../public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group'; +import { SliderConfig } from '../../../../../public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider'; const sharedConfigs = getPlotlySharedConfigs(); const VIS_CATEGORY = getPlotlyCategory(); +const { DefaultMode, Interpolation, LineWidth, FillOpacity, MarkerSize, LegendPosition, ShowLegend } = DefaultChartStyles; export const createLineTypeDefinition = (params: any = {}) => ({ name: 'line', @@ -41,45 +46,103 @@ export const createLineTypeDefinition = (params: any = {}) => ({ editor: VizDataPanel, sections: [ { - id: 'value_options', - name: 'Value options', - editor: ConfigValueOptions, - mapTo: 'valueOptions', + id: 'legend', + name: 'Legend', + editor: ConfigLegend, + mapTo: 'legend', schemas: [ { - name: 'X-axis', - isSingleSelection: true, + name: 'Show Legend', + mapTo: 'showLegend', component: null, - mapTo: 'xaxis', + props: { + options: [ + { name: 'Show', id: "show" }, + { name: 'Hidden', id: "hidden" }, + ], + defaultSelections: [{ name: 'Show', id: ShowLegend }], + }, }, { - name: 'Y-axis', - isSingleSelection: false, + name: 'Position', + mapTo: 'position', component: null, - mapTo: 'yaxis', + props: { + options: [ + { name: 'Right', id: 'v' }, + { name: 'Bottom', id: 'h' }, + ], + defaultSelections: [{ name: 'Right', id: LegendPosition }], + }, }, ], }, { - id: 'chart_options', - name: 'Chart options', - editor: ConfigValueOptions, - mapTo: 'chartOptions', + id: 'chart_styles', + name: 'Chart styles', + editor: ConfigLineChartStyles, + mapTo: 'chartStyles', schemas: [ { name: 'Mode', - isSingleSelection: true, - component: null, - mapTo: 'mode', + component: ButtonGroupItem, + mapTo: 'style', + eleType: 'buttons', props: { - dropdownList: [ - { name: 'Markers', modeId: 'markers' }, - { name: 'Lines', modeId: 'lines' }, - { name: 'Lines + Markers', modeId: 'lines+markers' }, + options: [ + { name: 'Lines', id: 'lines' }, + { name: 'Bars', id: 'bar' }, + { name: 'Points', id: 'markers' }, + { name: 'Lines + Points', id: 'lines+markers' } ], - defaultSelections: [{ name: 'Lines', modeId: 'lines' }], + defaultSelections: [{ name: 'Lines', id: DefaultMode }], }, }, + { + name: 'Interpolation', + component: ButtonGroupItem, + mapTo: 'interpolation', + eleType: 'buttons', + props: { + options: [ + { name: 'Linear', id: 'linear' }, + { name: 'Smooth', id: 'spline' }, + { name: 'Step before', id: 'hv' }, + { name: 'Step after', id: 'vh' }, + ], + defaultSelections: [{ name: 'Smooth', id: Interpolation }], + }, + }, + { + name: 'Line width', + component: SliderConfig, + mapTo: 'lineWidth', + defaultState: LineWidth, + eleType: 'slider', + props:{ + max: 10, + } + }, + { + name: 'Fill Opacity', + component: SliderConfig, + mapTo: 'fillOpacity', + defaultState: FillOpacity, + eleType: 'slider', + props:{ + max: 100, + } + }, + { + name: 'Point Size', + component: SliderConfig, + mapTo: 'pointSize', + defaultState: MarkerSize, + eleType: 'slider', + props:{ + max: 40, + } + }, ], }, { diff --git a/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx b/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx index 9155dea04..176c5421d 100644 --- a/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx +++ b/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx @@ -29,30 +29,26 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { if (fields.length < 3) return ; - const xaxisField = fields[fields.length - 2]; - const yaxisField = fields[fields.length - 1]; - const zMetrics = - dataConfig?.valueOptions && dataConfig?.valueOptions.zaxis - ? dataConfig?.valueOptions.zaxis[0] - : yaxis.length > 0 - ? yaxis[0] - : fields[fields.length - 3]; - const uniqueYaxis = uniq(data[yaxisField.name]); - const uniqueXaxis = uniq(data[xaxisField.name]); - const uniqueYaxisLength = uniqueYaxis.length; - const uniqueXaxisLength = uniqueXaxis.length; + const xaxisField = visualizations.data?.rawVizData?.heatmap?.dataConfig?.dimensions[0]; + const yaxisField = visualizations.data?.rawVizData?.heatmap?.dataConfig?.dimensions[1]; + const zMetrics = visualizations.data?.rawVizData?.heatmap?.dataConfig?.metrics[0]; if ( isEmpty(xaxisField) || isEmpty(yaxisField) || isEmpty(zMetrics) || - isEmpty(data[xaxisField.name]) || - isEmpty(data[yaxisField.name]) || - isEmpty(data[zMetrics.name]) || + isEmpty(data[xaxisField.label]) || + isEmpty(data[yaxisField.label]) || + isEmpty(data[zMetrics.label]) || indexOf(NUMERICAL_FIELDS, zMetrics.type) < 0 ) return ; + const uniqueYaxis = uniq(data[yaxisField.label]); + const uniqueXaxis = uniq(data[xaxisField.label]); + const uniqueYaxisLength = uniqueYaxis.length; + const uniqueXaxisLength = uniqueXaxis.length; + const colorField = dataConfig?.chartStyles ? dataConfig?.chartStyles.colorMode && dataConfig?.chartStyles.colorMode[0].name === OPACITY ? dataConfig?.chartStyles.color ?? HEATMAP_SINGLE_COLOR @@ -75,8 +71,8 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { const buckets = {}; // maps bukcets to metrics - for (let i = 0; i < data[xaxisField.name].length; i++) { - buckets[`${data[xaxisField.name][i]},${data[yaxisField.name][i]}`] = data[zMetrics.name][i]; + for (let i = 0; i < data[xaxisField.label].length; i++) { + buckets[`${data[xaxisField.label][i]},${data[yaxisField.label][i]}`] = data[zMetrics.label][i]; } // initialize empty 2 dimensional array, inner loop for each xaxis field, outer loop for yaxis diff --git a/dashboards-observability/public/components/visualizations/charts/maps/heatmap_type.ts b/dashboards-observability/public/components/visualizations/charts/maps/heatmap_type.ts index 4b8872931..8bcd56697 100644 --- a/dashboards-observability/public/components/visualizations/charts/maps/heatmap_type.ts +++ b/dashboards-observability/public/components/visualizations/charts/maps/heatmap_type.ts @@ -44,20 +44,6 @@ export const createMapsVisDefinition = () => ({ mapTo: 'dataConfig', editor: VizDataPanel, sections: [ - { - id: 'value_options', - name: 'Value options', - editor: ConfigValueOptions, - mapTo: 'valueOptions', - schemas: [ - { - name: 'Z-axis', - isSingleSelection: true, - component: null, - mapTo: 'zaxis', - }, - ], - }, { id: 'chart_styles', name: 'Chart Styles', diff --git a/dashboards-observability/public/components/visualizations/charts/maps/treemap_type.ts b/dashboards-observability/public/components/visualizations/charts/maps/treemap_type.ts index 80b8232b7..eb4bc7d6e 100644 --- a/dashboards-observability/public/components/visualizations/charts/maps/treemap_type.ts +++ b/dashboards-observability/public/components/visualizations/charts/maps/treemap_type.ts @@ -12,7 +12,6 @@ import { ConfigValueOptions, ColorPalettePicker, ConfigChartOptions, - ConfigTreemapParentFields, } from '../../../event_analytics/explorer/visualizations/config_panel/config_panes/config_controls'; import { DEFAULT_PALETTE, COLOR_PALETTES } from '../../../../../common/constants/colors'; @@ -45,32 +44,6 @@ export const createTreeMapDefinition = (params: BarTypeParams = {}) => ({ mapTo: 'dataConfig', editor: VizDataPanel, sections: [ - { - id: 'value_options', - name: 'Value options', - editor: ConfigValueOptions, - mapTo: 'valueOptions', - schemas: [ - { - name: 'Value Field', - isSingleSelection: true, - component: null, - mapTo: 'valueField', - }, - { - name: 'Child Field', - isSingleSelection: true, - component: null, - mapTo: 'childField', - }, - { - name: 'Parent Fields', - component: ConfigTreemapParentFields, - mapTo: 'parentFields', - defaultState: [], - }, - ], - }, { id: 'treemap_options', name: 'Treemap', diff --git a/dashboards-observability/public/components/visualizations/charts/maps/treemaps.tsx b/dashboards-observability/public/components/visualizations/charts/maps/treemaps.tsx index 6922f075c..f13c69ec5 100644 --- a/dashboards-observability/public/components/visualizations/charts/maps/treemaps.tsx +++ b/dashboards-observability/public/components/visualizations/charts/maps/treemaps.tsx @@ -23,22 +23,21 @@ export const TreeMap = ({ visualizations, layout, config }: any) => { const { dataConfig = {}, layoutConfig = {} } = visualizations?.data?.userConfigs; const childField = - dataConfig?.valueOptions && - dataConfig?.valueOptions.childField && - !isEmpty(dataConfig?.valueOptions.childField) - ? dataConfig?.valueOptions.childField[0] + visualizations.data?.rawVizData?.tree_map?.dataConfig?.dimensions && + visualizations.data?.rawVizData?.tree_map?.dataConfig?.dimensions[0].childField + ? visualizations.data?.rawVizData?.tree_map?.dataConfig?.dimensions[0].childField : fields[fields.length - 1]; const parentFields = - dataConfig?.valueOptions && dataConfig.valueOptions?.parentFields - ? dataConfig?.valueOptions.parentFields + visualizations.data?.rawVizData?.tree_map?.dataConfig?.dimensions && + visualizations.data?.rawVizData?.tree_map?.dataConfig.dimensions[0].parentFields + ? visualizations.data?.rawVizData?.tree_map?.dataConfig?.dimensions[0].parentFields : []; const valueField = - dataConfig?.valueOptions && - dataConfig.valueOptions?.valueField && - !isEmpty(dataConfig?.valueOptions.valueField) - ? dataConfig?.valueOptions.valueField[0] + visualizations.data?.rawVizData?.tree_map?.dataConfig?.metrics && + visualizations.data?.rawVizData?.tree_map?.dataConfig.metrics[0].valueField + ? visualizations.data?.rawVizData?.tree_map?.dataConfig?.metrics[0].valueField : fields[0]; const colorField = diff --git a/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx b/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx index 0a07e985a..5dc4dd204 100644 --- a/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx +++ b/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx @@ -16,11 +16,11 @@ export const Pie = ({ visualizations, layout, config }: any) => { } = visualizations.data.rawVizData; const { defaultAxes } = visualizations.data; const { dataConfig = {}, layoutConfig = {} } = visualizations?.data?.userConfigs; - const xaxis = visualizations.data?.rawVizData?.dataConfig?.dimensions - ? visualizations.data?.rawVizData?.dataConfig?.dimensions + const xaxis = visualizations.data?.rawVizData?.pie?.dataConfig?.dimensions + ? visualizations.data?.rawVizData?.pie?.dataConfig?.dimensions : []; - const yaxis = visualizations.data?.rawVizData?.dataConfig?.metrics - ? visualizations.data?.rawVizData?.dataConfig?.metrics + const yaxis = visualizations.data?.rawVizData?.pie?.dataConfig?.metrics + ? visualizations.data?.rawVizData?.pie?.dataConfig?.metrics : []; const type = dataConfig?.chartStyles?.mode ? dataConfig?.chartStyles?.mode[0]?.modeId : 'pie'; const lastIndex = fields.length - 1; diff --git a/dashboards-observability/yarn.lock b/dashboards-observability/yarn.lock index c205c9bf8..1bff758f9 100644 --- a/dashboards-observability/yarn.lock +++ b/dashboards-observability/yarn.lock @@ -325,6 +325,18 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +ag-grid-community@^27.3.0: + version "27.3.0" + resolved "https://registry.yarnpkg.com/ag-grid-community/-/ag-grid-community-27.3.0.tgz#b1e94a58026aaf2f0cd7920e35833325b5e762c7" + integrity sha512-R5oZMXEHXnOLrmhn91J8lR0bv6IAnRcU6maO+wKLMJxffRWaAYFAuw1jt7bdmcKCv8c65F6LEBx4ykSOALa9vA== + +ag-grid-react@^27.3.0: + version "27.3.0" + resolved "https://registry.yarnpkg.com/ag-grid-react/-/ag-grid-react-27.3.0.tgz#fe06647653f8b0b349b8e613aab8ea2e07915562" + integrity sha512-2bs9YfJ/shvBZQLLjny4NFvht+ic6VtpTPO0r3bHHOhlL3Fjx2rGvS6AHSwfvu+kJacHCta30PjaEbX8T3UDyw== + dependencies: + prop-types "^15.8.1" + ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -2133,6 +2145,15 @@ prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + property-information@^5.0.0: version "5.6.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" @@ -2216,7 +2237,7 @@ react-graph-vis@^1.0.5: vis-data "^7.1.2" vis-network "^9.0.0" -react-is@^16.8.1, react-is@^16.8.6: +react-is@^16.13.1, react-is@^16.8.1, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -2248,6 +2269,13 @@ react-markdown@^4.0.0: unist-util-visit "^1.3.0" xtend "^4.0.1" +react-paginate@^8.1.3: + version "8.1.3" + resolved "https://registry.yarnpkg.com/react-paginate/-/react-paginate-8.1.3.tgz#cd6f3cb8a56b47617a61a6a52e3d7c662ad9b91b" + integrity sha512-zBp80DBRcaeBnAeHUfbGKD0XHfbGNUolQ+S60Ymfs8o7rusYaJYZMAt1j93ADDNLlzRmJ0tMF/NeTlcdKf7dlQ== + dependencies: + prop-types "^15.6.1" + react-plotly.js@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/react-plotly.js/-/react-plotly.js-2.5.1.tgz#11182bf599ef11a0dbfcd171c6f5645535a2b486" From dd298c220ffbb1bab47b265e259448be60ec8fd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Jul 2022 10:44:01 -0700 Subject: [PATCH 4/9] Bump moment from 2.29.2 to 2.29.4 in /dashboards-observability (#845) Bumps [moment](https://github.com/moment/moment) from 2.29.2 to 2.29.4. - [Release notes](https://github.com/moment/moment/releases) - [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md) - [Commits](https://github.com/moment/moment/compare/2.29.2...2.29.4) --- updated-dependencies: - dependency-name: moment dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dashboards-observability/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dashboards-observability/yarn.lock b/dashboards-observability/yarn.lock index 1bff758f9..95f119e37 100644 --- a/dashboards-observability/yarn.lock +++ b/dashboards-observability/yarn.lock @@ -1913,9 +1913,9 @@ mkdirp@^0.5.4: minimist "^1.2.5" moment@^2.27.0: - version "2.29.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4" - integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg== + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== ms@2.0.0: version "2.0.0" From 1a95ba52bc72a2043510edd19284c2d36443b59e Mon Sep 17 00:00:00 2001 From: abasatwar Date: Tue, 26 Jul 2022 20:36:38 +0530 Subject: [PATCH 5/9] Sprint2 (#47) (#868) * graph style section UI schema Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts * changes for style mode and interpolation Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts * lineWidth integration for line mode Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * changes for Legend and Orientation in Line Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_legend.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * point size and Bar Alignment changes Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/common/types/explorer.ts * implemented fill opacity for line chart Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx * changes for line width and fill opacity in bar mode and removed mode from chartOption Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/common/constants/shared.ts * updated bar mode opacity in line chart Signed-off-by: rinku-kumar-psl * refactored the config chart style code Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/common/types/explorer.ts * snapshot updated and code refactored Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx * type added to new component Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group.tsx # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * review comments addressed Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx # Conflicts: # dashboards-observability/common/constants/shared.ts * cypress test case added and resolve button label wraping issue Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js # dashboards-observability/.cypress/utils/event_constants.js # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js * multi matrices changes for Line Signed-off-by: rinku-kumar-psl * dimensions and metrics UI changes for time-series Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/common/constants/explorer.ts # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx * made data config pannel collapsable and initial fields render Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx * code refactored Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx * snapshot updated and handled corner cases Signed-off-by: rinku-kumar-psl * code styling fixes and added TODO comment Signed-off-by: rinku-kumar-psl * sequence change for dimensions and metrics Signed-off-by: Deepak Nevde * Sprint1 (#14) * graph style section UI schema Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts * changes for style mode and interpolation Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts * lineWidth integration for line mode Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * changes for Legend and Orientation in Line Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_legend.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * point size and Bar Alignment changes Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # dashboards-observability/public/components/visualizations/charts/lines/line_type.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/common/types/explorer.ts * implemented fill opacity for line chart Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/visualizations/charts/lines/line.tsx # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx * changes for line width and fill opacity in bar mode and removed mode from chartOption Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/common/constants/shared.ts * updated bar mode opacity in line chart Signed-off-by: rinku-kumar-psl * refactored the config chart style code Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/index.ts # Conflicts: # dashboards-observability/common/constants/shared.ts # dashboards-observability/common/types/explorer.ts * snapshot updated and code refactored Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx * type added to new component Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_button_group.tsx # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_style_slider.tsx * review comments addressed Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/utils/utils.tsx # Conflicts: # dashboards-observability/common/constants/shared.ts * cypress test case added and resolve button label wraping issue Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js # dashboards-observability/.cypress/utils/event_constants.js # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js # Conflicts: # dashboards-observability/.cypress/integration/1_event_analytics.spec.js * multi matrices changes for Line Signed-off-by: rinku-kumar-psl * dimensions and metrics UI changes for time-series Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/common/constants/explorer.ts # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx * made data config pannel collapsable and initial fields render Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx # dashboards-observability/public/components/event_analytics/explorer/visualizations/index.tsx * code refactored Signed-off-by: rinku-kumar-psl # Conflicts: # dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_item.tsx * snapshot updated and handled corner cases Signed-off-by: rinku-kumar-psl * code styling fixes and added TODO comment Signed-off-by: rinku-kumar-psl * data config reviewed code added Signed-off-by: Deepak Nevde * Text correction Signed-off-by: Deepak Nevde * Conflicts resolved Signed-off-by: Deepak Nevde * table view: eui table replaced with ag-grid Signed-off-by: Ramneet Chopra * drag-drop issue fixed Signed-off-by: Ramneet Chopra * test case of data_table updated Signed-off-by: Ramneet Chopra * feedback comments resolved Signed-off-by: Ramneet Chopra * grid height issue:fixed Signed-off-by: Ramneet Chopra * column height, value getter for type double Signed-off-by: Ramneet Chopra * data_table elements moved to separate Signed-off-by: Ramneet Chopra * footer components Signed-off-by: Ramneet Chopra * cypress test cases for table view Signed-off-by: Ramneet Chopra * enhancement for heatmap with new UI Signed-off-by: Shankha Das * line chart test cases Signed-off-by: Shankha Das * console logs removed Signed-off-by: Shankha Das * updated value options ui for treemap Signed-off-by: Mrunal Zambre * removed console Signed-off-by: Mrunal Zambre * Fixes of sprint1 for new ui implementation (#12) Signed-off-by: ruchika-narang Co-authored-by: rinku-kumar-psl Co-authored-by: Deepak Nevde Co-authored-by: Ramneet Chopra Co-authored-by: Shankha Das Co-authored-by: Mrunal Zambre Co-authored-by: ruchika-narang <79983862+ruchika-narang@users.noreply.github.com> * Latest code added Signed-off-by: Deepak Nevde * Collapsapable button position change to top Signed-off-by: Deepak Nevde * table view: eui table replaced with ag-grid Signed-off-by: Ramneet Chopra * drag-drop issue fixed Signed-off-by: Ramneet Chopra * test case of data_table updated Signed-off-by: Ramneet Chopra * feedback comments resolved Signed-off-by: Ramneet Chopra * grid height issue:fixed Signed-off-by: Ramneet Chopra * column height, value getter for type double Signed-off-by: Ramneet Chopra * data_table elements moved to separate Signed-off-by: Ramneet Chopra * footer components Signed-off-by: Ramneet Chopra * cypress test cases for table view Signed-off-by: Ramneet Chopra * data config reviewed code added Signed-off-by: Deepak Nevde * Text correction Signed-off-by: Deepak Nevde * Conflicts resolved Signed-off-by: Deepak Nevde * enhancement for heatmap with new UI Signed-off-by: Shankha Das * line chart test cases Signed-off-by: Shankha Das * console logs removed Signed-off-by: Shankha Das * updated value options ui for treemap Signed-off-by: Mrunal Zambre * removed console Signed-off-by: Mrunal Zambre * sprint1-visualization-fixes. Signed-off-by: abasatwar * added colorscale config options for treemap Signed-off-by: Mrunal Zambre * code review comment resolved Signed-off-by: Deepak Nevde * added config option to sort treemap sectors Signed-off-by: Mrunal Zambre * changes to resctct duplicte options Signed-off-by: rinku-kumar-psl * Updated and Added test scripts for Treemap chart along with data config and worked on reassembling the event_constants.js file Signed-off-by: Pratibha Pandey * Removed unwanted code Signed-off-by: Pratibha Pandey * implementation of histogram with new UI Signed-off-by: ruchika-narang * gauge chart added Signed-off-by: Ramneet Chopra * Pie chart enhancement, multi labels change Signed-off-by: Deepak Nevde * threshold text fix Signed-off-by: Ramneet Chopra * cypress test cases added Signed-off-by: Ramneet Chopra * Code review comment resolved Signed-off-by: Deepak Nevde * reset fixed, unused imports removed, PR checks fixed Signed-off-by: Ramneet Chopra * single timestamp dimension, no data dsiplay, label rotate, label/legend size Signed-off-by: Ramneet Chopra * layout fixed for primary y axis Signed-off-by: Ramneet Chopra * change of screen size of no data found and visualization Signed-off-by: Shankha Das * changes for restriction of duplicate fields on Data Config and only numeric field selection to metrics Signed-off-by: rinku-kumar-psl * line label replaced with time series Signed-off-by: Ramneet Chopra * snapshot tests Signed-off-by: Ramneet Chopra * Removed unwanted spaces Signed-off-by: Pratibha Pandey * initialize default params for DimensonComponent and formatted the codes Signed-off-by: rinku-kumar-psl * pr review feedback Signed-off-by: Ramneet Chopra * updated preview functionality for charts Signed-off-by: Mrunal Zambre * updated snapshots Signed-off-by: Mrunal Zambre * Worked on review comments Signed-off-by: Pratibha Pandey * changed variable names Signed-off-by: Mrunal Zambre * code review changes done Signed-off-by: rinku-kumar-psl * added empty line at end. Signed-off-by: abasatwar * updated variable names Signed-off-by: Mrunal Zambre * updated snapshots Signed-off-by: Mrunal Zambre * Added pie chart test cases Signed-off-by: Pratibha Pandey * updated snapshots Signed-off-by: ruchika-narang * Removed consoles Signed-off-by: ruchika-narang * Worked on conflicts Signed-off-by: Pratibha Pandey * color selector added Signed-off-by: Ramneet Chopra * updated snapshots Signed-off-by: ruchika-narang * UI updated as recommended Signed-off-by: Shankha Das * Added legend to heatmap Signed-off-by: ruchika-narang * data_config_panel_item timeseries code removed Signed-off-by: Ramneet Chopra * bar chart with multiple dimension and metrics, timestamp Signed-off-by: abasatwar * limit no. of gauge option added Signed-off-by: Ramneet Chopra * threshold limit added, gauge default parameters moved to constants/explorer Signed-off-by: Ramneet Chopra * legend placement added Signed-off-by: Ramneet Chopra * yarn test Signed-off-by: Ramneet Chopra * snapshot updated Signed-off-by: abasatwar * snapshot updated Signed-off-by: abasatwar * Resolving issues after removal of preview functionality Signed-off-by: ruchika-narang * updated snapshots Signed-off-by: ruchika-narang * Updated snapshots Signed-off-by: ruchika-narang * changes for default timestamp data for time-series and corner cases Signed-off-by: rinku-kumar-psl * code review comment addressed Signed-off-by: rinku-kumar-psl * pr feedback Signed-off-by: Ramneet Chopra * dimensions, metrics length checks refined Signed-off-by: Ramneet Chopra * updated as per review comments Signed-off-by: abasatwar * fixing of data config corner cases Signed-off-by: rinku-kumar-psl * snapshot updated Signed-off-by: abasatwar * pr feedback Signed-off-by: Ramneet Chopra Co-authored-by: rinku-kumar-psl Co-authored-by: Deepak Nevde Co-authored-by: Ramneet Chopra Co-authored-by: Shankha Das Co-authored-by: Mrunal Zambre Co-authored-by: ruchika-narang <79983862+ruchika-narang@users.noreply.github.com> Co-authored-by: Pratibha Pandey Co-authored-by: ruchika-narang Co-authored-by: Shankha Das Co-authored-by: rinku-kumar-psl Co-authored-by: Deepak Nevde Co-authored-by: Ramneet Chopra Co-authored-by: Shankha Das Co-authored-by: Mrunal Zambre Co-authored-by: ruchika-narang <79983862+ruchika-narang@users.noreply.github.com> Co-authored-by: Pratibha Pandey Co-authored-by: ruchika-narang Co-authored-by: Shankha Das --- .../integration/1_event_analytics.spec.js | 181 +- .../.cypress/utils/event_constants.js | 117 +- .../common/constants/explorer.ts | 23 +- .../common/constants/shared.ts | 11 +- .../common/types/explorer.ts | 6 +- .../__snapshots__/utils.test.tsx.snap | 1382 +-- .../explorer/visualizations/app.scss | 29 + .../__snapshots__/config_panel.test.tsx.snap | 9929 ++++++++--------- .../config_panel/config_panel.scss | 15 +- .../config_panel/config_panel.tsx | 16 +- .../config_panel/config_panel_footer.tsx | 19 - .../config_bar_chart_styles.tsx | 27 +- .../config_controls/config_chart_options.tsx | 62 +- .../config_controls/config_color_theme.tsx | 210 +- .../config_controls/config_legend.tsx | 15 +- .../config_line_chart_styles.tsx | 101 +- .../config_controls/config_number_input.tsx | 39 +- .../config_panel_option_gauge.tsx | 52 + .../config_controls/config_panel_options.tsx | 58 +- .../config_controls/config_switch_button.tsx | 25 + .../config_controls/config_thresholds.tsx | 6 +- .../config_treemap_parents.tsx | 17 +- .../config_controls/config_value_options.tsx | 40 +- .../data_config_panel_item.tsx | 150 +- .../config_panes/config_controls/index.ts | 4 + .../treemap_config_panel_item.tsx | 62 +- .../config_panes/default_vis_editor.tsx | 1 + .../explorer/visualizations/index.tsx | 46 +- .../shared_components.test.tsx.snap | 10 +- .../shared_components/empty_placeholder.scss | 12 + .../shared_components/empty_placeholder.tsx | 7 +- .../__tests__/__snapshots__/bar.test.tsx.snap | 254 +- .../__snapshots__/heatmap.test.tsx.snap | 38 +- .../__snapshots__/histogram.test.tsx.snap | 612 + .../__snapshots__/line.test.tsx.snap | 259 +- .../__tests__/__snapshots__/pie.test.tsx.snap | 241 +- .../__snapshots__/text.test.tsx.snap | 28 +- .../__snapshots__/treemap.test.tsx.snap | 30 +- .../charts/__tests__/histogram.test.tsx | 30 + .../visualizations/charts/bar/bar.tsx | 170 +- .../visualizations/charts/bar/bar_type.ts | 53 +- .../charts/financial/gauge/gauge.tsx | 171 +- .../charts/financial/gauge/gauge_type.ts | 83 +- .../charts/helpers/viz_types.ts | 28 +- .../charts/histogram/histogram.tsx | 81 +- .../charts/histogram/histogram_type.ts | 80 +- .../visualizations/charts/lines/line.tsx | 116 +- .../visualizations/charts/lines/line_type.ts | 79 +- .../visualizations/charts/maps/heatmap.tsx | 5 +- .../charts/maps/heatmap_type.ts | 21 + .../charts/maps/treemap_type.ts | 38 + .../visualizations/charts/maps/treemaps.tsx | 14 +- .../visualizations/charts/pie/pie.tsx | 32 +- .../charts/shared/shared_configs.ts | 2 +- 54 files changed, 7671 insertions(+), 7466 deletions(-) create mode 100644 dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_panel_option_gauge.tsx create mode 100644 dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/config_switch_button.tsx create mode 100644 dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/empty_placeholder.scss create mode 100644 dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/histogram.test.tsx.snap create mode 100644 dashboards-observability/public/components/visualizations/charts/__tests__/histogram.test.tsx diff --git a/dashboards-observability/.cypress/integration/1_event_analytics.spec.js b/dashboards-observability/.cypress/integration/1_event_analytics.spec.js index f2b0db3c6..3f43a6eb7 100644 --- a/dashboards-observability/.cypress/integration/1_event_analytics.spec.js +++ b/dashboards-observability/.cypress/integration/1_event_analytics.spec.js @@ -21,10 +21,29 @@ import { renderTreeMapchart, renderPieChart, renderLineChartForDataConfig, - DataConfigLineChart + renderDataConfig, + aggregationValues, + DataConfigLineChart, + renderAddParent, + renderGaugeChart, + renderAddParent } from '../utils/event_constants'; import { supressResizeObserverIssue } from '../utils/constants'; +const renderHistogramChart = () => { + querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM); + cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Histogram').type('{enter}'); + cy.wait(delay); + cy.get('g.draglayer.cursor-crosshair').should('exist'); + cy.get('#configPanel__panelOptions .euiFieldText').click().type('Histogram chart'); + cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').click().type('This is the description for Histogram chart'); + cy.get('.euiIEFlexWrapFix').eq(1).contains('Chart Styles').should('exist'); + cy.get('.euiFormLabel.euiFormRow__label').eq(2).contains('Bucket Size'); + cy.get('.euiFieldNumber').eq(0).type('4'); + cy.get('.euiFormLabel.euiFormRow__label').eq(3).contains('Bucket Offset'); + cy.get('.euiFieldNumber').eq(0).type('6'); +}; + const vis_name_sub_string = Math.floor(Math.random() * 100); const saveVisualizationAndVerify = () => { cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click(); @@ -857,3 +876,163 @@ describe('Render Time series chart/Line chart and verify Data configurations UI DataConfigLineChart(); }); }); + +describe('Renders Data Configurations section for Pie chart', () => { + beforeEach(() => { + landOnEventVisualizations(); + }); + + it('Renders Dimensions and Metrics under Data Configurations for Pie chart', () => { + renderPieChart(); + renderDataConfig(); + }); + + it('Validate "Add" and "X" buttons', () => { + renderPieChart(); + cy.get('.euiResizablePanel.euiResizablePanel--middle').contains('Data Configurations'); + cy.get('.euiButton.euiButton--primary.euiButton--fullWidth').contains('Add').click(); + cy.get('.euiFormRow__fieldWrapper .euiComboBox').eq(3).click(); + cy.get('.euiComboBoxOption__content').eq(2).click(); + cy.get('.first-division .euiFormLabel.euiFormRow__label').eq(4).click(); + cy.get('.euiComboBoxOption__content').eq(1).click(); + cy.get('.euiFieldText[placeholder="Custom label"]').eq(1).type('Demo field'); + cy.get('.euiIcon.euiIcon--medium.euiIcon--danger').eq(1).click(); + cy.get('.euiButton.euiButton--primary.euiButton--fullWidth').contains('Add').should('exist'); + }); + + it('Verify drop down values for Aggregation', () => { + renderPieChart(); + cy.get('.euiResizablePanel.euiResizablePanel--middle').contains('Data Configurations'); + cy.get('.euiTitle.euiTitle--xxsmall').eq(1).contains('Dimensions').should('exist'); + cy.get('.first-division .euiFormLabel.euiFormRow__label').eq(0).contains('Aggregation'); + cy.get('[data-test-subj="comboBoxSearchInput"]').eq(0).click(); + aggregationValues.forEach(function (value){ + cy.get('.euiComboBoxOption__content').contains(value); + }); + }); + + it('Collapsible mode for Data Configuration panel', () => { + renderPieChart(); + cy.get('.euiResizablePanel.euiResizablePanel--middle').contains('Data Configurations'); + cy.get('.euiResizableButton.euiResizableButton--horizontal').eq(1).click(); + cy.get('[data-test-subj="panel-1-toggle"]').click(); + cy.get('[class*="euiResizableToggleButton-isCollapsed"]').eq(1).should('exist'); +describe('Renders Histogram chart', () => { + beforeEach(() => { + landOnEventVisualizations(); +}); + +it('Renders Histogram chart and save visualization', () => { + renderHistogramChart(); + cy.get('.euiFlexItem.euiFlexItem--flexGrowZero .euiButton__text').eq(2).click(); + cy.wait(delay); + saveVisualizationAndVerify(); + }); + + it('Delete Visualization for Histogram chart from list of saved Visualizations on Event analytics page', () =>{ + deleteVisualization(); + }) + + it('Renders Histogram chart, add value parameters and verify Reset button click is working', () => { + renderHistogramChart(); + cy.get('[data-test-subj="visualizeEditorResetButton"]').click(); + }); +}); +describe('Render Gauge Chart and verify if data gets render', () => { + it('Render gauge chart and verify by default no data gets render', () => { + renderGaugeChart(); + cy.get('.main-svg').contains('BeatsWest').should('not.exist'); + }); + + it('Render gauge chart and verify data gets render after click on update chart', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('.main-svg').contains('BeatsWest').should('exist'); + }); +}); + +describe('Render Gauge Chart and work with chart styles', () => { + it('Render gauge chart and change orientation to vertical', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('.euiButton__text').contains('Vertical').click(); + cy.get('.euiButton__text').contains('Preview').click(); + }); + + it('Render gauge chart and change title size then verify the update on chart', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(0).click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(0).type('30'); + cy.get('.euiButton__text').contains('Preview').click(); + }); + + it('Render gauge chart and change value size then verify the update on chart', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(1).click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(1).type('20'); + cy.get('.euiButton__text').contains('Preview').click(); + }); +}); + +describe('Render Gauge Chart and work with threshold', () => { + it('Render gauge chart and add threshold then verify by default the threshold is not seen', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('.euiButton__text').contains('+ Add threshold').click(); + cy.get('[data-test-subj="nameFieldText"]').type('Gauge Threshold'); + cy.get('[data-test-subj="valueFieldNumber"]').eq(2).type('50'); + cy.get('.euiButton__text').contains('Preview').click(); + cy.get('[data-unformatted="Gauge Threshold"]').should('not.be.visible'); + }); + + it('Render gauge chart and add threshold then verify the threshold label are seen after show threshold button enabled ', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('.euiButton__text').contains('+ Add threshold').click(); + cy.get('[data-test-subj="nameFieldText"]').type('Gauge Threshold'); + cy.get('[data-test-subj="valueFieldNumber"]').eq(2).type('50'); + cy.get('.euiSwitch__label').contains('Show threshold labels').click(); + cy.get('.euiButton__text').contains('Preview').click(); + cy.get('[data-unformatted="Gauge Threshold"]').should('be.visible'); + }); + + it('Render gauge chart and add threshold then verify the threshold marker are seen after show threshold button enabled ', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('.euiButton__text').contains('+ Add threshold').click(); + cy.get('[data-test-subj="nameFieldText"]').type('Gauge Threshold'); + cy.get('[data-test-subj="valueFieldNumber"]').eq(2).type('50'); + cy.get('.euiSwitch__label').contains('Show threshold markers').click(); + cy.get('.euiButton__text').contains('Preview').click(); + cy.get('path[style*="rgb(252, 5, 5)"]').eq(1).should('exist'); + cy.get('.bg-arc').find('path[style*="rgb(252, 5, 5)"]').should('have.length',4); + }); +}); + +describe('Render gauge chart and verify if reset works properly', () => { + it('Render gauge chart with all feild data then click on reset and verify reset works properly', () => { + renderGaugeChart(); + cy.get('.euiButton__text').contains('Update chart').click(); + cy.get('input[placeholder="Title"]').type('Gauge Chart'); + cy.get('textarea[placeholder="Description"]').type('Description For Gauge Chart'); + cy.get('.euiButton__text').contains('Vertical').click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(0).click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(0).type('30'); + cy.get('[data-test-subj="valueFieldNumber"]').eq(1).click(); + cy.get('[data-test-subj="valueFieldNumber"]').eq(1).type('20'); + cy.get('.euiButton__text').contains('+ Add threshold').click(); + cy.get('[data-test-subj="nameFieldText"]').type('Gauge Threshold'); + cy.get('[data-test-subj="valueFieldNumber"]').eq(2).type('50'); + cy.get('.euiSwitch__label').contains('Show threshold labels').click(); + cy.get('.euiSwitch__label').contains('Show threshold markers').click(); + cy.get('.euiButton__text').contains('Preview').click(); + cy.get('.euiButtonEmpty__text').contains('Reset').click(); + cy.get('input[placeholder="Title"]').should('not.have.value','Gauge Chart'); + cy.get('textarea[placeholder="Description"]').should('not.have.value','Description For Gauge Chart') + cy.get('[data-test-subj="valueFieldNumber"]').eq(0).should('have.value',''); + cy.get('[data-test-subj="valueFieldNumber"]').eq(1).should('have.value',''); + cy.get('button.euiSwitch__button[aria-checked="false"]').should('exist').should('have.length',3); + }); +}); diff --git a/dashboards-observability/.cypress/utils/event_constants.js b/dashboards-observability/.cypress/utils/event_constants.js index 4db8c146d..6d7ebbb05 100644 --- a/dashboards-observability/.cypress/utils/event_constants.js +++ b/dashboards-observability/.cypress/utils/event_constants.js @@ -33,7 +33,11 @@ export const TEST_QUERIES = [ dateRangeDOM: YEAR_TO_DATE_DOM_ID }, { - query:"source = opensearch_dashboards_sample_data_logs | where response='503' or response='404' | stats count() by span(timestamp,1d)", + query: "source = opensearch_dashboards_sample_data_logs | where response='503' or response='404' | stats count() by span(timestamp,1d)", + dateRangeDOM: YEAR_TO_DATE_DOM_ID + }, + { + query: 'source=opensearch_dashboards_sample_data_flights |where FlightDelayMin > 0 | stats sum(FlightDelayMin) as total_delay_min, count() as total_delayed by Carrier |eval avg_delay=total_delay_min / total_delayed | sort - avg_delay', dateRangeDOM: YEAR_TO_DATE_DOM_ID }, ]; @@ -44,6 +48,8 @@ export const SAVE_QUERY2 = 'Mock Flight count by destination'; export const SAVE_QUERY3 = 'Mock Flight count by destination save to panel'; export const SAVE_QUERY4 = 'Mock Flight peek'; +export const aggregationValues = ["COUNT", "SUM", "AVERAGE", "MAX", "MIN", "VAR_SAMP", "VAR_POP", "STDDEV_SAMP", "STDDEV_POP"]; + export const querySearch = (query, rangeSelected) => { cy.get('[data-test-subj="searchAutocompleteTextArea"]').type(query); cy.get('[data-test-subj="superDatePickerToggleQuickMenuButton"]').click(); @@ -80,21 +86,54 @@ export const landOnPanels = () => { cy.wait(delay); }; +const vis_name_sub_string = Math.floor(Math.random() * 100); +export 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(); +}; + +export const deleteVisualization = () => { + cy.get('a[href = "#/event_analytics"]').click(); + cy.get('.euiFlexGroup .euiFormControlLayout__childrenWrapper input') + .eq(0) + .type(`Test visualization` + vis_name_sub_string) + .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'); +}; + 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(); + querySearch(TEST_QUERIES[7].query, TEST_QUERIES[7].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('.euiIEFlexWrapFix').eq(1).contains('Treemap').should('exist'); + cy.get('#configPanel__treemap_options').contains('Tiling Algorithm').should('exist'); + cy.get('[data-test-subj = "comboBoxInput"]').eq(3).click(); + cy.get('button[name="Slice Dice"]').click(); }; export const renderPieChart = () => { @@ -104,11 +143,25 @@ export const renderPieChart = () => { cy.wait(delay); cy.get('#configPanel__panelOptions .euiFieldText').click().type('Pie chart'); cy.get('.euiFlexItem .euiFormRow [placeholder="Description"]').click().type('This is the description for Pie chart'); - cy.get('.euiIEFlexWrapFix').eq(1).contains('Value options').should('exist'); - cy.get('[data-test-subj="comboBoxInput"]').eq(1).click(); - cy.get('[name="count()"]').eq(0).click(); - cy.get('[data-test-subj="comboBoxToggleListButton"]').eq(0).click(); - cy.get('[data-test-subj="comboBoxInput"]').eq(2).click(); + cy.get('[aria-controls="configPanel__legend"]').contains('Legend').should('exist'); + cy.get('#configPanel__legend .euiTitle.euiTitle--xxsmall').eq(0).contains('Show Legend'); + cy.get('span[data-text="Show"]').contains('Show').should('exist'); + cy.get('#configPanel__legend .euiTitle.euiTitle--xxsmall').eq(1).contains('Position'); + cy.get('span[data-text="Right"]').contains('Right').should('exist'); + cy.get('#configPanel__legend .euiTitle.euiTitle--xxsmall').eq(2).contains('Legend Size'); + cy.get('[aria-controls="configPanel__chartStyles"]').contains('Chart Styles').should('exist'); + cy.get('#configPanel__chartStyles .euiTitle.euiTitle--xxsmall').eq(0).contains('Mode').click(); + cy.get('#configPanel__chartStyles .euiComboBox__inputWrap.euiComboBox__inputWrap--noWrap.euiComboBox__inputWrap-isClearable').click(); + cy.get('.euiComboBoxOption__content').contains('Donut').click(); + cy.get('#configPanel__chartStyles .euiTitle.euiTitle--xxsmall').eq(1).contains('Label Size'); + cy.get('#configPanel__chartStyles input[type="number"]').click().type('10'); + cy.get('#configPanel__chartStyles .euiTitle.euiTitle--xxsmall').eq(2).contains('Color Theme'); + cy.get('.euiSuperSelectControl').click(); + cy.get('.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('.visEditorSidebar__controls [data-test-subj="visualizeEditorRenderButton"]').contains('Preview').click(); + cy.get('.plot-container.plotly').should('exist'); }; export const renderDataConfig = () => { @@ -136,5 +189,29 @@ export const renderDataConfig = () => { export const renderLineChart = () => { landOnEventVisualizations(); querySearch(TEST_QUERIES[5].query, TEST_QUERIES[5].dateRangeDOM); + cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]') + .type('Line') + .type('{enter}'); +}; + +export const renderAddParent = () => { + cy.get(' [data-test-subj="addParentButton"] .euiButton__text').contains('+ Add Parent').click(); + cy.get('.first-division .euiFormLabel.euiFormRow__label').contains('Parent 1').should('exist'); + cy.get('p.euiComboBoxPlaceholder').eq(0).click({ force: true }); + cy.get('.euiComboBoxOption__content').eq(0).click(); + cy.get(' [data-test-subj="addParentButton"] .euiButton__text').contains('+ Add Parent').click(); + cy.get('.first-division .euiFormLabel.euiFormRow__label').contains('Parent 2').should('exist'); + cy.get('p.euiComboBoxPlaceholder').click({ force: true }); + cy.get('.euiComboBoxOption__content').eq(1).click(); + cy.get(' [data-test-subj="addParentButton"] .euiButton__text').contains('+ Add Parent').click(); + cy.get('.first-division .euiFormLabel.euiFormRow__label').contains('Parent 3').should('exist'); + cy.get('p.euiComboBoxPlaceholder').click({ force: true }); + cy.get('.euiComboBoxOption__content').eq(2).click(); cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Line').type('{enter}'); }; + +export const renderGaugeChart = () => { + landOnEventVisualizations(); + querySearch(TEST_QUERIES[1].query, TEST_QUERIES[1].dateRangeDOM); + cy.get('[data-test-subj="configPane__vizTypeSelector"] [data-test-subj="comboBoxInput"]').type('Gauge').type('{enter}'); +}; diff --git a/dashboards-observability/common/constants/explorer.ts b/dashboards-observability/common/constants/explorer.ts index 17612c44e..9199fc8cd 100644 --- a/dashboards-observability/common/constants/explorer.ts +++ b/dashboards-observability/common/constants/explorer.ts @@ -75,7 +75,7 @@ export const REDUX_EXPL_SLICE_FIELDS = 'fields'; export const REDUX_EXPL_SLICE_QUERY_TABS = 'queryTabs'; export const REDUX_EXPL_SLICE_VISUALIZATION = 'explorerVisualization'; export const REDUX_EXPL_SLICE_COUNT_DISTRIBUTION = 'countDistributionVisualization'; -export const PLOTLY_GAUGE_COLUMN_NUMBER = 5; +export const PLOTLY_GAUGE_COLUMN_NUMBER = 4; export const APP_ANALYTICS_TAB_ID_REGEX = /application-analytics-tab.+/; export const DEFAULT_AVAILABILITY_QUERY = 'stats count() by span( timestamp, 1h )'; export const ADD_BUTTON_TEXT = '+ Add color theme'; @@ -118,6 +118,8 @@ export const AGGREGATION_OPTIONS = [ }, ]; +// numeric fields type for metrics +export const numericalTypes = ['float', 'double', 'bigint', 'long', 'octet', 'short', 'byte', 'integer']; // Data table constants export const GRID_HEADER_COLUMN_MAX_WIDTH = '150px'; export const GRID_PAGE_RANGE_DISPLAY = 5; @@ -130,3 +132,22 @@ export const ROW_DENSITIES = [ ]; export const HEADER_HEIGHT = 35; + +// gauge chart default parameters +export interface DefaultGaugeChartParametersProps { + GaugeTitleSize: number, + DisplayDefaultGauges: number, + OrientationDefault: string, + TickLength: number, + LegendPlacement: string, + ThresholdsMaxLimit: number +}; + +export const DefaultGaugeChartParameters: DefaultGaugeChartParametersProps = { + GaugeTitleSize: 14, + DisplayDefaultGauges: 1, + OrientationDefault: 'h', + TickLength: 5, + LegendPlacement: 'center', + ThresholdsMaxLimit: 1 +} diff --git a/dashboards-observability/common/constants/shared.ts b/dashboards-observability/common/constants/shared.ts index 00b6b3f14..d4021c350 100644 --- a/dashboards-observability/common/constants/shared.ts +++ b/dashboards-observability/common/constants/shared.ts @@ -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, visChartTypes.TreeMap]; +export const ENABLED_VIS_TYPES = [visChartTypes.Bar, visChartTypes.HorizontalBar, visChartTypes.Line, visChartTypes.Pie, visChartTypes.HeatMap, visChartTypes.Text, visChartTypes.TreeMap, visChartTypes.Gauge, visChartTypes.Histogram]; //Live tail constants export const LIVE_OPTIONS = [ @@ -156,7 +156,9 @@ export interface DefaultChartStylesProps { FillOpacity: number, MarkerSize: number, ShowLegend: string, - LegendPosition: string + LegendPosition: string, + LabelAngle: number, + DefaultSortSectors: string, }; export const DefaultChartStyles: DefaultChartStylesProps = { @@ -166,7 +168,10 @@ export const DefaultChartStyles: DefaultChartStylesProps = { FillOpacity: 40, MarkerSize: 5, ShowLegend: 'show', - LegendPosition: 'v' + LegendPosition: 'v', + LabelAngle: 0, + DefaultSortSectors: 'largest_to_smallest', } export const FILLOPACITY_DIV_FACTOR = 200; + diff --git a/dashboards-observability/common/types/explorer.ts b/dashboards-observability/common/types/explorer.ts index 2204a6ab4..ade2c6db3 100644 --- a/dashboards-observability/common/types/explorer.ts +++ b/dashboards-observability/common/types/explorer.ts @@ -239,8 +239,12 @@ export interface ConfigListEntry { side: string; type: string; } +export interface HistogramConfigList { + bucketSize: string; + bucketOffset: string; +} export interface ConfigList { - dimensions?: ConfigListEntry[]; + dimensions?: ConfigListEntry[] | HistogramConfigList[]; metrics?: ConfigListEntry[]; } diff --git a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap index 3feb1f635..527aa9965 100644 --- a/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap +++ b/dashboards-observability/public/components/custom_panels/helpers/__tests__/__snapshots__/utils.test.tsx.snap @@ -88,26 +88,6 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "xaxis", - "name": "X-axis", - }, - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", - }, - ], - }, Object { "editor": [Function], "id": "legend", @@ -216,6 +196,12 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + }, Object { "component": [Function], "defaultState": 0, @@ -344,7 +330,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -449,26 +435,6 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "xaxis", - "name": "X-axis", - }, - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", - }, - ], - }, Object { "editor": [Function], "id": "legend", @@ -577,6 +543,12 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + }, Object { "component": [Function], "defaultState": 0, @@ -705,7 +677,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -733,7 +705,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` } layout={ Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -833,26 +805,6 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "xaxis", - "name": "X-axis", - }, - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", - }, - ], - }, Object { "editor": [Function], "id": "legend", @@ -961,6 +913,12 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + }, Object { "component": [Function], "defaultState": 0, @@ -1089,7 +1047,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1108,180 +1066,83 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` } } > - -
- - + className="euiText euiText--extraSmall lnsChart__empty" + data-test-subj="vizWorkspace__noData" + > + +
+ +
+ + + + + + +
+ +

+ + + No results found + + +

+
+ +
+ +
+ + @@ -1296,19 +1157,18 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "data": Object { "appData": Object {}, "defaultAxes": Object { - "xaxis": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], + "xaxis": Array [], "yaxis": Array [ Object { "label": "avg(FlightDelayMin)", "name": "avg(FlightDelayMin)", "type": "double", }, + Object { + "label": "Carrier", + "name": "Carrier", + "type": "keyword", + }, ], }, "indexFields": Object {}, @@ -1427,6 +1287,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "legendSize", + "name": "Legend Size", + "title": "Legend Size", + }, ], }, Object { @@ -1452,17 +1319,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "id": "lines", "name": "Lines", }, - Object { - "id": "bar", - "name": "Bars", - }, Object { "id": "markers", - "name": "Points", + "name": "Marker", }, Object { "id": "lines+markers", - "name": "Lines + Points", + "name": "Lines + Markers", }, ], }, @@ -1529,8 +1392,56 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "max": 40, }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + "title": "Label Size", + }, + Object { + "component": [Function], + "defaultState": 0, + "eleType": "slider", + "mapTo": "rotateLabels", + "name": "Rotate labels", + "props": Object { + "max": 90, + "min": -90, + "showTicks": true, + "ticks": Array [ + Object { + "label": "-90°", + "value": -90, + }, + Object { + "label": "-45°", + "value": -45, + }, + Object { + "label": "0°", + "value": 0, + }, + Object { + "label": "45°", + "value": 45, + }, + Object { + "label": "90°", + "value": 90, + }, + ], + }, + }, ], }, + Object { + "editor": [Function], + "id": "color-theme", + "mapTo": "colorTheme", + "name": "Color theme", + "schemas": Array [], + }, Object { "defaultState": Array [], "editor": [Function], @@ -1556,11 +1467,11 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` }, ], }, - "fullLabel": "Line", + "fullLabel": "Time series", "icon": [Function], "iconType": "visLine", "id": "line", - "label": "Line", + "label": "Time series", "name": "line", "selection": Object { "dataLoss": "nothing", @@ -1592,7 +1503,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1629,19 +1540,18 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "data": Object { "appData": Object {}, "defaultAxes": Object { - "xaxis": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], + "xaxis": Array [], "yaxis": Array [ Object { "label": "avg(FlightDelayMin)", "name": "avg(FlightDelayMin)", "type": "double", }, + Object { + "label": "Carrier", + "name": "Carrier", + "type": "keyword", + }, ], }, "indexFields": Object {}, @@ -1760,6 +1670,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "legendSize", + "name": "Legend Size", + "title": "Legend Size", + }, ], }, Object { @@ -1785,17 +1702,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "id": "lines", "name": "Lines", }, - Object { - "id": "bar", - "name": "Bars", - }, Object { "id": "markers", - "name": "Points", + "name": "Marker", }, Object { "id": "lines+markers", - "name": "Lines + Points", + "name": "Lines + Markers", }, ], }, @@ -1862,19 +1775,67 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "max": 40, }, }, - ], - }, - Object { - "defaultState": Array [], - "editor": [Function], - "id": "thresholds", - "mapTo": "thresholds", - "name": "Thresholds", - "schemas": Array [], - }, - ], - }, - Object { + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + "title": "Label Size", + }, + Object { + "component": [Function], + "defaultState": 0, + "eleType": "slider", + "mapTo": "rotateLabels", + "name": "Rotate labels", + "props": Object { + "max": 90, + "min": -90, + "showTicks": true, + "ticks": Array [ + Object { + "label": "-90°", + "value": -90, + }, + Object { + "label": "-45°", + "value": -45, + }, + Object { + "label": "0°", + "value": 0, + }, + Object { + "label": "45°", + "value": 45, + }, + Object { + "label": "90°", + "value": 90, + }, + ], + }, + }, + ], + }, + Object { + "editor": [Function], + "id": "color-theme", + "mapTo": "colorTheme", + "name": "Color theme", + "schemas": Array [], + }, + Object { + "defaultState": Array [], + "editor": [Function], + "id": "thresholds", + "mapTo": "thresholds", + "name": "Thresholds", + "schemas": Array [], + }, + ], + }, + Object { "content": Array [], "editor": [Function], "id": "style-panel", @@ -1889,11 +1850,11 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` }, ], }, - "fullLabel": "Line", + "fullLabel": "Time series", "icon": [Function], "iconType": "visLine", "id": "line", - "label": "Line", + "label": "Time series", "name": "line", "selection": Object { "dataLoss": "nothing", @@ -1925,7 +1886,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1984,7 +1945,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -2016,19 +1977,18 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "data": Object { "appData": Object {}, "defaultAxes": Object { - "xaxis": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], + "xaxis": Array [], "yaxis": Array [ Object { "label": "avg(FlightDelayMin)", "name": "avg(FlightDelayMin)", "type": "double", }, + Object { + "label": "Carrier", + "name": "Carrier", + "type": "keyword", + }, ], }, "indexFields": Object {}, @@ -2147,6 +2107,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "legendSize", + "name": "Legend Size", + "title": "Legend Size", + }, ], }, Object { @@ -2172,17 +2139,13 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "id": "lines", "name": "Lines", }, - Object { - "id": "bar", - "name": "Bars", - }, Object { "id": "markers", - "name": "Points", + "name": "Marker", }, Object { "id": "lines+markers", - "name": "Lines + Points", + "name": "Lines + Markers", }, ], }, @@ -2249,8 +2212,56 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "max": 40, }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + "title": "Label Size", + }, + Object { + "component": [Function], + "defaultState": 0, + "eleType": "slider", + "mapTo": "rotateLabels", + "name": "Rotate labels", + "props": Object { + "max": 90, + "min": -90, + "showTicks": true, + "ticks": Array [ + Object { + "label": "-90°", + "value": -90, + }, + Object { + "label": "-45°", + "value": -45, + }, + Object { + "label": "0°", + "value": 0, + }, + Object { + "label": "45°", + "value": 45, + }, + Object { + "label": "90°", + "value": 90, + }, + ], + }, + }, ], }, + Object { + "editor": [Function], + "id": "color-theme", + "mapTo": "colorTheme", + "name": "Color theme", + "schemas": Array [], + }, Object { "defaultState": Array [], "editor": [Function], @@ -2276,11 +2287,11 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` }, ], }, - "fullLabel": "Line", + "fullLabel": "Time series", "icon": [Function], "iconType": "visLine", "id": "line", - "label": "Line", + "label": "Time series", "name": "line", "selection": Object { "dataLoss": "nothing", @@ -2312,7 +2323,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -2343,226 +2354,83 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` } } > - -
- - + className="euiText euiText--extraSmall lnsChart__empty" + data-test-subj="vizWorkspace__noData" + > + +
+ +
+ + + + + + +
+ +

+ + + No results found + + +

+
+ +
+ +
+ + @@ -2762,7 +2630,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -2972,7 +2840,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3000,7 +2868,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` } layout={ Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3205,7 +3073,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3224,180 +3092,83 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` } } > - -
- - + className="euiText euiText--extraSmall lnsChart__empty" + data-test-subj="vizWorkspace__noData" + > + +
+ +
+ + + + + + +
+ +

+ + + No results found + + +

+
+ +
+ +
+ + @@ -3570,7 +3341,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3753,7 +3524,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3781,7 +3552,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` } layout={ Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3959,7 +3730,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -3978,160 +3749,83 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` } } > - -
- - + className="euiText euiText--extraSmall lnsChart__empty" + data-test-subj="vizWorkspace__noData" + > + +
+ +
+ + + + + + +
+ +

+ + + No results found + + +

+
+ +
+ +
+ + diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/app.scss b/dashboards-observability/public/components/event_analytics/explorer/visualizations/app.scss index 2f01e1b8e..ef67ba34b 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/app.scss +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/app.scss @@ -32,6 +32,35 @@ flex-grow: 1; } +.containerPanel { + padding: 0 16px; +} + +.dataConfigContainer { + height: 1242px; + overflow: auto; +} + +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +::-webkit-scrollbar-thumb { + background: #c2c2c2; +} + +.euiResizableToggleButton:not(:focus):not(:active):not(.euiResizableToggleButton-isVisible):not(.euiResizableToggleButton-isCollapsed) { + height: 24px; + width: 24px; + top: 0; + left: inherit; + box-shadow: none; +} + .lensChartIcon__subdued { fill: $euiTextSubduedColor; diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap index 435c32d43..1cac93734 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/__tests__/__snapshots__/config_panel.test.tsx.snap @@ -213,26 +213,6 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "xaxis", - "name": "X-axis", - }, - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", - }, - ], - }, Object { "editor": [Function], "id": "legend", @@ -341,6 +321,12 @@ exports[`Config panel component Renders config panel with visualization data 1`] ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + }, Object { "component": [Function], "defaultState": 0, @@ -469,7 +455,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -517,7 +503,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] async={false} compressed={false} fullWidth={true} - isClearable={true} + isClearable={false} onChange={[Function]} options={ Array [ @@ -534,26 +520,6 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "dataConfig", "name": "Data", "sections": Array [ - Object { - "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "xaxis", - "name": "X-axis", - }, - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", - }, - ], - }, Object { "editor": [Function], "id": "legend", @@ -662,6 +628,12 @@ exports[`Config panel component Renders config panel with visualization data 1`] ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + }, Object { "component": [Function], "defaultState": 0, @@ -790,7 +762,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -870,6 +842,13 @@ exports[`Config panel component Renders config panel with visualization data 1`] ], }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "legendSize", + "name": "Legend Size", + "title": "Legend Size", + }, ], }, Object { @@ -895,17 +874,13 @@ exports[`Config panel component Renders config panel with visualization data 1`] "id": "lines", "name": "Lines", }, - Object { - "id": "bar", - "name": "Bars", - }, Object { "id": "markers", - "name": "Points", + "name": "Marker", }, Object { "id": "lines+markers", - "name": "Lines + Points", + "name": "Lines + Markers", }, ], }, @@ -972,8 +947,56 @@ exports[`Config panel component Renders config panel with visualization data 1`] "max": 40, }, }, + Object { + "component": [Function], + "eleType": "input", + "mapTo": "labelSize", + "name": "Label Size", + "title": "Label Size", + }, + Object { + "component": [Function], + "defaultState": 0, + "eleType": "slider", + "mapTo": "rotateLabels", + "name": "Rotate labels", + "props": Object { + "max": 90, + "min": -90, + "showTicks": true, + "ticks": Array [ + Object { + "label": "-90°", + "value": -90, + }, + Object { + "label": "-45°", + "value": -45, + }, + Object { + "label": "0°", + "value": 0, + }, + Object { + "label": "45°", + "value": 45, + }, + Object { + "label": "90°", + "value": 90, + }, + ], + }, + }, ], }, + Object { + "editor": [Function], + "id": "color-theme", + "mapTo": "colorTheme", + "name": "Color theme", + "schemas": Array [], + }, Object { "defaultState": Array [], "editor": [Function], @@ -999,11 +1022,11 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, ], }, - "fullLabel": "Line", + "fullLabel": "Time series", "icon": [Function], "iconType": "visLine", "id": "line", - "label": "Line", + "label": "Time series", "name": "line", "selection": Object { "dataLoss": "nothing", @@ -1035,7 +1058,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1238,7 +1261,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1277,6 +1300,37 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "dataConfig", "name": "Data", "sections": Array [ + Object { + "editor": [Function], + "id": "legend", + "mapTo": "legend", + "name": "Legend", + "schemas": Array [ + Object { + "component": null, + "mapTo": "showLegend", + "name": "Show Colorscale", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, + }, + ], + }, Object { "editor": [Function], "id": "chart_styles", @@ -1579,7 +1633,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] "responsive": true, }, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1652,7 +1706,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] "#BD6F26", "#4C636F", ], - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -1692,6 +1746,37 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "dataConfig", "name": "Data", "sections": Array [ + Object { + "editor": [Function], + "id": "legend", + "mapTo": "legend", + "name": "Legend", + "schemas": Array [ + Object { + "component": null, + "mapTo": "showLegend", + "name": "Show Colorscale", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, + }, + ], + }, Object { "editor": [Function], "id": "treemap_options", @@ -1740,6 +1825,30 @@ exports[`Config panel component Renders config panel with visualization data 1`] "isClearable": false, }, }, + Object { + "component": [Function], + "eleType": "buttons", + "mapTo": "sort_sectors", + "name": "Sort Sectors", + "props": Object { + "defaultSelections": Array [ + Object { + "id": undefined, + "name": "Largest to Smallest", + }, + ], + "options": Array [ + Object { + "id": "largest_to_smallest", + "name": "Largest to Smallest", + }, + Object { + "id": "random", + "name": "Random", + }, + ], + }, + }, ], }, Object { @@ -2023,7 +2132,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -2039,16 +2148,8 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, }, }, - ] - } - placeholder="Select a chart" - renderOption={[Function]} - selectedOptions={ - Array [ Object { - "barWidth": 0.97, "category": "Visualizations", - "categoryAxis": "xaxis", "component": [Function], "editorConfig": Object { "panelTabs": Array [ @@ -2060,81 +2161,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] "sections": Array [ Object { "editor": [Function], - "id": "value_options", - "mapTo": "valueOptions", - "name": "Value options", - "schemas": Array [ - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "xaxis", - "name": "X-axis", - }, - Object { - "component": null, - "isSingleSelection": false, - "mapTo": "yaxis", - "name": "Y-axis", - }, - ], - }, - Object { - "editor": [Function], - "id": "legend", - "mapTo": "legend", - "name": "Legend", - "schemas": Array [ - Object { - "component": null, - "mapTo": "showLegend", - "name": "Show Legend", - "props": Object { - "defaultSelections": Array [ - Object { - "id": "show", - "name": "Show", - }, - ], - "options": Array [ - Object { - "id": "show", - "name": "Show", - }, - Object { - "id": "hidden", - "name": "Hidden", - }, - ], - }, - }, - Object { - "component": null, - "mapTo": "position", - "name": "Position", - "props": Object { - "defaultSelections": Array [ - Object { - "id": "v", - "name": "Right", - }, - ], - "options": Array [ - Object { - "id": "v", - "name": "Right", - }, - Object { - "id": "h", - "name": "Bottom", - }, - ], - }, - }, - ], - }, - Object { - "editor": [Function], - "id": "chart_styles", + "id": "chart-styles", "mapTo": "chartStyles", "name": "Chart styles", "schemas": Array [ @@ -2146,11 +2173,15 @@ exports[`Config panel component Renders config panel with visualization data 1`] "props": Object { "defaultSelections": Array [ Object { - "id": "v", - "name": "Vertical", + "id": "auto", + "name": "Auto", }, ], "options": Array [ + Object { + "id": "auto", + "name": "Auto", + }, Object { "id": "v", "name": "Vertical", @@ -2165,86 +2196,138 @@ exports[`Config panel component Renders config panel with visualization data 1`] Object { "component": [Function], "eleType": "buttons", - "mapTo": "mode", - "name": "Mode", + "mapTo": "legendPlacement", + "name": "Legend Placement", "props": Object { "defaultSelections": Array [ Object { - "id": "group", - "name": "Group", + "id": "center", + "name": "Center", }, ], "options": Array [ Object { - "id": "group", - "name": "Group", + "id": "center", + "name": "Center", }, Object { - "id": "stack", - "name": "Stack", + "id": "right", + "name": "Right", + }, + Object { + "id": "left", + "name": "Left", }, ], }, }, Object { "component": [Function], - "defaultState": 0, - "eleType": "slider", - "mapTo": "rotateBarLabels", - "name": "Rotate bar labels", - "props": Object { - "max": 90, - "min": -90, - "showTicks": true, - "ticks": Array [ - Object { - "label": "-90°", - "value": -90, - }, - Object { - "label": "-45°", - "value": -45, - }, - Object { - "label": "0°", - "value": 0, - }, - Object { - "label": "45°", - "value": 45, - }, - Object { - "label": "90°", - "value": 90, - }, - ], - }, + "eleType": "input", + "mapTo": "titleSize", + "name": "Title Size", + "title": "Title Size", }, Object { "component": [Function], - "defaultState": 0.7, - "eleType": "slider", - "mapTo": "groupWidth", - "name": "Group width", - "props": Object { - "max": 1, - "step": 0.01, - }, + "eleType": "input", + "mapTo": "valueSize", + "name": "Value Size", + "title": "Value Size", }, Object { "component": [Function], - "defaultState": 0.97, - "eleType": "slider", - "mapTo": "barWidth", - "name": "Bar width", - "props": Object { - "max": 1, - "step": 0.01, - }, + "currentValue": false, + "eleType": "switchButton", + "mapTo": "showThresholdLabels", + "name": "Show threshold labels", + "title": "Show threshold labels", }, Object { "component": [Function], - "defaultState": 1, + "currentValue": true, + "eleType": "switchButton", + "mapTo": "showThresholdMarkers", + "name": "Show threshold markers", + "title": "Show threshold markers", + }, + ], + }, + Object { + "defaultState": Array [], + "editor": [Function], + "id": "thresholds", + "mapTo": "thresholds", + "name": "Thresholds", + "props": Object { + "maxLimit": 1, + }, + "schemas": Array [], + }, + ], + }, + Object { + "content": Array [], + "editor": [Function], + "id": "style-panel", + "mapTo": "layoutConfig", + "name": "Layout", + }, + ], + }, + "fullLabel": "Gauge", + "icon": [Function], + "iconType": "visGauge", + "id": "gauge", + "label": "Gauge", + "name": "Gauge", + "selection": Object { + "dataLoss": "nothing", + }, + "type": "indicator", + "valueSeries": "yaxis", + "visConfig": Object { + "config": Object { + "displaylogo": false, + "responsive": true, + }, + "layout": Object { + "height": 1180, + "legend": Object { + "orientation": "v", + "traceorder": "normal", + }, + "margin": Object { + "b": 30, + "l": 60, + "pad": 0, + "r": 30, + "t": 50, + }, + "showlegend": true, + }, + }, + }, + Object { + "category": "Visualizations", + "component": [Function], + "editorConfig": Object { + "panelTabs": Array [ + Object { + "editor": [Function], + "id": "data-panel", + "mapTo": "dataConfig", + "name": "Data", + "sections": Array [ + Object { + "editor": [Function], + "id": "chart-styles", + "mapTo": "chartStyles", + "name": "Chart styles", + "schemas": Array [ + Object { + "component": [Function], + "defaultState": 2, "eleType": "slider", "mapTo": "lineWidth", "name": "Line width", @@ -2254,7 +2337,7 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, Object { "component": [Function], - "defaultState": 80, + "defaultState": 40, "eleType": "slider", "mapTo": "fillOpacity", "name": "Fill Opacity", @@ -2271,6 +2354,60 @@ exports[`Config panel component Renders config panel with visualization data 1`] "name": "Color Theme", "schemas": Array [], }, + Object { + "editor": [Function], + "id": "legend", + "mapTo": "legend", + "name": "Legend", + "schemas": Array [ + Object { + "component": null, + "mapTo": "showLegend", + "name": "Show Legend", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "show", + "name": "Show", + }, + ], + "options": Array [ + Object { + "id": "show", + "name": "Show", + }, + Object { + "id": "hidden", + "name": "Hidden", + }, + ], + }, + }, + Object { + "component": null, + "mapTo": "position", + "name": "Position", + "props": Object { + "defaultSelections": Array [ + Object { + "id": "v", + "name": "Right", + }, + ], + "options": Array [ + Object { + "id": "v", + "name": "Right", + }, + Object { + "id": "h", + "name": "Bottom", + }, + ], + }, + }, + ], + }, ], }, Object { @@ -2280,41 +2417,25 @@ exports[`Config panel component Renders config panel with visualization data 1`] "mapTo": "layoutConfig", "name": "Layout", }, - Object { - "editor": [Function], - "id": "availability-panel", - "mapTo": "availabilityConfig", - "name": "Availability", - }, ], }, - "fillOpacity": 80, - "fullLabel": "Bar", - "groupWidth": 0.7, - "icon": [Function], - "iconType": "visBarVerticalStacked", - "id": "bar", - "label": "Bar", - "labelAngle": 0, - "legendPosition": "v", - "lineWidth": 1, - "mode": "group", - "name": "bar", - "orientation": "v", + "fullLabel": "Histogram", + "iconType": "visArea", + "id": "histogram", + "label": "Histogram", + "name": "histogram", "selection": Object { "dataLoss": "nothing", }, - "seriesAxis": "yaxis", - "showLegend": "show", - "type": "bar", + "type": "histogram", + "valueSeries": "yaxis", "visConfig": Object { "config": Object { "displaylogo": false, "responsive": true, }, - "isUniColor": false, "layout": Object { - "height": 500, + "height": 1180, "legend": Object { "orientation": "v", "traceorder": "normal", @@ -2332,2504 +2453,326 @@ exports[`Config panel component Renders config panel with visualization data 1`] }, ] } - singleSelection={true} - sortMatchesBy="none" - > -
- - -
-
-
- - - - - - - Bar - - - - - - - - - - - - -
- -
-
- -
- -
- - - - - - - - -
-
-
-
- - -
- - -
- -
- - -
- -
- , - "id": "data-panel", - "name": "Data", - } - } - tabs={ + Object { + "editor": [Function], + "id": "color-theme", + "mapTo": "colorTheme", + "name": "Color Theme", + "schemas": Array [], + }, + ], + }, + Object { + "content": Array [], + "editor": [Function], + "id": "style-panel", + "mapTo": "layoutConfig", + "name": "Layout", + }, + Object { + "editor": [Function], + "id": "availability-panel", + "mapTo": "availabilityConfig", + "name": "Availability", + }, + ], + }, + "fillOpacity": 80, + "fullLabel": "Bar", + "groupWidth": 0.7, + "icon": [Function], + "iconType": "visBarVerticalStacked", + "id": "bar", + "label": "Bar", + "labelAngle": 0, + "legendPosition": "v", + "lineWidth": 1, + "mode": "group", + "name": "bar", + "orientation": "v", + "selection": Object { + "dataLoss": "nothing", + }, + "seriesAxis": "yaxis", + "showLegend": "show", + "type": "bar", + "visConfig": Object { + "config": Object { + "displaylogo": false, + "responsive": true, + }, + "isUniColor": false, + "layout": Object { + "height": 1180, + "legend": Object { + "orientation": "v", + "traceorder": "normal", + }, + "margin": Object { + "b": 30, + "l": 60, + "pad": 0, + "r": 30, + "t": 50, + }, + "showlegend": true, + }, + }, + }, + ] + } + singleSelection={true} + sortMatchesBy="none" + > +
+ + +
+
+
+ , - "id": "data-panel", - "name": "Data", - }, - Object { - "content": , - "id": "style-panel", - "name": "Layout", - }, - Object { - "content": + + + + + + Bar + + + + + + + + + + + + , - "id": "availability-panel", - "name": "Availability", - }, - ] - } - > -
- -
- - - - - - - +
+
+ +
+ - - + + +
+
- -
- + + +
+ + +
+ +
+ + +
+ +
+ -
- -
- -
-
- - -
-
- -
-
- -
-
- -
- -
-
- - - -
-
- - -
-
- - - - -
-
-
-
- -
- Name your visualization. -
-
-
-
-
- -
-
- - - -
-
- - -