diff options
Diffstat (limited to 'app/assets/javascripts/monitoring/components/charts')
6 files changed, 149 insertions, 34 deletions
diff --git a/app/assets/javascripts/monitoring/components/charts/column.vue b/app/assets/javascripts/monitoring/components/charts/column.vue index 7a2e3e1b511..d7d01def45e 100644 --- a/app/assets/javascripts/monitoring/components/charts/column.vue +++ b/app/assets/javascripts/monitoring/components/charts/column.vue @@ -5,7 +5,8 @@ import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; import { chartHeight } from '../../constants'; import { makeDataSeries } from '~/helpers/monitor_helper'; import { graphDataValidatorForValues } from '../../utils'; -import { getYAxisOptions, getChartGrid } from './options'; +import { getTimeAxisOptions, getYAxisOptions, getChartGrid } from './options'; +import { timezones } from '../../format_date'; export default { components: { @@ -20,6 +21,11 @@ export default { required: true, validator: graphDataValidatorForValues.bind(null, false), }, + timezone: { + type: String, + required: false, + default: timezones.LOCAL, + }, }, data() { return { @@ -43,6 +49,8 @@ export default { }; }, chartOptions() { + const xAxis = getTimeAxisOptions({ timezone: this.timezone }); + const yAxis = { ...getYAxisOptions(this.graphData.yAxis), scale: false, @@ -50,8 +58,9 @@ export default { return { grid: getChartGrid(), + xAxis, yAxis, - dataZoom: this.dataZoomConfig, + dataZoom: [this.dataZoomConfig], }; }, xAxisTitle() { diff --git a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue index e015ef32d8c..ad176637538 100644 --- a/app/assets/javascripts/monitoring/components/charts/empty_chart.vue +++ b/app/assets/javascripts/monitoring/components/charts/empty_chart.vue @@ -23,10 +23,10 @@ export default { <template> <div class="d-flex flex-column justify-content-center"> <div - class="prepend-top-8 svg-w-100 d-flex align-items-center" + class="gl-mt-3 svg-w-100 d-flex align-items-center" :style="svgContainerStyle" v-html="chartEmptyStateIllustration" ></div> - <h5 class="text-center prepend-top-8">{{ __('No data to display') }}</h5> + <h5 class="text-center gl-mt-3">{{ __('No data to display') }}</h5> </div> </template> diff --git a/app/assets/javascripts/monitoring/components/charts/heatmap.vue b/app/assets/javascripts/monitoring/components/charts/heatmap.vue index 55a25ee09fd..f6f266dacf3 100644 --- a/app/assets/javascripts/monitoring/components/charts/heatmap.vue +++ b/app/assets/javascripts/monitoring/components/charts/heatmap.vue @@ -1,8 +1,8 @@ <script> import { GlResizeObserverDirective } from '@gitlab/ui'; import { GlHeatmap } from '@gitlab/ui/dist/charts'; -import dateformat from 'dateformat'; import { graphDataValidatorForValues } from '../../utils'; +import { formatDate, timezones, formats } from '../../format_date'; export default { components: { @@ -17,6 +17,11 @@ export default { required: true, validator: graphDataValidatorForValues.bind(null, false), }, + timezone: { + type: String, + required: false, + default: timezones.LOCAL, + }, }, data() { return { @@ -43,7 +48,7 @@ export default { return this.result.values.map(val => { const [yLabel] = val; - return dateformat(new Date(yLabel), 'HH:MM:ss'); + return formatDate(new Date(yLabel), { format: formats.shortTime, timezone: this.timezone }); }); }, result() { diff --git a/app/assets/javascripts/monitoring/components/charts/options.js b/app/assets/javascripts/monitoring/components/charts/options.js index 09b03774580..f7822e69b1d 100644 --- a/app/assets/javascripts/monitoring/components/charts/options.js +++ b/app/assets/javascripts/monitoring/components/charts/options.js @@ -1,5 +1,6 @@ import { SUPPORTED_FORMATS, getFormatter } from '~/lib/utils/unit_format'; -import { s__ } from '~/locale'; +import { __, s__ } from '~/locale'; +import { formatDate, timezones, formats } from '../../format_date'; const yAxisBoundaryGap = [0.1, 0.1]; /** @@ -21,6 +22,21 @@ const chartGridLeft = 75; // Axis options /** + * Axis types + * @see https://echarts.apache.org/en/option.html#xAxis.type + */ +export const axisTypes = { + /** + * Category axis, suitable for discrete category data. + */ + category: 'category', + /** + * Time axis, suitable for continuous time series data. + */ + time: 'time', +}; + +/** * Converts .yml parameters to echarts axis options for data axis * @param {Object} param - Dashboard .yml definition options */ @@ -58,6 +74,17 @@ export const getYAxisOptions = ({ }; }; +export const getTimeAxisOptions = ({ timezone = timezones.LOCAL } = {}) => ({ + name: __('Time'), + type: axisTypes.time, + axisLabel: { + formatter: date => formatDate(date, { format: formats.shortTime, timezone }), + }, + axisPointer: { + snap: false, + }, +}); + // Chart grid /** diff --git a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue index 66ba20c125f..ac31d107e63 100644 --- a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue +++ b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue @@ -2,8 +2,11 @@ import { GlResizeObserverDirective } from '@gitlab/ui'; import { GlStackedColumnChart } from '@gitlab/ui/dist/charts'; import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; -import { chartHeight } from '../../constants'; +import { chartHeight, legendLayoutTypes } from '../../constants'; +import { s__ } from '~/locale'; import { graphDataValidatorForValues } from '../../utils'; +import { getTimeAxisOptions, axisTypes } from './options'; +import { timezones } from '../../format_date'; export default { components: { @@ -18,6 +21,36 @@ export default { required: true, validator: graphDataValidatorForValues.bind(null, false), }, + timezone: { + type: String, + required: false, + default: timezones.LOCAL, + }, + legendLayout: { + type: String, + required: false, + default: legendLayoutTypes.table, + }, + legendAverageText: { + type: String, + required: false, + default: s__('Metrics|Avg'), + }, + legendCurrentText: { + type: String, + required: false, + default: s__('Metrics|Current'), + }, + legendMaxText: { + type: String, + required: false, + default: s__('Metrics|Max'), + }, + legendMinText: { + type: String, + required: false, + default: s__('Metrics|Min'), + }, }, data() { return { @@ -28,7 +61,14 @@ export default { }, computed: { chartData() { - return this.graphData.metrics.map(metric => metric.result[0].values.map(val => val[1])); + return this.graphData.metrics.map(({ result }) => { + // This needs a fix. Not only metrics[0] should be shown. + // See https://gitlab.com/gitlab-org/gitlab/-/issues/220492 + if (!result || result.length === 0) { + return []; + } + return result[0].values.map(val => val[1]); + }); }, xAxisTitle() { return this.graphData.x_label !== undefined ? this.graphData.x_label : ''; @@ -37,10 +77,17 @@ export default { return this.graphData.y_label !== undefined ? this.graphData.y_label : ''; }, xAxisType() { - return this.graphData.x_type !== undefined ? this.graphData.x_type : 'category'; + // stacked-column component requires the x-axis to be of type `category` + return axisTypes.category; }, groupBy() { - return this.graphData.metrics[0].result[0].values.map(val => val[0]); + // This needs a fix. Not only metrics[0] should be shown. + // See https://gitlab.com/gitlab-org/gitlab/-/issues/220492 + const { result } = this.graphData.metrics[0]; + if (!result || result.length === 0) { + return []; + } + return result[0].values.map(val => val[0]); }, dataZoomConfig() { const handleIcon = this.svgs['scroll-handle']; @@ -49,11 +96,15 @@ export default { }, chartOptions() { return { - dataZoom: this.dataZoomConfig, + xAxis: { + ...getTimeAxisOptions({ timezone: this.timezone }), + type: this.xAxisType, + }, + dataZoom: [this.dataZoomConfig], }; }, seriesNames() { - return this.graphData.metrics.map(metric => metric.series_name); + return this.graphData.metrics.map(metric => metric.label); }, }, created() { @@ -94,6 +145,11 @@ export default { :width="width" :height="height" :series-names="seriesNames" + :legend-layout="legendLayout" + :legend-average-text="legendAverageText" + :legend-current-text="legendCurrentText" + :legend-max-text="legendMaxText" + :legend-min-text="legendMinText" /> </div> </template> diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue index 8f37a12af75..28af2d8ba77 100644 --- a/app/assets/javascripts/monitoring/components/charts/time_series.vue +++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue @@ -2,18 +2,19 @@ import { omit, throttle } from 'lodash'; import { GlLink, GlDeprecatedButton, GlTooltip, GlResizeObserverDirective } from '@gitlab/ui'; import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts'; -import dateFormat from 'dateformat'; -import { s__, __ } from '~/locale'; +import { s__ } from '~/locale'; import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; import Icon from '~/vue_shared/components/icon.vue'; -import { panelTypes, chartHeight, lineTypes, lineWidths, dateFormats } from '../../constants'; -import { getYAxisOptions, getChartGrid, getTooltipFormatter } from './options'; +import { panelTypes, chartHeight, lineTypes, lineWidths, legendLayoutTypes } from '../../constants'; +import { getYAxisOptions, getTimeAxisOptions, getChartGrid, getTooltipFormatter } from './options'; import { annotationsYAxis, generateAnnotationsSeries } from './annotations'; import { makeDataSeries } from '~/helpers/monitor_helper'; import { graphDataValidatorForValues } from '../../utils'; +import { formatDate, timezones } from '../../format_date'; + +export const timestampToISODate = timestamp => new Date(timestamp).toISOString(); const THROTTLED_DATAZOOM_WAIT = 1000; // milliseconds -const timestampToISODate = timestamp => new Date(timestamp).toISOString(); const events = { datazoom: 'datazoom', @@ -74,21 +75,41 @@ export default { required: false, default: () => [], }, + legendLayout: { + type: String, + required: false, + default: legendLayoutTypes.table, + }, legendAverageText: { type: String, required: false, default: s__('Metrics|Avg'), }, + legendCurrentText: { + type: String, + required: false, + default: s__('Metrics|Current'), + }, legendMaxText: { type: String, required: false, default: s__('Metrics|Max'), }, + legendMinText: { + type: String, + required: false, + default: s__('Metrics|Min'), + }, groupId: { type: String, required: false, default: '', }, + timezone: { + type: String, + required: false, + default: timezones.LOCAL, + }, }, data() { return { @@ -154,23 +175,16 @@ export default { const { yAxis, xAxis } = this.option; const option = omit(this.option, ['series', 'yAxis', 'xAxis']); + const timeXAxis = { + ...getTimeAxisOptions({ timezone: this.timezone }), + ...xAxis, + }; + const dataYAxis = { ...getYAxisOptions(this.graphData.yAxis), ...yAxis, }; - const timeXAxis = { - name: __('Time'), - type: 'time', - axisLabel: { - formatter: date => dateFormat(date, dateFormats.timeOfDay), - }, - axisPointer: { - snap: true, - }, - ...xAxis, - }; - return { series: this.chartOptionSeries, xAxis: timeXAxis, @@ -271,12 +285,13 @@ export default { */ formatAnnotationsTooltipText(params) { return { - title: dateFormat(params.data?.tooltipData?.title, dateFormats.default), + title: formatDate(params.data?.tooltipData?.title, { timezone: this.timezone }), content: params.data?.tooltipData?.content, }; }, formatTooltipText(params) { - this.tooltip.title = dateFormat(params.value, dateFormats.default); + this.tooltip.title = formatDate(params.value, { timezone: this.timezone }); + this.tooltip.content = []; params.seriesData.forEach(dataPoint => { @@ -368,8 +383,11 @@ export default { :thresholds="thresholds" :width="width" :height="height" - :average-text="legendAverageText" - :max-text="legendMaxText" + :legend-layout="legendLayout" + :legend-average-text="legendAverageText" + :legend-current-text="legendCurrentText" + :legend-max-text="legendMaxText" + :legend-min-text="legendMinText" @created="onChartCreated" @updated="onChartUpdated" > |