diff --git a/dashboards-observability/common/query_manager/ast/expression/group_by.ts b/dashboards-observability/common/query_manager/ast/expression/group_by.ts index ce6d8ffef..1d0a1ad07 100644 --- a/dashboards-observability/common/query_manager/ast/expression/group_by.ts +++ b/dashboards-observability/common/query_manager/ast/expression/group_by.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { isEmpty } from 'lodash'; import { PPLNode } from '../node'; import { Field } from './field'; @@ -24,8 +25,11 @@ export class GroupBy extends PPLNode { } toString(): string { - return `by ${this.span ? `${this.span.toString()}${this.fields.length > 0 ? ', ' : ''}` : ''}${this.fields - .map((field) => field.toString()) - .join(', ')}`; + return ( + `${!isEmpty(this.fields) || !isEmpty(this.span) ? 'by ' : ''}` + + `${ + !isEmpty(this.span) ? `${this.span.toString()}${this.fields.length > 0 ? ', ' : ''}` : '' + }${this.fields.map((field) => field.toString()).join(', ')}` + ); } } diff --git a/dashboards-observability/common/query_manager/utils/index.ts b/dashboards-observability/common/query_manager/utils/index.ts index b8644f050..d93983382 100644 --- a/dashboards-observability/common/query_manager/utils/index.ts +++ b/dashboards-observability/common/query_manager/utils/index.ts @@ -5,6 +5,7 @@ import { CUSTOM_LABEL } from '../../../common/constants/explorer'; import { AggregationConfigurations, PreviouslyParsedStaleStats } from '../ast/types'; +import { removeBacktick } from '../../../common/utils'; export const composeAggregations = ( aggConfig: AggregationConfigurations, @@ -23,7 +24,7 @@ export const composeAggregations = ( group_fields: [ ...(aggConfig.dimensions || []), ...(aggConfig.breakdowns || []), - ].map((dimension) => ({ name: dimension.name })), + ].map((dimension) => ({ name: `\`${removeBacktick(dimension.name)}\`` })), ...(aggConfig.span && JSON.stringify(aggConfig?.span) !== '{}' && { span: composeSpan(aggConfig.span) }), }, diff --git a/dashboards-observability/common/utils/index.ts b/dashboards-observability/common/utils/index.ts index 6999e7cd3..8ec98b14f 100644 --- a/dashboards-observability/common/utils/index.ts +++ b/dashboards-observability/common/utils/index.ts @@ -3,5 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -export { getIndexPatternFromRawQuery, preprocessQuery, buildQuery, composeFinalQuery } from './query_utils'; +export { + getIndexPatternFromRawQuery, + preprocessQuery, + buildQuery, + composeFinalQuery, + removeBacktick, +} from './query_utils'; export { uiSettingsService } from './settings_service'; diff --git a/dashboards-observability/common/utils/query_utils.ts b/dashboards-observability/common/utils/query_utils.ts index dddfdf236..8b1c7d22d 100644 --- a/dashboards-observability/common/utils/query_utils.ts +++ b/dashboards-observability/common/utils/query_utils.ts @@ -127,3 +127,8 @@ export const composeFinalQuery = ( filteredPattern }); }; + +export const removeBacktick = (stringContainsBacktick: string) => { + if (!stringContainsBacktick) return ''; + return stringContainsBacktick.replace(/`/g, ''); +}; 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 1d6c90187..4d71b9e61 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 @@ -1417,10 +1417,10 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "orientation": "v", "type": "bar", "x": Array [ - ",BeatsWest", - ",Logstash Airways", - ",OpenSearch Dashboards Airlines", - ",OpenSearch-Air", + "BeatsWest", + "Logstash Airways", + "OpenSearch Dashboards Airlines", + "OpenSearch-Air", ], "y": Array [ undefined, @@ -1500,10 +1500,10 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "orientation": "v", "type": "bar", "x": Array [ - ",BeatsWest", - ",Logstash Airways", - ",OpenSearch Dashboards Airlines", - ",OpenSearch-Air", + "BeatsWest", + "Logstash Airways", + "OpenSearch Dashboards Airlines", + "OpenSearch-Air", ], "y": Array [ undefined, @@ -3193,83 +3193,201 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` } } > - -
- -
- -
- - - - - - -
- -

- - - No results found - - -

