summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Vargas <jvargas@gitlab.com>2019-08-09 15:59:05 -0500
committerJose Vargas <jvargas@gitlab.com>2019-08-23 16:07:51 -0500
commit0765c8a13886147d160ac4f585d010cf1ba89498 (patch)
tree1f773f8c519616253b79c884e8ce6a804021762f
parente84922906e51b22f2f335ebaa4390ccac2e4caf8 (diff)
downloadgitlab-ce-jivanvl-add-support-stacked-column-charts.tar.gz
Add support for stacked column chartsjivanvl-add-support-stacked-column-charts
This adds support for stacked column charts inside the monitoring dashboard
-rw-r--r--app/assets/javascripts/monitoring/components/charts/stacked_column.vue109
-rw-r--r--app/assets/javascripts/monitoring/components/panel_type.vue30
-rw-r--r--spec/javascripts/monitoring/charts/stacked_column_spec.js27
3 files changed, 166 insertions, 0 deletions
diff --git a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
new file mode 100644
index 00000000000..348dd52c904
--- /dev/null
+++ b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
@@ -0,0 +1,109 @@
+<script>
+import { GlStackedColumnChart } from '@gitlab/ui/dist/charts';
+import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
+import { chartHeight } from '../../constants';
+import { graphDataValidatorForValues } from '../../utils';
+
+export default {
+ components: {
+ GlStackedColumnChart,
+ },
+ props: {
+ graphData: {
+ type: Object,
+ required: true,
+ validator: graphDataValidatorForValues.bind(null, false),
+ },
+ containerWidth: {
+ type: Number,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ width: 0,
+ height: chartHeight,
+ svgs: {},
+ };
+ },
+ computed: {
+ chartData() {
+ // TODO: Process this data from the graphData prop
+ return [
+ [58, 49, 38, 23, 27, 68, 38, 35, 7, 64, 65, 31],
+ [8, 6, 34, 19, 9, 7, 17, 25, 14, 7, 10, 32],
+ [67, 60, 66, 32, 61, 54, 13, 50, 16, 11, 47, 28],
+ [8, 9, 5, 40, 13, 19, 58, 21, 47, 59, 23, 46],
+ ];
+ },
+ xAxisTitle() {
+ return this.graphData.queries[0].result[0].x_label !== undefined
+ ? this.graphData.queries[0].result[0].x_label
+ : '';
+ },
+ yAxisTitle() {
+ return this.graphData.queries[0].result[0].y_label !== undefined
+ ? this.graphData.queries[0].result[0].y_label
+ : '';
+ },
+ xAxisType() {
+ return this.graphData.x_type !== undefined ? this.graphData.x_type : 'category';
+ },
+ groupBy() {
+ // TODO: Process this data from the graphData prop
+ // eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
+ return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+ },
+ dataZoomConfig() {
+ const handleIcon = this.svgs['scroll-handle'];
+
+ return handleIcon ? { handleIcon } : {};
+ },
+ chartOptions() {
+ return {
+ dataZoom: this.dataZoomConfig,
+ };
+ },
+ seriesNames() {
+ // TODO: Process this data from the graphData prop
+ // eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
+ return ['Fun 1', 'Fun 2', 'Fun 3', 'Fun 4'];
+ },
+ },
+ created() {
+ this.setSvg('scroll-handle');
+ },
+ methods: {
+ setSvg(name) {
+ getSvgIconPathContent(name)
+ .then(path => {
+ if (path) {
+ this.$set(this.svgs, name, `path://${path}`);
+ }
+ })
+ .catch(() => {});
+ },
+ },
+};
+</script>
+<template>
+ <div class="prometheus-graph col-12 col-lg-6">
+ <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-stacked-column-chart
+ ref="stackedColumnChart"
+ v-bind="$attrs"
+ :data="chartData"
+ :option="chartOptions"
+ :x-axis-title="xAxisTitle"
+ :y-axis-title="yAxisTitle"
+ :x-axis-type="xAxisType"
+ :group-by="groupBy"
+ :width="width"
+ :height="height"
+ :series-names="seriesNames"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/monitoring/components/panel_type.vue b/app/assets/javascripts/monitoring/components/panel_type.vue
index 96f62bc85ee..fc8f461fd2f 100644
--- a/app/assets/javascripts/monitoring/components/panel_type.vue
+++ b/app/assets/javascripts/monitoring/components/panel_type.vue
@@ -12,12 +12,14 @@ import {
import Icon from '~/vue_shared/components/icon.vue';
import MonitorAreaChart from './charts/area.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
+import MonitorStackedColumnChart from './charts/stacked_column.vue';
import MonitorEmptyChart from './charts/empty_chart.vue';
export default {
components: {
MonitorAreaChart,
MonitorSingleStatChart,
+ MonitorStackedColumnChart,
MonitorEmptyChart,
Icon,
GlDropdown,
@@ -92,6 +94,34 @@ export default {
v-if="isPanelType('single-stat') && graphDataHasMetrics"
:graph-data="graphData"
/>
+ <monitor-stacked-column-chart
+ v-else-if="isPanelType('stacked-column') && graphDataHasMetrics"
+ :graph-data="graphData"
+ :container-width="dashboardWidth"
+ >
+ <gl-dropdown
+ v-gl-tooltip
+ class="mx-2"
+ toggle-class="btn btn-transparent border-0"
+ :right="true"
+ :no-caret="true"
+ :title="__('More actions')"
+ >
+ <template slot="button-content">
+ <icon name="ellipsis_v" class="text-secondary" />
+ </template>
+ <gl-dropdown-item :href="downloadCsv" download="chart_metrics.csv">
+ {{ __('Download CSV') }}
+ </gl-dropdown-item>
+ <gl-dropdown-item
+ class="js-chart-link"
+ :data-clipboard-text="clipboardText"
+ @click="showToast"
+ >
+ {{ __('Generate link to chart') }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+ </monitor-stacked-column-chart>
<monitor-area-chart
v-else-if="graphDataHasMetrics"
:graph-data="graphData"
diff --git a/spec/javascripts/monitoring/charts/stacked_column_spec.js b/spec/javascripts/monitoring/charts/stacked_column_spec.js
new file mode 100644
index 00000000000..6b120bddafa
--- /dev/null
+++ b/spec/javascripts/monitoring/charts/stacked_column_spec.js
@@ -0,0 +1,27 @@
+import { shallowMount } from '@vue/test-utils';
+import StackedColumnChart from '~/monitoring/components/charts/stacked_column.vue';
+import { graphDataPrometheusQueryRange } from '../mock_data';
+
+describe('Stacked column chart component', () => {
+ let stackedColumnChart;
+ const containerWidth = 200;
+
+ beforeEach(() => {
+ stackedColumnChart = shallowMount(StackedColumnChart, {
+ propsData: {
+ graphData: graphDataPrometheusQueryRange,
+ containerWidth,
+ },
+ })
+ });
+
+ afterEach(() => {
+ stackedColumnChart.destroy();
+ });
+
+ describe('with graphData present', () => {
+ it('chartData should return an array of arrays', () => {
+ expect(stackedColumnChart.vm.chartData.length).toBe(4);
+ });
+ });
+});