diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/monitoring/components/charts/area.vue | 103 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/constants.js | 10 |
2 files changed, 84 insertions, 29 deletions
diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue index 17e4f325b08..41783d311ef 100644 --- a/app/assets/javascripts/monitoring/components/charts/area.vue +++ b/app/assets/javascripts/monitoring/components/charts/area.vue @@ -4,6 +4,7 @@ import dateFormat from 'dateformat'; 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'; let debouncedResize; @@ -19,7 +20,6 @@ export default { required: true, validator(data) { return ( - data.queries && Array.isArray(data.queries) && data.queries.filter(query => { if (Array.isArray(query.result)) { @@ -51,21 +51,44 @@ export default { return { tooltip: { title: '', - content: '', + content: [], isDeployment: false, sha: '', }, width: 0, - height: 0, + height: chartHeight, svgs: {}, + primaryColor: null, }; }, computed: { chartData() { - return this.graphData.queries.reduce((accumulator, query) => { - accumulator[query.unit] = query.result.reduce((acc, res) => acc.concat(res.values), []); - return accumulator; - }, {}); + return this.graphData.queries.map(query => { + const { appearance } = query; + const lineType = + appearance && appearance.line && appearance.line.type + ? appearance.line.type + : lineTypes.default; + const lineColor = lineType === lineTypes.threshold ? this.primaryColor : undefined; + + return { + name: this.formatLegendLabel(query), + data: this.concatenateResults(query.result), + lineStyle: { + type: lineType, + color: lineColor, + }, + itemStyle: { + color: lineColor, + }, + areaStyle: { + opacity: + appearance && appearance.area && typeof appearance.area.opacity === 'number' + ? appearance.area.opacity + : undefined, + }, + }; + }); }, chartOptions() { return { @@ -85,9 +108,6 @@ export default { formatter: value => value.toFixed(3), }, }, - legend: { - formatter: this.xAxisLabel, - }, series: this.scatterSeries, dataZoom: this.dataZoomConfig, }; @@ -98,8 +118,8 @@ export default { return handleIcon ? { handleIcon } : {}; }, earliestDatapoint() { - return Object.values(this.chartData).reduce((acc, data) => { - const [[timestamp]] = data.sort(([a], [b]) => { + return this.chartData.reduce((acc, series) => { + const [[timestamp]] = series.data.sort(([a], [b]) => { if (a < b) { return -1; } @@ -129,15 +149,15 @@ export default { }, scatterSeries() { return { - type: 'scatter', + type: graphTypes.deploymentData, data: this.recentDeployments.map(deployment => [deployment.createdAt, 0]), symbol: this.svgs.rocket, symbolSize: 14, + itemStyle: { + color: this.primaryColor, + }, }; }, - xAxisLabel() { - return this.graphData.queries.map(query => query.label).join(', '); - }, yAxisLabel() { return `${this.graphData.y_label}`; }, @@ -155,18 +175,34 @@ export default { this.setSvg('scroll-handle'); }, methods: { + concatenateResults(results) { + return results.reduce((acc, result) => acc.concat(result.values), []); + }, + formatLegendLabel(query) { + return `${query.label}`; + }, formatTooltipText(params) { - const [seriesData] = params.seriesData; - this.tooltip.isDeployment = seriesData.componentSubType === 'scatter'; this.tooltip.title = dateFormat(params.value, 'dd mmm yyyy, h:MMTT'); - if (this.tooltip.isDeployment) { - const [deploy] = this.recentDeployments.filter( - deployment => deployment.createdAt === seriesData.value[0], - ); - this.tooltip.sha = deploy.sha.substring(0, 8); - } else { - this.tooltip.content = `${this.yAxisLabel} ${seriesData.value[1].toFixed(3)}`; - } + this.tooltip.content = []; + params.seriesData.forEach(seriesData => { + if (seriesData.componentSubType === graphTypes.deploymentData) { + this.tooltip.isDeployment = true; + const [deploy] = this.recentDeployments.filter( + deployment => deployment.createdAt === seriesData.value[0], + ); + this.tooltip.sha = deploy.sha.substring(0, 8); + } else { + const { seriesName } = seriesData; + // seriesData.value contains the chart's [x, y] value pair + // seriesData.value[1] is threfore the chart y value + const value = seriesData.value[1].toFixed(3); + + this.tooltip.content.push({ + name: seriesName, + value, + }); + } + }); }, setSvg(name) { getSvgIconPathContent(name) @@ -177,10 +213,12 @@ export default { }) .catch(() => {}); }, + onChartUpdated(chart) { + [this.primaryColor] = chart.getOption().color; + }, onResize() { - const { width, height } = this.$refs.areaChart.$el.getBoundingClientRect(); + const { width } = this.$refs.areaChart.$el.getBoundingClientRect(); this.width = width; - this.height = height; }, }, }; @@ -201,6 +239,7 @@ export default { :thresholds="alertData" :width="width" :height="height" + @updated="onChartUpdated" > <template slot="tooltipTitle"> <div v-if="tooltip.isDeployment"> @@ -214,7 +253,13 @@ export default { {{ tooltip.sha }} </div> <template v-else> - {{ tooltip.content }} + <div + v-for="(content, key) in tooltip.content" + :key="key" + class="d-flex justify-content-between" + > + {{ content.name }} {{ content.value }} + </div> </template> </template> </gl-area-chart> diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js new file mode 100644 index 00000000000..869173b6572 --- /dev/null +++ b/app/assets/javascripts/monitoring/constants.js @@ -0,0 +1,10 @@ +export const chartHeight = 300; + +export const graphTypes = { + deploymentData: 'scatter', +}; + +export const lineTypes = { + default: 'solid', + threshold: 'dashed', +}; |