-
- -
- -
- - + id="explorerPlotComponent" + style={ + Object { + "height": "100%", + "width": "100%", + } + } + /> + + @@ -4699,10 +4817,10 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` undefined, ], "y": Array [ - ",", - ",", - ",", - ",", + "", + "", + "", + "", ], }, ] @@ -4782,10 +4900,10 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` undefined, ], "y": Array [ - ",", - ",", - ",", - ",", + "", + "", + "", + "", ], }, ] diff --git a/dashboards-observability/public/components/event_analytics/explorer/explorer.tsx b/dashboards-observability/public/components/event_analytics/explorer/explorer.tsx index bc8965ea6..f56f98b65 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/explorer.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/explorer.tsx @@ -1088,31 +1088,6 @@ export const Explorer = ({ ); }; - const getSpanValue = (groupByToken: GroupByChunk) => { - const timeUnitValue = TIME_INTERVAL_OPTIONS.find( - (time_unit) => time_unit.value === groupByToken?.span?.span_expression.time_unit - )?.text; - return groupByToken?.span !== null - ? { - time_field: [ - { - name: groupByToken?.span.span_expression.field, - type: 'timestamp', - label: groupByToken?.span.span_expression.field, - }, - ], - unit: [ - { - text: timeUnitValue, - value: groupByToken?.span.span_expression.time_unit, - label: timeUnitValue, - }, - ], - interval: groupByToken?.span.span_expression.literal_value, - } - : undefined; - }; - const handleQuerySearch = useCallback( async (availability?: boolean) => { // clear previous selected timestamp when index pattern changes @@ -1270,7 +1245,6 @@ export const Explorer = ({ description: vizDescription, subType: subType, unitsOfMeasure: metricMeasure, - // selectedLabels: metricLabel }) .then((res: any) => { setToast( @@ -1307,7 +1281,6 @@ export const Explorer = ({ description: vizDescription, subType: subType, unitsOfMeasure: metricMeasure, - // selectedLabels: metricLabel }) .then((res: any) => { batch(() => { diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx index 6a7d3c735..d7d13710c 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_config_panel_fields.tsx @@ -26,11 +26,13 @@ import { ConfigListEntry, DataConfigPanelFieldProps, } from '../../../../../../../../common/types/explorer'; +import { removeBacktick } from '../../../../../../../../common/utils' const HIDE_ADD_BUTTON_VIZ_TYPES = [ VIS_CHART_TYPES.HeatMap, VIS_CHART_TYPES.Line, VIS_CHART_TYPES.Scatter, + VIS_CHART_TYPES.Pie ]; export const DataConfigPanelFields = ({ @@ -114,7 +116,7 @@ export const DataConfigPanelFields = ({ tabIndex={0} onClick={() => handleServiceEdit(index, sectionName, false)} > - {obj[CUSTOM_LABEL] || `${isAggregation ? obj.aggregation : ''} ${obj.label}`} + {removeBacktick(obj[CUSTOM_LABEL] || `${isAggregation ? obj.aggregation : ''} ${obj.label}`)} {isAggregation diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx index 9afcb69e6..535f76946 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/data_configurations_panel.tsx @@ -19,7 +19,7 @@ import { EuiTitle, htmlIdGenerator, } from '@elastic/eui'; -import { filter, isEmpty } from 'lodash'; +import { filter, isEmpty, isEqual } from 'lodash'; import { AGGREGATIONS, AGGREGATION_OPTIONS, @@ -283,7 +283,7 @@ export const DataConfigPanelItem = ({ ...configList, }, }); - + console.log('newQueryString: ', newQueryString); handleQueryChange(newQueryString); getVisualizations({ query: nextQueryState[FINAL_QUERY], @@ -315,6 +315,13 @@ export const DataConfigPanelItem = ({ filter(options, (i: IField) => i.type !== TIMESTAMP); const getOptionsAvailable = (sectionName: string) => { + if ( + (visualizations.vis.name === VIS_CHART_TYPES.Line || + visualizations.vis.name === VIS_CHART_TYPES.Scatter) && + isEqual(sectionName, GROUPBY) + ) + return filter(fieldOptionList, (i) => i.type === TIMESTAMP); + if ( sectionName === AGGREGATIONS || sectionName === BREAKDOWNS || @@ -322,11 +329,6 @@ export const DataConfigPanelItem = ({ isTimeStampSelected ) return fieldOptionList; - if ( - visualizations.vis.name === VIS_CHART_TYPES.Line || - visualizations.vis.name === VIS_CHART_TYPES.Scatter - ) - return filter(fieldOptionList, (i) => i.type === TIMESTAMP); return getTimeStampFilteredFields(fieldOptionList); }; @@ -580,6 +582,7 @@ export const DataConfigPanelItem = ({ iconType="play" onClick={() => updateChart()} size="s" + isDisabled={isEmpty(configList[AGGREGATIONS])} > Update chart diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap index 8511fbe6f..f409c4a8d 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/__tests__/__snapshots__/shared_components.test.tsx.snap @@ -72,12 +72,12 @@ exports[`Shared components Renders empty placeholder component 1`] = `

- No results found + No data found

diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/empty_placeholder.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/empty_placeholder.tsx index 54e9f1cb6..56b8886fe 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/empty_placeholder.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/empty_placeholder.tsx @@ -20,7 +20,7 @@ export const EmptyPlaceholder = (props: { icon: string }) => (

- +

diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/index.ts b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/index.ts index dfbd82f35..118494bbd 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/index.ts +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/index.ts @@ -4,5 +4,5 @@ */ export * from './empty_placeholder'; -export { ToolbarPopoverProps, ToolbarPopover } from './toolbar_popover'; export { ToolbarButtonProps, ToolbarButton } from './toolbar_button'; +export { VisCanvassPlaceholder } from './vis_canvass_placeholder' diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/vis_canvass_placeholder.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/vis_canvass_placeholder.tsx new file mode 100644 index 000000000..5ebede43e --- /dev/null +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/shared_components/vis_canvass_placeholder.tsx @@ -0,0 +1,26 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { EuiIcon, EuiText, EuiSpacer } from '@elastic/eui'; +import './empty_placeholder.scss'; + +export const VisCanvassPlaceholder = (props: { message: string; icon: string }) => ( + <> + + + +

+ { props.message } +

+
+ +); diff --git a/dashboards-observability/public/components/event_analytics/utils/utils.tsx b/dashboards-observability/public/components/event_analytics/utils/utils.tsx index 342d58af7..db80aa9a5 100644 --- a/dashboards-observability/public/components/event_analytics/utils/utils.tsx +++ b/dashboards-observability/public/components/event_analytics/utils/utils.tsx @@ -5,7 +5,7 @@ */ import dateMath from '@elastic/datemath'; -import { uniqueId } from 'lodash'; +import { uniqueId, isEmpty } from 'lodash'; import moment from 'moment'; import React from 'react'; import { HttpStart } from '../../../../../../src/core/public'; @@ -408,7 +408,7 @@ export const getDefaultVisConfig = (statsToken: statsChunk) => { return { [GROUPBY]: [], [AGGREGATIONS]: [], - [BREAKDOWNS]: [] + [BREAKDOWNS]: [], }; } @@ -435,23 +435,23 @@ const getSpanValue = (groupByToken: GroupByChunk) => { const timeUnitValue = TIME_INTERVAL_OPTIONS.find( (time_unit) => time_unit.value === groupByToken?.span?.span_expression.time_unit )?.text; - return groupByToken?.span !== null + return !isEmpty(groupByToken?.span) ? { time_field: [ { - name: groupByToken?.span.span_expression.field, + name: groupByToken?.span?.span_expression?.field, type: 'timestamp', - label: groupByToken?.span.span_expression.field, + label: groupByToken?.span?.span_expression?.field, }, ], unit: [ { text: timeUnitValue, - value: groupByToken?.span.span_expression.time_unit, + value: groupByToken?.span?.span_expression?.time_unit, label: timeUnitValue, }, ], - interval: groupByToken?.span.span_expression.literal_value, + interval: groupByToken?.span?.span_expression?.literal_value, } : undefined; }; diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/bar.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/bar.test.tsx.snap index d8163e362..bbbb71931 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/bar.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/bar.test.tsx.snap @@ -529,112 +529,75 @@ exports[`Veritcal Bar component Renders veritcal bar component 1`] = ` } } > - -
- - + className="euiText euiText--extraSmall lnsChart__empty" + data-test-subj="vizWorkspace__noData" + > + +
+ +
+ + + + + + +
+ +

+ Missing aggregations +

+
+ +
+ +
+ + `; diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/gauge.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/gauge.test.tsx.snap index 742cbbc53..70e513288 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/gauge.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/gauge.test.tsx.snap @@ -445,12 +445,12 @@ exports[`Gauge component Renders gauge component 1`] = `

- No results found + No data found

diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/heatmap.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/heatmap.test.tsx.snap index 755b6a4da..967f3492e 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/heatmap.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/heatmap.test.tsx.snap @@ -529,8 +529,9 @@ exports[`Heatmap component Renders heatmap component 1`] = ` } } > -

- - - No results found - - + Invalid data, heatmap can only have exact 2 dimensions and 1 series

@@ -605,6 +598,6 @@ exports[`Heatmap component Renders heatmap component 1`] = `
-
+ `; diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/horizontal_bar.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/horizontal_bar.test.tsx.snap index 23b32e4c2..c8115cee2 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/horizontal_bar.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/horizontal_bar.test.tsx.snap @@ -529,112 +529,75 @@ exports[`Horizontal bar component Renders horizontal bar component 1`] = ` } } > - -
- - + className="euiText euiText--extraSmall lnsChart__empty" + data-test-subj="vizWorkspace__noData" + > + +
+ +
+ + + + + + +
+ +

+ Missing aggregations +

+
+ +
+ +
+ + `; 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 c054c7fe5..9694c40d7 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 @@ -529,8 +529,9 @@ exports[`Line component Renders line component 1`] = ` } } > -

- - - No results found - - + Missing mandatory series

@@ -605,6 +598,6 @@ exports[`Line component Renders line component 1`] = ` - + `; diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/metrics.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/metrics.test.tsx.snap index 9a2ba7cce..c001a02af 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/metrics.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/metrics.test.tsx.snap @@ -569,12 +569,12 @@ exports[`Metrics component Renders Metrics component 1`] = `

- No results found + No data found

diff --git a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/pie.test.tsx.snap b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/pie.test.tsx.snap index 6d12adee6..4bcc7e430 100644 --- a/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/pie.test.tsx.snap +++ b/dashboards-observability/public/components/visualizations/charts/__tests__/__snapshots__/pie.test.tsx.snap @@ -590,12 +590,12 @@ exports[`Pie component Renders pie component 1`] = `

- No results found + No data found

diff --git a/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx b/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx index 86ca4769b..4a2e37ea2 100644 --- a/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx +++ b/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx @@ -23,7 +23,7 @@ import { import { IVisualizationContainerProps } from '../../../../../common/types/explorer'; 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 { EmptyPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components/empty_placeholder'; +import { VisCanvassPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components'; import { hexToRgb } from '../../../event_analytics/utils/utils'; import { Plt } from '../../plotly/plot'; import { transformPreprocessedDataToTraces, preprocessJsonData } from '../shared/common'; @@ -97,13 +97,8 @@ export const Bar = ({ visualizations, layout, config }: any) => { const plotlyColorway = queriedVizData[fields[lastIndex].name].length < 16 ? PLOTLY_COLOR : [LONG_CHART_COLOR]; - if ( - isEmpty(queriedVizData) || - !Array.isArray(dimensions) || - !Array.isArray(series) || - (breakdowns && !Array.isArray(breakdowns)) - ) - return ; + if (isEmpty(series)) + return ; const addStylesToTraces = (traces, traceStyles) => { const { barOrientation, fillOpacity, tooltipMode, tooltipText, lineWidth } = traceStyles; 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 dfa40da13..34f673282 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 @@ -27,20 +27,15 @@ const doubleValueGetter = (params) => { return params.data[params.column.colId]; }; -export const DataTable = ({ visualizations, layout, config }: any) => { +export const DataTable = ({ visualizations }: any) => { const { data: { - defaultAxes, - indexFields, - query, rawVizData: { - data: queriedVizData, - jsonData, - metadata: { fields = [] }, - }, + jsonData = [], + metadata: { fields = [] } = {}, + } = {}, userConfigs: { dataConfig: { chartStyles = {} } = {} } = {}, - } = {}, - vis: visMetaData, + } = {} }: IVisualizationContainerProps = visualizations; const enablePagination = diff --git a/dashboards-observability/public/components/visualizations/charts/lines/line.tsx b/dashboards-observability/public/components/visualizations/charts/lines/line.tsx index d669c60ed..5aa31552e 100644 --- a/dashboards-observability/public/components/visualizations/charts/lines/line.tsx +++ b/dashboards-observability/public/components/visualizations/charts/lines/line.tsx @@ -17,7 +17,7 @@ import { IVisualizationContainerProps } from '../../../../../common/types/explor import { hexToRgb } from '../../../../components/event_analytics/utils/utils'; 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 { EmptyPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components/empty_placeholder'; +import { VisCanvassPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components'; import { Plt } from '../../plotly/plot'; import { transformPreprocessedDataToTraces, preprocessJsonData } from '../shared/common'; @@ -87,7 +87,7 @@ export const Line = ({ visualizations, layout, config }: any) => { const timestampField = find(fields, (field) => field.type === 'timestamp'); let xaxis = [timestampField]; - if (!timestampField || isEmpty(series)) return ; + if (isEmpty(series)) return ; const addStylesToTraces = (traces, traceStyles) => { const { fillOpacity, tooltipMode, tooltipText, lineWidth, lineShape, markerSize } = traceStyles; diff --git a/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx b/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx index 7bc51e497..ad08ac26f 100644 --- a/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx +++ b/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx @@ -4,7 +4,7 @@ */ import React, { useMemo } from 'react'; import { colorPalette } from '@elastic/eui'; -import { has, isEmpty, uniq } from 'lodash'; +import { forEach, has, isEmpty, isEqual, uniq } from 'lodash'; import Plotly from 'plotly.js-dist'; import { HEATMAP_PALETTE_COLOR, @@ -18,17 +18,16 @@ import { getPropName, } from '../../../../components/event_analytics/utils/utils'; import { IVisualizationContainerProps } from '../../../../../common/types/explorer'; -import { EmptyPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components/empty_placeholder'; +import { VisCanvassPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components/vis_canvass_placeholder'; import { Plt } from '../../plotly/plot'; import { AGGREGATIONS, GROUPBY } from '../../../../../common/constants/explorer'; import { PLOT_MARGIN } from '../../../../../common/constants/shared'; +import { getCompleteTimespanKey } from '../../../visualizations/charts/shared/common'; +import { removeBacktick } from '../../../../../common/utils'; export const HeatMap = ({ visualizations, layout, config }: any) => { const { data: { - defaultAxes, - indexFields, - query, rawVizData: { data: queriedVizData, metadata: { fields }, @@ -36,6 +35,7 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { userConfigs: { dataConfig: { chartStyles = {}, + span = {}, legend = {}, tooltipOptions = {}, panelOptions = {}, @@ -48,26 +48,31 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { vis: { icontype }, }: IVisualizationContainerProps = visualizations; - if (fields.length < 3) return ; - - const xaxisField = dimensions[0]; - const yaxisField = dimensions[1]; - const zMetrics = series[0]; + const backtickRemovedVisData = {}; + forEach(queriedVizData, (value, key) => { + backtickRemovedVisData[removeBacktick(key)] = value; + }); + const combinedDemensions = [ + ...(!isEmpty(span) ? [getCompleteTimespanKey(span)] : []), + ...dimensions, + ]; + if (!isEqual(combinedDemensions.length, 2) || !isEqual(series.length, 1)) + return ; + const xaxisField = { ...combinedDemensions[0] }; + const yaxisField = { ...combinedDemensions[1] }; + const zMetrics = { ...series[0] }; if ( isEmpty(xaxisField) || isEmpty(yaxisField) || isEmpty(zMetrics) || - isEmpty(queriedVizData[xaxisField.label]) || - isEmpty(queriedVizData[yaxisField.label]) || - isEmpty(queriedVizData[getPropName(zMetrics)]) || - dimensions.length > 2 || - series.length > 1 + isEmpty(backtickRemovedVisData[removeBacktick(xaxisField.label)]) || + isEmpty(backtickRemovedVisData[removeBacktick(yaxisField.label)]) ) - return ; + return ; - const uniqueYaxis = uniq(queriedVizData[yaxisField.label]); - const uniqueXaxis = uniq(queriedVizData[xaxisField.label]); + const uniqueYaxis = uniq(backtickRemovedVisData[removeBacktick(yaxisField.label)]); + const uniqueXaxis = uniq(backtickRemovedVisData[removeBacktick(xaxisField.label)]); const uniqueYaxisLength = uniqueYaxis.length; const uniqueXaxisLength = uniqueXaxis.length; const tooltipMode = @@ -97,9 +102,9 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { const buckets = {}; // maps bukcets to metrics - for (let i = 0; i < queriedVizData[xaxisField.label].length; i++) { - buckets[`${queriedVizData[xaxisField.label][i]},${queriedVizData[yaxisField.label][i]}`] = - queriedVizData[getPropName(zMetrics)][i]; + for (let i = 0; i < backtickRemovedVisData[removeBacktick(xaxisField.label)].length; i++) { + buckets[`${backtickRemovedVisData[removeBacktick(xaxisField.label)][i]},${backtickRemovedVisData[removeBacktick(yaxisField.label)][i]}`] = + backtickRemovedVisData[getPropName(zMetrics)][i]; } // initialize empty 2 dimensional array, inner loop for each xaxis field, outer loop for yaxis @@ -122,7 +127,7 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { return heapMapZaxis; }, [ - queriedVizData, + backtickRemovedVisData, uniqueYaxis, uniqueXaxis, uniqueYaxisLength, diff --git a/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx b/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx index 48cf5c366..e6443b158 100644 --- a/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx +++ b/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { find, isEmpty } from 'lodash'; +import { find, isEmpty, forEach } from 'lodash'; import React, { useMemo } from 'react'; import { DEFAULT_PALETTE, HEX_CONTRAST_COLOR } from '../../../../../common/constants/colors'; import { @@ -21,6 +21,7 @@ import { import { EmptyPlaceholder } from '../../../event_analytics/explorer/visualizations/shared_components/empty_placeholder'; import { getPropName, getTooltipHoverInfo } from '../../../event_analytics/utils/utils'; import { Plt } from '../../plotly/plot'; +import { removeBacktick } from '../../../../../common/utils'; export const Pie = ({ visualizations, layout, config }: any) => { const { @@ -56,6 +57,11 @@ export const Pie = ({ visualizations, layout, config }: any) => { const title = panelOptions.title || layoutConfig.layout?.title || ''; const timestampField = find(fields, (field) => field.type === 'timestamp'); + const backtickRemovedVisData = {}; + forEach(queriedVizData, (value, key) => { + backtickRemovedVisData[removeBacktick(key)] = value; + }); + /** * determine x axis */ @@ -74,10 +80,10 @@ export const Pie = ({ visualizations, layout, config }: any) => { (Number(`0x1${hex}`) ^ HEX_CONTRAST_COLOR).toString(16).substr(1).toUpperCase(); const labelsOfXAxis = xaxes.reduce((prev, cur) => { - if (queriedVizData[cur.name]) { - if (prev.length === 0) return queriedVizData[cur.name].flat(); + if (backtickRemovedVisData[removeBacktick(cur.name)]) { + if (prev.length === 0) return backtickRemovedVisData[removeBacktick(cur.name)].flat(); return prev.map( - (item: string | number, index: number) => `${item}, ${queriedVizData[cur.name][index]}` + (item: string | number, index: number) => `${item}, ${backtickRemovedVisData[removeBacktick(cur.name)][index]}` ); } }, []); @@ -92,7 +98,7 @@ export const Pie = ({ visualizations, layout, config }: any) => { colorTheme.name !== DEFAULT_PALETTE ? { marker: { - colors: [...Array(queriedVizData[fieldName].length).fill(colorTheme.childColor)], + colors: [...Array(backtickRemovedVisData[removeBacktick(fieldName)].length).fill(colorTheme.childColor)], line: { color: hexColor, width: 1, @@ -102,7 +108,7 @@ export const Pie = ({ visualizations, layout, config }: any) => { : undefined; return { labels: labelsOfXAxis, - values: queriedVizData[fieldName], + values: backtickRemovedVisData[removeBacktick(fieldName)], type: 'pie', name: getPropName(field), hole: type === 'pie' ? 0 : 0.5, @@ -125,7 +131,7 @@ export const Pie = ({ visualizations, layout, config }: any) => { }, }; }), - [series, queriedVizData, chartLabelSize, labelsOfXAxis, colorTheme] + [series, backtickRemovedVisData, chartLabelSize, labelsOfXAxis, colorTheme] ); const mergedLayout = useMemo(() => { diff --git a/dashboards-observability/public/components/visualizations/charts/shared/common.ts b/dashboards-observability/public/components/visualizations/charts/shared/common.ts index e5c0b06d4..6d782b41a 100644 --- a/dashboards-observability/public/components/visualizations/charts/shared/common.ts +++ b/dashboards-observability/public/components/visualizations/charts/shared/common.ts @@ -6,10 +6,13 @@ import { isEmpty, forEach } from 'lodash'; import { CUSTOM_LABEL } from '../../../../../common/constants/explorer'; import { ConfigList, DimensionSpan } from '../../../../../common/types/explorer'; +import { removeBacktick } from '../../../../../common/utils'; export const getCompleteTimespanKey = (span: DimensionSpan) => { - if (!span || isEmpty(span.time_field) || isEmpty(span.interval) || isEmpty(span.unit)) return ''; - return { name: `span(${span.time_field[0]?.name},${span.interval}${span.unit[0]?.value})` }; + if (isEmpty(span) || isEmpty(span.time_field) || isEmpty(span.interval) || isEmpty(span.unit)) + return ''; + const spanName = `span(${span.time_field[0]?.name},${span.interval}${span.unit[0]?.value})`; + return { name: spanName, label: spanName }; }; /** @@ -58,22 +61,30 @@ export const preprocessJsonData = ( ) => { const seriesFlattenedEntries = []; forEach(visJson, (entry) => { + const backtickRemovedEntry = {}; + // remove backtick, so data in jsonData can be accessed through using field name + forEach(entry, (value, key) => { + backtickRemovedEntry[removeBacktick(key)] = value; + }); forEach(series, (sr) => { let tabularVizData = {}; const serieKey = sr[CUSTOM_LABEL] ? sr[CUSTOM_LABEL] : `${sr.aggregation}(${sr.name})`; - let timespanDimension = []; - if (span) { - timespanDimension.push(getCompleteTimespanKey(span)); - } if (!isEmpty(serieKey)) { - const concatedXaxisLabel = [...timespanDimension, ...(dimensions)] - .map((dimension) => entry[dimension.name]) + const concatedXaxisLabel = [ + ...(!isEmpty(span) ? [getCompleteTimespanKey(span)] : []), + ...dimensions, + ] + .map((dimension) => { + return backtickRemovedEntry[removeBacktick(dimension.name)] ?? ''; + }) .join(','); const concatedBreakdownLabel = breakdowns - ? breakdowns.map((breakdown) => entry[breakdown.name]).join(',') + ? breakdowns + .map((breakdown) => backtickRemovedEntry[removeBacktick(breakdown.name)]) + .join(',') : ''; tabularVizData = { - value: entry[serieKey], + value: backtickRemovedEntry[serieKey], x: concatedXaxisLabel, breakdown: concatedBreakdownLabel, aggName: serieKey, diff --git a/dashboards-observability/public/components/visualizations/visualization.tsx b/dashboards-observability/public/components/visualizations/visualization.tsx index 75ba98241..63c342244 100644 --- a/dashboards-observability/public/components/visualizations/visualization.tsx +++ b/dashboards-observability/public/components/visualizations/visualization.tsx @@ -4,30 +4,19 @@ */ import React from 'react'; -import { isArray } from 'lodash'; +import { isEmpty } from 'lodash'; import { VisualizationChart } from './visualization_chart'; -import { EmptyPlaceholder } from '../event_analytics/explorer/visualizations/shared_components/empty_placeholder'; -import { VIS_CHART_TYPES } from '../../../common/constants/shared'; +import { VisCanvassPlaceholder } from '../event_analytics/explorer/visualizations/shared_components'; interface IVisualizationProps {} export const Visualization = ({ visualizations }: IVisualizationProps) => { - const { data, vis } = visualizations; - const { metadata = {} } = visualizations?.data?.rawVizData; - const { fields = [] } = metadata; - - // check viz data - const isVizDataValid = data && vis && visualizations?.data?.rawVizData; - - // check fields - const isVizFieldValid = fields && isArray(fields) && fields.length > 0; - return ( <> - {vis?.type === VIS_CHART_TYPES.LogsView || (isVizDataValid && isVizFieldValid) ? ( + {!isEmpty(visualizations?.data?.rawVizData?.data) ? ( ) : ( - + )} );