<script> import { GlAreaChart } from '@gitlab/ui/dist/charts'; import { debounceByAnimationFrame } from '~/lib/utils/common_utils'; import dateFormat from 'dateformat'; import { X_INTERVAL } from '../constants'; import { validateGraphData } from '../utils'; import { __ } from '~/locale'; let debouncedResize; export default { components: { GlAreaChart, }, inheritAttrs: false, props: { graphData: { type: Object, required: true, validator: validateGraphData, }, containerWidth: { type: Number, required: true, }, }, data() { return { tooltipPopoverTitle: '', tooltipPopoverContent: '', width: this.containerWidth, }; }, computed: { chartData() { return this.graphData.queries.reduce((accumulator, query) => { accumulator[query.unit] = query.result.reduce((acc, res) => acc.concat(res.values), []); return accumulator; }, {}); }, extractTimeData() { return this.chartData.requests.map(data => data.time); }, generateSeries() { return { name: __('Invocations'), type: 'line', data: this.chartData.requests.map(data => [data.time, data.value]), symbolSize: 0, }; }, getInterval() { const { result } = this.graphData.queries[0]; if (result.length === 0) { return 1; } const split = result[0].values.reduce( (acc, pair) => (pair.value > acc ? pair.value : acc), 1, ); return split < X_INTERVAL ? split : X_INTERVAL; }, chartOptions() { return { xAxis: { name: 'time', type: 'time', axisLabel: { formatter: date => dateFormat(date, 'h:MM TT'), }, data: this.extractTimeData, nameTextStyle: { padding: [18, 0, 0, 0], }, }, yAxis: { name: this.yAxisLabel, nameTextStyle: { padding: [0, 0, 36, 0], }, splitNumber: this.getInterval, }, legend: { formatter: this.xAxisLabel, }, series: this.generateSeries, }; }, xAxisLabel() { return this.graphData.queries.map(query => query.label).join(', '); }, yAxisLabel() { const [query] = this.graphData.queries; return `${this.graphData.y_label} (${query.unit})`; }, }, watch: { containerWidth: 'onResize', }, beforeDestroy() { window.removeEventListener('resize', debouncedResize); }, created() { debouncedResize = debounceByAnimationFrame(this.onResize); window.addEventListener('resize', debouncedResize); }, methods: { formatTooltipText(params) { const [seriesData] = params.seriesData; this.tooltipPopoverTitle = dateFormat(params.value, 'dd mmm yyyy, h:MMTT'); this.tooltipPopoverContent = `${this.yAxisLabel}: ${seriesData.value[1]}`; }, onResize() { const { width } = this.$refs.areaChart.$el.getBoundingClientRect(); this.width = width; }, }, }; </script> <template> <div class="prometheus-graph"> <div class="prometheus-graph-header"> <h5 ref="graphTitle" class="prometheus-graph-title">{{ graphData.title }}</h5> <div ref="graphWidgets" class="prometheus-graph-widgets"> <slot></slot> </div> </div> <gl-area-chart ref="areaChart" v-bind="$attrs" :data="[]" :option="chartOptions" :format-tooltip-text="formatTooltipText" :width="width" :include-legend-avg-max="false" > <template slot="tooltipTitle">{{ tooltipPopoverTitle }}</template> <template slot="tooltipContent">{{ tooltipPopoverContent }}</template> </gl-area-chart> </div> </template>