From 06c4b30ec5f336599ab824e37014e3b89cd51b14 Mon Sep 17 00:00:00 2001 From: ruchika-narang <79983862+ruchika-narang@users.noreply.github.com> Date: Wed, 14 Sep 2022 00:13:40 +0530 Subject: [PATCH] Resolving conflicts after merge of antlr code (#1021) * Resolved initial render of bar chart Signed-off-by: ruchika-narang * Made the charts workable after merging of antlr code to main Signed-off-by: ruchika-narang * Changes of condition for userconfigs Signed-off-by: ruchika-narang * Worked on line chart, treemap with the new antlr code Signed-off-by: ruchika-narang Signed-off-by: ruchika-narang --- .../__snapshots__/utils.test.tsx.snap | 288 +----------------- .../data_config_panel_item.tsx | 107 ++----- .../logs_view_config_panel_item.tsx | 6 +- .../treemap_config_panel_item.tsx | 68 +++-- .../visualizations/charts/bar/bar.tsx | 1 - .../charts/financial/gauge/gauge.tsx | 11 +- .../charts/helpers/viz_types.ts | 156 +++++++--- .../visualizations/charts/lines/line.tsx | 24 +- .../visualizations/charts/maps/heatmap.tsx | 24 +- .../visualizations/charts/pie/pie.tsx | 138 +++++---- 10 files changed, 308 insertions(+), 515 deletions(-) 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 e31ae697b..ac6bc701d 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 @@ -133,26 +133,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "barwidth": 0.97, @@ -617,26 +598,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "barwidth": 0.97, @@ -1124,26 +1086,7 @@ exports[`Utils helper functions renders displayVisualization function 1`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "barwidth": 0.97, @@ -1567,12 +1510,8 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "defaultAxes": Object { "xaxis": Array [ Object { - "aggregation": "", - "custom_label": "", "label": "", "name": "", - "side": "right", - "type": "", }, ], "yaxis": Array [ @@ -1698,34 +1637,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "aggregation": "", - "custom_label": "", - "label": "", - "name": "", - "side": "right", - "type": "", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -2104,12 +2016,8 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "defaultAxes": Object { "xaxis": Array [ Object { - "aggregation": "", - "custom_label": "", "label": "", "name": "", - "side": "right", - "type": "", }, ], "yaxis": Array [ @@ -2235,34 +2143,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "aggregation": "", - "custom_label": "", - "label": "", - "name": "", - "side": "right", - "type": "", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -2695,12 +2576,8 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "defaultAxes": Object { "xaxis": Array [ Object { - "aggregation": "", - "custom_label": "", "label": "", "name": "", - "side": "right", - "type": "", }, ], "yaxis": Array [ @@ -2826,34 +2703,7 @@ exports[`Utils helper functions renders displayVisualization function 2`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "aggregation": "", - "custom_label": "", - "label": "", - "name": "", - "side": "right", - "type": "", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -3440,26 +3290,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -3729,26 +3560,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -4041,26 +3853,7 @@ exports[`Utils helper functions renders displayVisualization function 3`] = ` "size": 4, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "Carrier", - "name": "Carrier", - "type": "keyword", - }, - ], - "metrics": Array [ - Object { - "label": "avg(FlightDelayMin)", - "name": "avg(FlightDelayMin)", - "type": "double", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -4358,26 +4151,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` "size": 0, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "span(timestamp,1h)", - "name": "span(timestamp,1h)", - "type": "timestamp", - }, - ], - "metrics": Array [ - Object { - "label": "count('ip')", - "name": "count('ip')", - "type": "integer", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -4593,26 +4367,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` "size": 0, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "span(timestamp,1h)", - "name": "span(timestamp,1h)", - "type": "timestamp", - }, - ], - "metrics": Array [ - Object { - "label": "count('ip')", - "name": "count('ip')", - "type": "integer", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", @@ -4851,26 +4606,7 @@ exports[`Utils helper functions renders displayVisualization function 4`] = ` "size": 0, "status": 200, }, - "userConfigs": Object { - "dataConfig": Object { - "valueOptions": Object { - "dimensions": Array [ - Object { - "label": "span(timestamp,1h)", - "name": "span(timestamp,1h)", - "type": "timestamp", - }, - ], - "metrics": Array [ - Object { - "label": "count('ip')", - "name": "count('ip')", - "type": "integer", - }, - ], - }, - }, - }, + "userConfigs": Object {}, }, "vis": Object { "category": "Visualizations", 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 d616dc156..87d6802d0 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 @@ -19,16 +19,9 @@ import { EuiFieldNumber, htmlIdGenerator, } from '@elastic/eui'; -import { useDispatch, useSelector, batch } from 'react-redux'; -import { - render as renderExplorerVis, - selectExplorerVisualization, -} from '../../../../../redux/slices/visualization_slice'; +import { useDispatch, batch } from 'react-redux'; import { changeQuery } from '../../../../../redux/slices/query_slice'; -import { - change as changeVizConfig, - selectVisualizationConfig, -} from '../../../../../redux/slices/viualization_config_slice'; +import { change as changeVizConfig } from '../../../../../redux/slices/viualization_config_slice'; import { AGGREGATION_OPTIONS, numericalTypes, @@ -42,111 +35,47 @@ import { TabContext } from '../../../../../hooks'; import { QueryManager } from '../../../../../../../../common/query_manager'; import { composeAggregations } from '../../../../../../../../common/query_manager/utils'; -const initialConfigEntry = { +const initialDimensionEntry = { label: '', - aggregation: '', - custom_label: '', name: '', - side: 'right', - type: '', }; -const DEFAULT_DATA_CONFIGS = { - [visChartTypes.HeatMap]: { - dimensions: [initialConfigEntry, initialConfigEntry], - metrics: [initialConfigEntry], - }, - [visChartTypes.Histogram]: { - dimensions: [{ bucketSize: '', bucketOffset: '' }], - }, +const initialMetricEntry = { + alias: '', + label: '', + name: '', + aggregation: 'count', }; -const SPECIAL_RENDERING_VIZS = [visChartTypes.HeatMap, visChartTypes.Histogram]; - -const getStandardedOuiField = (name?: string, type?: string) => ({ - name, - label: name, - type, -}); - export const DataConfigPanelItem = ({ fieldOptionList, visualizations }: any) => { const dispatch = useDispatch(); const { tabId, handleQuerySearch, handleQueryChange, setTempQuery, fetchData } = useContext( TabContext ); - const explorerVisualizationConfigs = useSelector(selectVisualizationConfig)[tabId]; const { data } = visualizations; const { data: vizData = {}, metadata: { fields = [] } = {} } = data?.rawVizData; const { indexFields: { availableFields }, } = data; const [configList, setConfigList] = useState({}); + const { userConfigs } = data; useEffect(() => { - if ( - data.rawVizData?.[visualizations.vis.name] && - data.rawVizData?.[visualizations.vis.name].dataConfig - ) { - setConfigList((staleState) => { - return { - ...staleState, - ...data.rawVizData[visualizations.vis.name].dataConfig, - }; - }); - } else if (some(SPECIAL_RENDERING_VIZS, (visType) => visType === visualizations.vis.name)) { - // any vis that doesn't conform normal metrics/dimensions data confiurations + if (userConfigs && userConfigs.dataConfig) { setConfigList({ - ...DEFAULT_DATA_CONFIGS[visualizations.vis.name], + ...userConfigs.dataConfig, }); - } else { - // default - const qm = new QueryManager(); - const statsTokens = qm.queryParser().parse(data.query.rawQuery).getStats(); - if (!statsTokens) { - setConfigList({ - metrics: [], - dimensions: [], - }); - } else { - const fieldInfo = statsTokens.groupby?.span?.span_expression?.field; - setConfigList({ - metrics: statsTokens.aggregations.map((agg) => ({ - alias: agg.alias, - label: agg.function?.value_expression, - name: agg.function?.value_expression, - aggregation: agg.function?.name, - })), - dimensions: statsTokens.groupby?.group_fields?.map((agg) => ({ - label: agg.name ?? '', - name: agg.name ?? '', - })), - span: { - time_field: statsTokens.groupby?.span?.span_expression?.field - ? [getStandardedOuiField(fieldInfo, 'timestamp')] - : [], - interval: statsTokens.groupby?.span?.span_expression?.literal_value ?? '0', - unit: statsTokens.groupby?.span?.span_expression?.time_unit - ? [getStandardedOuiField(statsTokens.groupby?.span?.span_expression?.time_unit)] - : [], - }, - }); - } } - }, [ - data.defaultAxes, - data.rawVizData?.[visualizations.vis.name]?.dataConfig, - visualizations.vis.name, - ]); + }, [userConfigs?.dataConfig, visualizations.vis.name]); const updateList = (value: string, index: number, name: string, field: string) => { const list = { ...configList }; let listItem = { ...list[name][index] }; listItem = { ...listItem, - [field]: value, + [field === 'custom_label' ? 'alias' : field]: value, }; if (field === 'label') { - listItem.type = value !== '' ? fields.find((x) => x.name === value)?.type : ''; listItem.name = value; } const updatedList = { @@ -180,8 +109,14 @@ export const DataConfigPanelItem = ({ fieldOptionList, visualizations }: any) => }; const handleServiceAdd = (name: string) => { - const updatedList = { ...configList, [name]: [...configList[name], initialConfigEntry] }; - setConfigList(updatedList); + const list = { + ...configList, + [name]: [ + ...configList[name], + name === 'metrics' ? initialMetricEntry : initialDimensionEntry, + ], + }; + setConfigList(list); }; const updateChart = (updatedConfigList = configList) => { diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/logs_view_config_panel_item.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/logs_view_config_panel_item.tsx index 7c4c33870..6f9bb5388 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/logs_view_config_panel_item.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/logs_view_config_panel_item.tsx @@ -47,12 +47,12 @@ export const LogsViewConfigPanelItem = ({ fieldOptionList, visualizations }: any const [configList, setConfigList] = useState({}); useEffect(() => { - if (userConfigs && userConfigs.dataConfig && userConfigs.dataConfig.valueOptions) { + if (userConfigs && userConfigs.dataConfig) { setConfigList({ - ...userConfigs.dataConfig.valueOptions, + ...userConfigs.dataConfig, }); } - }, [userConfigs?.dataConfig?.valueOptions, visualizations.vis.name]); + }, [userConfigs?.dataConfig, visualizations.vis.name]); useEffect(() => { if (fieldOptionList.length === 0) { diff --git a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/treemap_config_panel_item.tsx b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/treemap_config_panel_item.tsx index 06cb1e8f5..895a1708a 100644 --- a/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/treemap_config_panel_item.tsx +++ b/dashboards-observability/public/components/event_analytics/explorer/visualizations/config_panel/config_panes/config_controls/treemap_config_panel_item.tsx @@ -13,14 +13,23 @@ import { EuiFormRow, EuiPanel, } from '@elastic/eui'; -import { useDispatch } from 'react-redux'; +import { useDispatch, batch } from 'react-redux'; +import { changeQuery } from '../../../../../redux/slices/query_slice'; +import { + change as changeVizConfig, + selectVisualizationConfig, +} from '../../../../../redux/slices/viualization_config_slice'; import { ConfigTreemapParentFields } from './config_treemap_parents'; -import { numericalTypes } from '../../../../../../../../common/constants/explorer'; +import { numericalTypes, RAW_QUERY } from '../../../../../../../../common/constants/explorer'; import { TabContext } from '../../../../../hooks'; +import { QueryManager } from '../../../../../../../../common/query_manager'; +import { composeAggregations } from '../../../../../../../../common/query_manager/utils'; export const TreemapConfigPanelItem = ({ fieldOptionList, visualizations, tabID }: any) => { const dispatch = useDispatch(); - const { tabId, curVisId, changeVisualizationConfig } = useContext(TabContext); + const { tabId, curVisId, changeVisualizationConfig, fetchData, handleQueryChange } = useContext< + any + >(TabContext); const { data } = visualizations; const { userConfigs } = data; @@ -34,12 +43,12 @@ export const TreemapConfigPanelItem = ({ fieldOptionList, visualizations, tabID }); useEffect(() => { - if (userConfigs && userConfigs.dataConfig && userConfigs.dataConfig.valueOptions) { + if (userConfigs && userConfigs.dataConfig) { setConfigList({ - ...userConfigs.dataConfig.valueOptions, + ...userConfigs.dataConfig, }); } - }, [userConfigs?.dataConfig?.valueOptions, visualizations.vis.name]); + }, [userConfigs?.dataConfig, visualizations.vis.name]); const updateList = (configName: string, fieldName: string, value: string | any[]) => { let list = { ...configList }; @@ -58,23 +67,38 @@ export const TreemapConfigPanelItem = ({ fieldOptionList, visualizations, tabID setConfigList(newList); }; - const updateChart = () => { - dispatch( - changeVisualizationConfig({ - tabId, - vizId: curVisId, - data: { - ...userConfigs, - dataConfig: { - ...userConfigs.dataConfig, - valueOptions: { - dimensions: configList.dimensions, - metrics: configList.metrics, + const updateChart = (updatedConfigList = configList) => { + const qm = new QueryManager(); + const statsTokens = qm.queryParser().parse(data.query.rawQuery).getStats(); + const newQuery = qm + .queryBuilder() + .build(data.query.rawQuery, composeAggregations(updatedConfigList, statsTokens)); + + batch(async () => { + await handleQueryChange(newQuery); + await dispatch( + changeQuery({ + tabId, + query: { + ...data.query, + [RAW_QUERY]: newQuery, + }, + }) + ); + await fetchData(); + await dispatch( + changeVizConfig({ + tabId, + vizId: visualizations.vis.name, + data: { + dataConfig: { + metrics: updatedConfigList.metrics, + dimensions: updatedConfigList.dimensions, }, }, - }, - }) - ); + }) + ); + }); }; const getOptionsAvailable = (sectionName: string) => { @@ -169,7 +193,7 @@ export const TreemapConfigPanelItem = ({ fieldOptionList, visualizations, tabID updateChart()} size="s" > Update chart diff --git a/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx b/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx index f52409b89..02690816e 100644 --- a/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx +++ b/dashboards-observability/public/components/visualizations/charts/bar/bar.tsx @@ -31,7 +31,6 @@ export const Bar = ({ visualizations, layout, config }: any) => { }: IVisualizationContainerProps = visualizations; const lastIndex = fields.length - 1; const { dataConfig = {}, layoutConfig = {}, availabilityConfig = {} } = userConfigs; - console.log('bar dataConfig: ', dataConfig); if ( isEmpty(queriedVizData) || diff --git a/dashboards-observability/public/components/visualizations/charts/financial/gauge/gauge.tsx b/dashboards-observability/public/components/visualizations/charts/financial/gauge/gauge.tsx index 7882f79c6..b9b9f1549 100644 --- a/dashboards-observability/public/components/visualizations/charts/financial/gauge/gauge.tsx +++ b/dashboards-observability/public/components/visualizations/charts/financial/gauge/gauge.tsx @@ -27,12 +27,10 @@ export const Gauge = ({ visualizations, layout, config }: any) => { // data config parametrs const { dataConfig = {}, layoutConfig = {} } = visualizations.data.userConfigs; - const dimensions = dataConfig?.valueOptions?.dimensions - ? dataConfig.valueOptions.dimensions.filter((item) => item.name !== '') - : []; - const metrics = dataConfig?.valueOptions?.metrics - ? dataConfig.valueOptions.metrics.filter((item) => item.name !== '') + const dimensions = dataConfig?.dimensions + ? dataConfig.dimensions.filter((item) => item.name !== '') : []; + const metrics = dataConfig?.metrics ? dataConfig.metrics.filter((item) => item.name !== '') : []; const dimensionsLength = dimensions.length; const metricsLength = metrics.length; const numberOfGauges = dataConfig?.panelOptions?.numberOfGauges || DisplayDefaultGauges; @@ -70,9 +68,8 @@ export const Gauge = ({ visualizations, layout, config }: any) => { .reduce((prev, cur) => { return prev.map((i, j) => `${i}, ${cur[j]}`); }); - const selectedMetricsData = metrics.map((metric: any) => - data[metric.name].slice(0, numberOfGauges) + data[`${metric.aggregation}(${metric.name})`].slice(0, numberOfGauges) ); selectedMetricsData.map((metricSlice: any, metricSliceIndex: number) => { diff --git a/dashboards-observability/public/components/visualizations/charts/helpers/viz_types.ts b/dashboards-observability/public/components/visualizations/charts/helpers/viz_types.ts index cd79672eb..ef4b0c320 100644 --- a/dashboards-observability/public/components/visualizations/charts/helpers/viz_types.ts +++ b/dashboards-observability/public/components/visualizations/charts/helpers/viz_types.ts @@ -12,7 +12,7 @@ import { ExplorerData, } from '../../../../../common/types/explorer'; import { visChartTypes } from '../../../../../common/constants/shared'; - +import { QueryManager } from '../../../../../common/query_manager'; interface IVizContainerProps { vizId: string; appData?: { fromApp: boolean }; @@ -27,13 +27,16 @@ interface IVizContainerProps { explorer?: ExplorerData; } -const initialConfigEntry = { +const initialDimensionEntry = { + label: '', + name: '', +}; + +const initialMetricEntry = { + alias: '', label: '', - aggregation: '', - custom_label: '', name: '', - side: 'right', - type: '', + aggregation: 'count', }; const initialEntryTreemap = { label: '', name: '' }; @@ -49,7 +52,7 @@ const getDefaultXYAxisLabels = (vizFields: IField[], visName: string) => { const xaxis = vizFieldsWithLabel.filter((field) => field.type === 'timestamp'); return visName === visChartTypes.Line ? xaxis.length === 0 - ? [initialConfigEntry] + ? [initialDimensionEntry] : xaxis : [vizFieldsWithLabel[vizFieldsWithLabel.length - 1]]; }; @@ -65,20 +68,119 @@ const getDefaultXYAxisLabels = (vizFields: IField[], visName: string) => { return { xaxis: mapXaxis(), yaxis: mapYaxis() }; }; -const getUserConfigs = (userSelectedConfigs: object, vizFields: IField[], visName: string) => { +const getStandardedOuiField = (name?: string, type?: string) => ({ + name, + label: name, + type, +}); + +const defaultUserConfigs = (queryString, visualizationName: string) => { + let tempUserConfigs = {}; + const qm = new QueryManager(); + const statsTokens = qm.queryParser().parse(queryString.rawQuery).getStats(); + if (!statsTokens) { + tempUserConfigs = { + metrics: [], + dimensions: [], + }; + } else { + const fieldInfo = statsTokens.groupby?.span?.span_expression?.field; + tempUserConfigs = { + span: { + time_field: statsTokens.groupby?.span?.span_expression?.field + ? [getStandardedOuiField(fieldInfo, 'timestamp')] + : [], + interval: statsTokens.groupby?.span?.span_expression?.literal_value ?? '0', + unit: statsTokens.groupby?.span?.span_expression?.time_unit + ? [getStandardedOuiField(statsTokens.groupby?.span?.span_expression?.time_unit)] + : [], + }, + }; + if (visualizationName === visChartTypes.LogsView) { + tempUserConfigs = { + ...tempUserConfigs, + metrics: [], + dimensions: statsTokens.aggregations + .map((agg) => ({ + label: agg.name ?? '', + name: agg.name ?? '', + })) + .concat( + statsTokens.groupby?.group_fields?.map((agg) => ({ + label: agg.name ?? '', + name: agg.name ?? '', + })) + ), + }; + } else if (visualizationName === visChartTypes.HeatMap) { + tempUserConfigs = { + ...tempUserConfigs, + dimensions: [initialDimensionEntry, initialDimensionEntry], + metrics: [initialMetricEntry], + }; + } else if (visualizationName === visChartTypes.TreeMap) { + tempUserConfigs = { + dimensions: [ + { + childField: { + ...(statsTokens.groupby?.group_fields.length > 0 + ? { + label: statsTokens.groupby?.group_fields[0].name, + name: statsTokens.groupby?.group_fields[0].name, + } + : initialEntryTreemap), + }, + parentFields: [], + }, + ], + metrics: [ + { + valueField: { + ...(statsTokens.aggregations.length > 0 + ? { + label: statsTokens.aggregations[0].function?.value_expression, + name: statsTokens.aggregations[0].function?.value_expression, + } + : initialEntryTreemap), + }, + }, + ], + }; + } else { + tempUserConfigs = { + ...tempUserConfigs, + metrics: statsTokens.aggregations.map((agg) => ({ + alias: agg.alias, + label: agg.function?.value_expression, + name: agg.function?.value_expression, + aggregation: agg.function?.name, + })), + dimensions: statsTokens.groupby?.group_fields?.map((agg) => ({ + label: agg.name ?? '', + name: agg.name ?? '', + })), + }; + } + } + return tempUserConfigs; +}; + +const getUserConfigs = ( + userSelectedConfigs: object, + vizFields: IField[], + visName: string, + query +) => { let configOfUser = userSelectedConfigs; const axesData = getDefaultXYAxisLabels(vizFields, visName); - if (!userSelectedConfigs.dataConfig?.valueOptions) { + if (!(userSelectedConfigs.dataConfig?.dimensions || userSelectedConfigs.dataConfig?.metrics)) { switch (visName) { case visChartTypes.HeatMap: configOfUser = { ...userSelectedConfigs, dataConfig: { ...userSelectedConfigs?.dataConfig, - valueOptions: { - dimensions: [initialConfigEntry, initialConfigEntry], - metrics: [initialConfigEntry], - }, + ...defaultUserConfigs(query, visName), }, }; break; @@ -87,17 +189,7 @@ const getUserConfigs = (userSelectedConfigs: object, vizFields: IField[], visNam ...userSelectedConfigs, dataConfig: { ...userSelectedConfigs?.dataConfig, - valueOptions: { - dimensions: [ - { - childField: { ...(axesData.xaxis ? axesData.xaxis[0] : initialEntryTreemap) }, - parentFields: [], - }, - ], - metrics: [ - { valueField: { ...(axesData.yaxis ? axesData.yaxis[0] : initialEntryTreemap) } }, - ], - }, + ...defaultUserConfigs(query, visName), }, }; break; @@ -118,11 +210,7 @@ const getUserConfigs = (userSelectedConfigs: object, vizFields: IField[], visNam ...userSelectedConfigs, dataConfig: { ...userSelectedConfigs?.dataConfig, - valueOptions: { - dimensions: - axesData.xaxis && axesData.yaxis ? axesData.xaxis.concat(axesData.yaxis) : [], - metrics: [], - }, + ...defaultUserConfigs(query, visName), }, }; break; @@ -131,10 +219,7 @@ const getUserConfigs = (userSelectedConfigs: object, vizFields: IField[], visNam ...userSelectedConfigs, dataConfig: { ...userSelectedConfigs?.dataConfig, - valueOptions: { - metrics: axesData.yaxis ?? [], - dimensions: axesData.xaxis ?? [], - }, + ...defaultUserConfigs(query, visName), }, }; break; @@ -157,6 +242,9 @@ export const getVizContainerProps = ({ ? { ...getVisType(vizId, { type: vizId }) } : { ...getVisType(vizId) }; + const userSetConfigs = isEmpty(query) + ? userConfigs + : getUserConfigs(userConfigs, rawVizData?.metadata?.fields, getVisTypeData().name, query); return { data: { appData: { ...appData }, @@ -164,7 +252,7 @@ export const getVizContainerProps = ({ query: { ...query }, indexFields: { ...indexFields }, userConfigs: { - ...getUserConfigs(userConfigs, rawVizData?.metadata?.fields, getVisTypeData().name), + ...userSetConfigs, }, defaultAxes: { ...getDefaultXYAxisLabels(rawVizData?.metadata?.fields, getVisTypeData().name), diff --git a/dashboards-observability/public/components/visualizations/charts/lines/line.tsx b/dashboards-observability/public/components/visualizations/charts/lines/line.tsx index 80c22b8e8..3745a363b 100644 --- a/dashboards-observability/public/components/visualizations/charts/lines/line.tsx +++ b/dashboards-observability/public/components/visualizations/charts/lines/line.tsx @@ -4,7 +4,7 @@ */ import React, { useMemo } from 'react'; -import { take, isEmpty, last } from 'lodash'; +import { take, isEmpty, last, find } 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'; @@ -40,12 +40,8 @@ export const Line = ({ visualizations, layout, config }: any) => { availabilityConfig = {}, } = visualizations?.data?.userConfigs; - const xaxis = dataConfig?.valueOptions?.dimensions - ? dataConfig.valueOptions.dimensions.filter((item) => item.label) - : []; - const yaxis = dataConfig?.valueOptions?.metrics - ? dataConfig.valueOptions.metrics.filter((item) => item.label) - : []; + // const xaxis = dataConfig?.dimensions ? dataConfig.dimensions.filter((item) => item.label) : []; + const yaxis = dataConfig?.metrics ? dataConfig.metrics.filter((item) => item.label) : []; const tooltipMode = dataConfig?.tooltipOptions?.tooltipMode !== undefined ? dataConfig.tooltipOptions.tooltipMode @@ -81,6 +77,18 @@ export const Line = ({ visualizations, layout, config }: any) => { dataConfig.colorTheme.find((colorSelected) => colorSelected.name.name === field.name) ?.color) || PLOTLY_COLOR[index % PLOTLY_COLOR.length]; + /** + * determine x axis + */ + const xaxis = useMemo(() => { + // span selection + const timestampField = find(fields, (field) => field.type === 'timestamp'); + if (dataConfig.span && dataConfig.span.time_field && timestampField) { + return [timestampField, ...dataConfig.dimensions]; + } + + return dataConfig.dimensions; + }, [dataConfig.dimensions]); if (isEmpty(xaxis) || isEmpty(yaxis)) return ; @@ -135,7 +143,7 @@ export const Line = ({ visualizations, layout, config }: any) => { return { x: data[!isEmpty(xaxis) ? xaxis[0]?.label : fields[lastIndex].name], - y: data[field.label], + y: data[`${field.aggregation}(${field.name})`], type: isBarMode ? 'bar' : 'scatter', name: field.label, mode, diff --git a/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx b/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx index 11e6dfe48..30dce8305 100644 --- a/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx +++ b/dashboards-observability/public/components/visualizations/charts/maps/heatmap.tsx @@ -27,9 +27,9 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { if (fields.length < 3) return ; - const xaxisField = dataConfig?.valueOptions?.dimensions[0]; - const yaxisField = dataConfig?.valueOptions?.dimensions[1]; - const zMetrics = dataConfig?.valueOptions?.metrics[0]; + const xaxisField = dataConfig?.dimensions[0]; + const yaxisField = dataConfig?.dimensions[1]; + const zMetrics = dataConfig?.metrics[0]; if ( isEmpty(xaxisField) || @@ -37,8 +37,8 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { isEmpty(zMetrics) || isEmpty(data[xaxisField.label]) || isEmpty(data[yaxisField.label]) || - isEmpty(data[zMetrics.label]) || - indexOf(NUMERICAL_FIELDS, zMetrics.type) < 0 + isEmpty(data[`${zMetrics.aggregation}(${zMetrics.name})`]) + // indexOf(NUMERICAL_FIELDS, zMetrics.type) < 0 ) return ; @@ -80,7 +80,7 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { // maps bukcets to metrics for (let i = 0; i < data[xaxisField.label].length; i++) { buckets[`${data[xaxisField.label][i]},${data[yaxisField.label][i]}`] = - data[zMetrics.label][i]; + data[`${zMetrics.aggregation}(${zMetrics.name})`][i]; } // initialize empty 2 dimensional array, inner loop for each xaxis field, outer loop for yaxis @@ -131,11 +131,13 @@ export const HeatMap = ({ visualizations, layout, config }: any) => { title: dataConfig?.panelOptions?.title || layoutConfig.layout?.title || '', }; - - const mergedConfigs = useMemo(() => ({ - ...config, - ...(layoutConfig.config && layoutConfig.config), - }), [config, layoutConfig.config]); + const mergedConfigs = useMemo( + () => ({ + ...config, + ...(layoutConfig.config && layoutConfig.config), + }), + [config, layoutConfig.config] + ); return ; }; diff --git a/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx b/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx index 912f3f6d2..64b1a5cf2 100644 --- a/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx +++ b/dashboards-observability/public/components/visualizations/charts/pie/pie.tsx @@ -17,12 +17,8 @@ export const Pie = ({ visualizations, layout, config }: any) => { } = visualizations.data.rawVizData; const { defaultAxes } = visualizations.data; const { dataConfig = {}, layoutConfig = {} } = visualizations?.data?.userConfigs; - const xaxis = dataConfig?.valueOptions?.dimensions - ? dataConfig.valueOptions.dimensions.filter((item) => item.label) - : []; - const yaxis = dataConfig?.valueOptions?.metrics - ? dataConfig.valueOptions.metrics.filter((item) => item.label) - : []; + const xaxis = dataConfig?.dimensions ? dataConfig.dimensions.filter((item) => item.label) : []; + const yaxis = dataConfig?.metrics ? dataConfig.metrics.filter((item) => item.label) : []; const type = dataConfig?.chartStyles?.mode ? dataConfig?.chartStyles?.mode[0]?.modeId : 'pie'; const lastIndex = fields.length - 1; const colorTheme = dataConfig?.chartStyles?.colorTheme @@ -44,12 +40,12 @@ export const Pie = ({ visualizations, layout, config }: any) => { if (isEmpty(xaxis) || isEmpty(yaxis)) return ; - let valueSeries; - if (!isEmpty(xaxis) && !isEmpty(yaxis)) { - valueSeries = [...yaxis]; - } else { - valueSeries = defaultAxes.yaxis || take(fields, lastIndex > 0 ? lastIndex : 1); - } + let valueSeries; + if (!isEmpty(xaxis) && !isEmpty(yaxis)) { + valueSeries = [...yaxis]; + } else { + valueSeries = defaultAxes.yaxis || take(fields, lastIndex > 0 ? lastIndex : 1); + } const invertHex = (hex: string) => (Number(`0x1${hex}`) ^ HEX_CONTRAST_COLOR).toString(16).substr(1).toUpperCase(); @@ -75,59 +71,63 @@ export const Pie = ({ visualizations, layout, config }: any) => { }, [xaxis, data, fields, createLegendLabels]); const hexColor = invertHex(colorTheme); - const pies = useMemo(() => valueSeries.map((field: any, index: number) => { - const marker = - colorTheme.name !== DEFAULT_PALETTE - ? { - marker: { - colors: [...Array(data[field.name].length).fill(colorTheme.childColor)], - line: { - color: hexColor, - width: 1, - }, + const pies = useMemo( + () => + valueSeries.map((field: any, index: number) => { + const marker = + colorTheme.name !== DEFAULT_PALETTE + ? { + marker: { + colors: [...Array(data[field.name].length).fill(colorTheme.childColor)], + line: { + color: hexColor, + width: 1, + }, + }, + } + : undefined; + return { + labels: labelsOfXAxis, + values: data[field.label], + type: 'pie', + name: field.name, + hole: type === 'pie' ? 0 : 0.5, + text: field.name, + textinfo: 'percent', + hoverinfo: tooltipMode === 'hidden' ? 'none' : tooltipText, + automargin: true, + textposition: 'outside', + domain: { + row: Math.floor(index / 3), + column: index % 3, }, - } - : undefined; - return { - labels: labelsOfXAxis, - values: data[field.label], - type: 'pie', - name: field.name, - hole: type === 'pie' ? 0 : 0.5, - text: field.name, - textinfo: 'percent', - hoverinfo: tooltipMode === 'hidden' ? 'none' : tooltipText, - automargin: true, - textposition: 'outside', - domain: { - row: Math.floor(index / 3), - column: index % 3, - }, - ...marker, - outsidetextfont: { - size: labelSize, - }, - }; - }) - , [valueSeries, valueSeries, data, labelSize, labelsOfXAxis, colorTheme]); + ...marker, + outsidetextfont: { + size: labelSize, + }, + }; + }), + [valueSeries, valueSeries, data, labelSize, labelsOfXAxis, colorTheme] + ); const isAtleastOneFullRow = Math.floor(valueSeries.length / 3) > 0; - const mergedLayout = useMemo(() => ({ - grid: { - rows: Math.floor(valueSeries.length / 3) + 1, - columns: isAtleastOneFullRow ? 3 : valueSeries.length, - }, - ...layout, - ...(layoutConfig.layout && layoutConfig.layout), - title: dataConfig?.panelOptions?.title || layoutConfig.layout?.title || '', - legend: { - ...layout.legend, - orientation: legendPosition, - font: { size: legendSize }, - }, - showlegend: showLegend, - }), + const mergedLayout = useMemo( + () => ({ + grid: { + rows: Math.floor(valueSeries.length / 3) + 1, + columns: isAtleastOneFullRow ? 3 : valueSeries.length, + }, + ...layout, + ...(layoutConfig.layout && layoutConfig.layout), + title: dataConfig?.panelOptions?.title || layoutConfig.layout?.title || '', + legend: { + ...layout.legend, + orientation: legendPosition, + font: { size: legendSize }, + }, + showlegend: showLegend, + }), [ valueSeries, isAtleastOneFullRow, @@ -136,13 +136,17 @@ export const Pie = ({ visualizations, layout, config }: any) => { layoutConfig.layout?.title, layout.legend, legendPosition, - legendSize - ]); + legendSize, + ] + ); - const mergedConfigs = useMemo(() => ({ - ...config, - ...(layoutConfig.config && layoutConfig.config), - }), [config, layoutConfig.config]); + const mergedConfigs = useMemo( + () => ({ + ...config, + ...(layoutConfig.config && layoutConfig.config), + }), + [config, layoutConfig.config] + ); return ; };