From 6383769942b2b7fcdca8ed361a4fbb363ac3c68c Mon Sep 17 00:00:00 2001 From: Adriel Santiago Date: Sun, 24 Mar 2019 10:34:27 -0400 Subject: Restore multiple series support Corrects an issue whereby queries which return multiple series results were not rendering as multiple data series on the metrics dashboard --- app/assets/javascripts/helpers/monitor_helper.js | 17 ++++++++ .../monitoring/components/charts/area.vue | 15 ++++---- ...n-multiple-series-are-not-working-correctly.yml | 5 +++ spec/frontend/helpers/monitor_helper_spec.js | 45 ++++++++++++++++++++++ 4 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 app/assets/javascripts/helpers/monitor_helper.js create mode 100644 changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml create mode 100644 spec/frontend/helpers/monitor_helper_spec.js diff --git a/app/assets/javascripts/helpers/monitor_helper.js b/app/assets/javascripts/helpers/monitor_helper.js new file mode 100644 index 00000000000..2c2a04d5b5e --- /dev/null +++ b/app/assets/javascripts/helpers/monitor_helper.js @@ -0,0 +1,17 @@ +/* eslint-disable import/prefer-default-export */ + +export const makeDataSeries = (queryResults, defaultConfig) => + queryResults.reduce((acc, result) => { + const data = result.values.filter(([, value]) => !Number.isNaN(value)); + if (!data.length) { + return acc; + } + const relevantMetric = defaultConfig.name.toLowerCase().replace(' ', '_'); + const name = result.metric[relevantMetric]; + const series = { data }; + if (name) { + series.name = `${defaultConfig.name}: ${name}`; + } + + return acc.concat({ ...defaultConfig, ...series }); + }, []); diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue index d453dc1fdb7..b0bbe272d1f 100644 --- a/app/assets/javascripts/monitoring/components/charts/area.vue +++ b/app/assets/javascripts/monitoring/components/charts/area.vue @@ -5,6 +5,7 @@ import { debounceByAnimationFrame } from '~/lib/utils/common_utils'; import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; import Icon from '~/vue_shared/components/icon.vue'; import { chartHeight, graphTypes, lineTypes } from '../../constants'; +import { makeDataSeries } from '~/helpers/monitor_helper'; let debouncedResize; @@ -63,7 +64,7 @@ export default { }, computed: { chartData() { - return this.graphData.queries.map(query => { + return this.graphData.queries.reduce((acc, query) => { const { appearance } = query; const lineType = appearance && appearance.line && appearance.line.type @@ -74,9 +75,8 @@ export default { ? appearance.line.width : undefined; - return { + const series = makeDataSeries(query.result, { name: this.formatLegendLabel(query), - data: this.concatenateResults(query.result), lineStyle: { type: lineType, width: lineWidth, @@ -87,8 +87,10 @@ export default { ? appearance.area.opacity : undefined, }, - }; - }); + }); + + return acc.concat(series); + }, []); }, chartOptions() { return { @@ -175,9 +177,6 @@ export default { this.setSvg('scroll-handle'); }, methods: { - concatenateResults(results) { - return results.reduce((acc, result) => acc.concat(result.values), []); - }, formatLegendLabel(query) { return `${query.label}`; }, diff --git a/changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml b/changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml new file mode 100644 index 00000000000..9ab8d2b8596 --- /dev/null +++ b/changelogs/unreleased/59324-queries-which-return-multiple-series-are-not-working-correctly.yml @@ -0,0 +1,5 @@ +--- +title: Fix multiple series queries on metrics dashboard +merge_request: 26514 +author: +type: fixed diff --git a/spec/frontend/helpers/monitor_helper_spec.js b/spec/frontend/helpers/monitor_helper_spec.js new file mode 100644 index 00000000000..2e8bff298c4 --- /dev/null +++ b/spec/frontend/helpers/monitor_helper_spec.js @@ -0,0 +1,45 @@ +import * as monitorHelper from '~/helpers/monitor_helper'; + +describe('monitor helper', () => { + const defaultConfig = { default: true, name: 'default name' }; + const name = 'data name'; + const series = [[1, 1], [2, 2], [3, 3]]; + const data = ({ metric = { default_name: name }, values = series } = {}) => [{ metric, values }]; + + describe('makeDataSeries', () => { + const expectedDataSeries = [ + { + ...defaultConfig, + data: series, + }, + ]; + + it('converts query results to data series', () => { + expect(monitorHelper.makeDataSeries(data({ metric: {} }), defaultConfig)).toEqual( + expectedDataSeries, + ); + }); + + it('returns an empty array if no query results exist', () => { + expect(monitorHelper.makeDataSeries([], defaultConfig)).toEqual([]); + }); + + it('handles multi-series query results', () => { + const expectedData = { ...expectedDataSeries[0], name: 'default name: data name' }; + + expect(monitorHelper.makeDataSeries([...data(), ...data()], defaultConfig)).toEqual([ + expectedData, + expectedData, + ]); + }); + + it('excludes NaN values', () => { + expect( + monitorHelper.makeDataSeries( + data({ metric: {}, values: [[1, 1], [2, NaN]] }), + defaultConfig, + ), + ).toEqual([{ ...expectedDataSeries[0], data: [[1, 1]] }]); + }); + }); +}); -- cgit v1.2.1