summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2017-04-04 15:19:17 +0000
committerFilipa Lacerda <filipa@gitlab.com>2017-04-04 15:19:17 +0000
commita46cca2e58643acd9d936442f98b12aaa84b9a26 (patch)
tree7142876d43d21fa4a641d094fc9cb42f1dae092f
parent10c768533027e7523467680b8fd401fcc017e827 (diff)
parent3069a2c959fcdf05b95a5c0893d4c31e10950a01 (diff)
downloadgitlab-ce-a46cca2e58643acd9d936442f98b12aaa84b9a26.tar.gz
Merge branch 'environment-performance-improvements' into 'master'
Improved Environments Metrics UX Closes #29227 See merge request !9946
-rw-r--r--app/assets/javascripts/lib/utils/number_utils.js34
-rw-r--r--app/assets/javascripts/monitoring/prometheus_graph.js323
-rw-r--r--app/assets/stylesheets/pages/environments.scss10
-rw-r--r--app/views/projects/environments/_external_url.html.haml1
-rw-r--r--app/views/projects/environments/_metrics_button.html.haml1
-rw-r--r--app/views/projects/environments/metrics.html.haml2
-rw-r--r--app/views/projects/environments/show.html.haml4
-rw-r--r--changelogs/unreleased/environment-performance-improvements.yml4
-rw-r--r--spec/javascripts/lib/utils/number_utility_spec.js41
-rw-r--r--spec/javascripts/monitoring/prometheus_graph_spec.js10
10 files changed, 277 insertions, 153 deletions
diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js
new file mode 100644
index 00000000000..e2bf69ee52e
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/number_utils.js
@@ -0,0 +1,34 @@
+/* eslint-disable import/prefer-default-export */
+
+/**
+ * Function that allows a number with an X amount of decimals
+ * to be formatted in the following fashion:
+ * * For 1 digit to the left of the decimal point and X digits to the right of it
+ * * * Show 3 digits to the right
+ * * For 2 digits to the left of the decimal point and X digits to the right of it
+ * * * Show 2 digits to the right
+*/
+export function formatRelevantDigits(number) {
+ let digitsLeft = '';
+ let relevantDigits = 0;
+ let formattedNumber = '';
+ if (!isNaN(Number(number))) {
+ digitsLeft = number.split('.')[0];
+ switch (digitsLeft.length) {
+ case 1:
+ relevantDigits = 3;
+ break;
+ case 2:
+ relevantDigits = 2;
+ break;
+ case 3:
+ relevantDigits = 1;
+ break;
+ default:
+ relevantDigits = 4;
+ break;
+ }
+ formattedNumber = Number(number).toFixed(relevantDigits);
+ }
+ return formattedNumber;
+}
diff --git a/app/assets/javascripts/monitoring/prometheus_graph.js b/app/assets/javascripts/monitoring/prometheus_graph.js
index 844a0785bc9..a6ffa0f59de 100644
--- a/app/assets/javascripts/monitoring/prometheus_graph.js
+++ b/app/assets/javascripts/monitoring/prometheus_graph.js
@@ -1,9 +1,9 @@
-/* eslint-disable no-new*/
+/* eslint-disable no-new */
/* global Flash */
import d3 from 'd3';
import statusCodes from '~/lib/utils/http_status';
-import '../lib/utils/common_utils';
+import { formatRelevantDigits } from '~/lib/utils/number_utils';
import '../flash';
const prometheusGraphsContainer = '.prometheus-graph';
@@ -21,19 +21,19 @@ class PrometheusGraph {
const parentContainerWidth = $(prometheusGraphsContainer).parent().width() +
extraAddedWidthParent;
this.originalWidth = parentContainerWidth;
- this.originalHeight = 400;
+ this.originalHeight = 330;
this.width = parentContainerWidth - this.margin.left - this.margin.right;
- this.height = 400 - this.margin.top - this.margin.bottom;
+ this.height = this.originalHeight - this.margin.top - this.margin.bottom;
this.backOffRequestCounter = 0;
this.configureGraph();
this.init();
}
createGraph() {
- Object.keys(this.data).forEach((key) => {
- const value = this.data[key];
- if (value.length > 0) {
- this.plotValues(value, key);
+ Object.keys(this.graphSpecificProperties).forEach((key) => {
+ const value = this.graphSpecificProperties[key];
+ if (value.data.length > 0) {
+ this.plotValues(key);
}
});
}
@@ -49,53 +49,56 @@ class PrometheusGraph {
});
}
- plotValues(valuesToPlot, key) {
+ plotValues(key) {
+ const graphSpecifics = this.graphSpecificProperties[key];
+
const x = d3.time.scale()
.range([0, this.width]);
const y = d3.scale.linear()
.range([this.height, 0]);
- const prometheusGraphContainer = `${prometheusGraphsContainer}[graph-type=${key}]`;
+ graphSpecifics.xScale = x;
+ graphSpecifics.yScale = y;
- const graphSpecifics = this.graphSpecificProperties[key];
+ const prometheusGraphContainer = `${prometheusGraphsContainer}[graph-type=${key}]`;
const chart = d3.select(prometheusGraphContainer)
- .attr('width', this.width + this.margin.left + this.margin.right)
- .attr('height', this.height + this.margin.bottom + this.margin.top)
- .append('g')
- .attr('transform', `translate(${this.margin.left},${this.margin.top})`);
+ .attr('width', this.width + this.margin.left + this.margin.right)
+ .attr('height', this.height + this.margin.bottom + this.margin.top)
+ .append('g')
+ .attr('transform', `translate(${this.margin.left},${this.margin.top})`);
const axisLabelContainer = d3.select(prometheusGraphContainer)
- .attr('width', this.originalWidth + this.marginLabelContainer.left + this.marginLabelContainer.right)
- .attr('height', this.originalHeight + this.marginLabelContainer.bottom + this.marginLabelContainer.top)
+ .attr('width', this.originalWidth)
+ .attr('height', this.originalHeight)
.append('g')
.attr('transform', `translate(${this.marginLabelContainer.left},${this.marginLabelContainer.top})`);
- x.domain(d3.extent(valuesToPlot, d => d.time));
- y.domain([0, d3.max(valuesToPlot.map(metricValue => metricValue.value))]);
+ x.domain(d3.extent(graphSpecifics.data, d => d.time));
+ y.domain([0, d3.max(graphSpecifics.data.map(metricValue => metricValue.value))]);
const xAxis = d3.svg.axis()
- .scale(x)
- .ticks(this.commonGraphProperties.axis_no_ticks)
- .orient('bottom');
+ .scale(x)
+ .ticks(this.commonGraphProperties.axis_no_ticks)
+ .orient('bottom');
const yAxis = d3.svg.axis()
- .scale(y)
- .ticks(this.commonGraphProperties.axis_no_ticks)
- .tickSize(-this.width)
- .orient('left');
+ .scale(y)
+ .ticks(this.commonGraphProperties.axis_no_ticks)
+ .tickSize(-this.width)
+ .orient('left');
this.createAxisLabelContainers(axisLabelContainer, key);
chart.append('g')
- .attr('class', 'x-axis')
- .attr('transform', `translate(0,${this.height})`)
- .call(xAxis);
+ .attr('class', 'x-axis')
+ .attr('transform', `translate(0,${this.height})`)
+ .call(xAxis);
chart.append('g')
- .attr('class', 'y-axis')
- .call(yAxis);
+ .attr('class', 'y-axis')
+ .call(yAxis);
const area = d3.svg.area()
.x(d => x(d.time))
@@ -108,13 +111,13 @@ class PrometheusGraph {
.y(d => y(d.value));
chart.append('path')
- .datum(valuesToPlot)
- .attr('d', area)
- .attr('class', 'metric-area')
- .attr('fill', graphSpecifics.area_fill_color);
+ .datum(graphSpecifics.data)
+ .attr('d', area)
+ .attr('class', 'metric-area')
+ .attr('fill', graphSpecifics.area_fill_color);
chart.append('path')
- .datum(valuesToPlot)
+ .datum(graphSpecifics.data)
.attr('class', 'metric-line')
.attr('stroke', graphSpecifics.line_color)
.attr('fill', 'none')
@@ -126,7 +129,7 @@ class PrometheusGraph {
.attr('class', 'prometheus-graph-overlay')
.attr('width', this.width)
.attr('height', this.height)
- .on('mousemove', this.handleMouseOverGraph.bind(this, x, y, valuesToPlot, chart, prometheusGraphContainer, key));
+ .on('mousemove', this.handleMouseOverGraph.bind(this, prometheusGraphContainer));
}
// The legends from the metric
@@ -134,128 +137,150 @@ class PrometheusGraph {
const graphSpecifics = this.graphSpecificProperties[key];
axisLabelContainer.append('line')
- .attr('class', 'label-x-axis-line')
- .attr('stroke', '#000000')
- .attr('stroke-width', '1')
- .attr({
- x1: 0,
- y1: this.originalHeight - this.marginLabelContainer.top,
- x2: this.originalWidth - this.margin.right,
- y2: this.originalHeight - this.marginLabelContainer.top,
- });
+ .attr('class', 'label-x-axis-line')
+ .attr('stroke', '#000000')
+ .attr('stroke-width', '1')
+ .attr({
+ x1: 10,
+ y1: this.originalHeight - this.margin.top,
+ x2: (this.originalWidth - this.margin.right) + 10,
+ y2: this.originalHeight - this.margin.top,
+ });
axisLabelContainer.append('line')
- .attr('class', 'label-y-axis-line')
- .attr('stroke', '#000000')
- .attr('stroke-width', '1')
- .attr({
- x1: 0,
- y1: 0,
- x2: 0,
- y2: this.originalHeight - this.marginLabelContainer.top,
- });
+ .attr('class', 'label-y-axis-line')
+ .attr('stroke', '#000000')
+ .attr('stroke-width', '1')
+ .attr({
+ x1: 10,
+ y1: 0,
+ x2: 10,
+ y2: this.originalHeight - this.margin.top,
+ });
+
+ axisLabelContainer.append('rect')
+ .attr('class', 'rect-axis-text')
+ .attr('x', 0)
+ .attr('y', 50)
+ .attr('width', 30)
+ .attr('height', 150);
axisLabelContainer.append('text')
- .attr('class', 'label-axis-text')
- .attr('text-anchor', 'middle')
- .attr('transform', `translate(15, ${(this.originalHeight - this.marginLabelContainer.top) / 2}) rotate(-90)`)
- .text(graphSpecifics.graph_legend_title);
+ .attr('class', 'label-axis-text')
+ .attr('text-anchor', 'middle')
+ .attr('transform', `translate(15, ${(this.originalHeight - this.margin.top) / 2}) rotate(-90)`)
+ .text(graphSpecifics.graph_legend_title);
axisLabelContainer.append('rect')
- .attr('class', 'rect-axis-text')
- .attr('x', (this.originalWidth / 2) - this.margin.right)
- .attr('y', this.originalHeight - this.marginLabelContainer.top - 20)
- .attr('width', 30)
- .attr('height', 80);
+ .attr('class', 'rect-axis-text')
+ .attr('x', (this.originalWidth / 2) - this.margin.right)
+ .attr('y', this.originalHeight - 100)
+ .attr('width', 30)
+ .attr('height', 80);
axisLabelContainer.append('text')
- .attr('class', 'label-axis-text')
- .attr('x', (this.originalWidth / 2) - this.margin.right)
- .attr('y', this.originalHeight - this.marginLabelContainer.top)
- .attr('dy', '.35em')
- .text('Time');
+ .attr('class', 'label-axis-text')
+ .attr('x', (this.originalWidth / 2) - this.margin.right)
+ .attr('y', this.originalHeight - this.margin.top)
+ .attr('dy', '.35em')
+ .text('Time');
// Legends
// Metric Usage
axisLabelContainer.append('rect')
- .attr('x', this.originalWidth - 170)
- .attr('y', (this.originalHeight / 2) - 60)
- .style('fill', graphSpecifics.area_fill_color)
- .attr('width', 20)
- .attr('height', 35);
+ .attr('x', this.originalWidth - 170)
+ .attr('y', (this.originalHeight / 2) - 60)
+ .style('fill', graphSpecifics.area_fill_color)
+ .attr('width', 20)
+ .attr('height', 35);
axisLabelContainer.append('text')
- .attr('class', 'label-axis-text')
- .attr('x', this.originalWidth - 140)
- .attr('y', (this.originalHeight / 2) - 50)
- .text('Average');
+ .attr('class', 'text-metric-title')
+ .attr('x', this.originalWidth - 140)
+ .attr('y', (this.originalHeight / 2) - 50)
+ .text('Average');
axisLabelContainer.append('text')
- .attr('class', 'text-metric-usage')
- .attr('x', this.originalWidth - 140)
- .attr('y', (this.originalHeight / 2) - 25);
+ .attr('class', 'text-metric-usage')
+ .attr('x', this.originalWidth - 140)
+ .attr('y', (this.originalHeight / 2) - 25);
}
- handleMouseOverGraph(x, y, valuesToPlot, chart, prometheusGraphContainer, key) {
+ handleMouseOverGraph(prometheusGraphContainer) {
const rectOverlay = document.querySelector(`${prometheusGraphContainer} .prometheus-graph-overlay`);
- const timeValueFromOverlay = x.invert(d3.mouse(rectOverlay)[0]);
- const timeValueIndex = bisectDate(valuesToPlot, timeValueFromOverlay, 1);
- const d0 = valuesToPlot[timeValueIndex - 1];
- const d1 = valuesToPlot[timeValueIndex];
- const currentData = timeValueFromOverlay - d0.time > d1.time - timeValueFromOverlay ? d1 : d0;
- const maxValueMetric = y(d3.max(valuesToPlot.map(metricValue => metricValue.value)));
- const currentTimeCoordinate = x(currentData.time);
- const graphSpecifics = this.graphSpecificProperties[key];
- // Remove the current selectors
- d3.selectAll(`${prometheusGraphContainer} .selected-metric-line`).remove();
- d3.selectAll(`${prometheusGraphContainer} .circle-metric`).remove();
- d3.selectAll(`${prometheusGraphContainer} .rect-text-metric`).remove();
- d3.selectAll(`${prometheusGraphContainer} .text-metric`).remove();
-
- chart.append('line')
- .attr('class', 'selected-metric-line')
- .attr({
- x1: currentTimeCoordinate,
- y1: y(0),
- x2: currentTimeCoordinate,
- y2: maxValueMetric,
- });
+ const currentXCoordinate = d3.mouse(rectOverlay)[0];
+
+ Object.keys(this.graphSpecificProperties).forEach((key) => {
+ const currentGraphProps = this.graphSpecificProperties[key];
+ const timeValueOverlay = currentGraphProps.xScale.invert(currentXCoordinate);
+ const overlayIndex = bisectDate(currentGraphProps.data, timeValueOverlay, 1);
+ const d0 = currentGraphProps.data[overlayIndex - 1];
+ const d1 = currentGraphProps.data[overlayIndex];
+ const evalTime = timeValueOverlay - d0.time > d1.time - timeValueOverlay;
+ const currentData = evalTime ? d1 : d0;
+ const currentTimeCoordinate = currentGraphProps.xScale(currentData.time);
+ const currentPrometheusGraphContainer = `${prometheusGraphsContainer}[graph-type=${key}]`;
+ const maxValueFromData = d3.max(currentGraphProps.data.map(metricValue => metricValue.value));
+ const maxMetricValue = currentGraphProps.yScale(maxValueFromData);
+
+ // Clear up all the pieces of the flag
+ d3.selectAll(`${currentPrometheusGraphContainer} .selected-metric-line`).remove();
+ d3.selectAll(`${currentPrometheusGraphContainer} .circle-metric`).remove();
+ d3.selectAll(`${currentPrometheusGraphContainer} .rect-text-metric`).remove();
+ d3.selectAll(`${currentPrometheusGraphContainer} .text-metric`).remove();
+
+ const currentChart = d3.select(currentPrometheusGraphContainer).select('g');
+ currentChart.append('line')
+ .attr('class', 'selected-metric-line')
+ .attr({
+ x1: currentTimeCoordinate,
+ y1: currentGraphProps.yScale(0),
+ x2: currentTimeCoordinate,
+ y2: maxMetricValue,
+ });
+
+ currentChart.append('circle')
+ .attr('class', 'circle-metric')
+ .attr('fill', currentGraphProps.line_color)
+ .attr('cx', currentTimeCoordinate)
+ .attr('cy', currentGraphProps.yScale(currentData.value))
+ .attr('r', this.commonGraphProperties.circle_radius_metric);
+
+ // The little box with text
+ const rectTextMetric = currentChart.append('g')
+ .attr('class', 'rect-text-metric')
+ .attr('translate', `(${currentTimeCoordinate}, ${currentGraphProps.yScale(currentData.value)})`);
+
+ rectTextMetric.append('rect')
+ .attr('class', 'rect-metric')
+ .attr('x', currentTimeCoordinate + 10)
+ .attr('y', maxMetricValue)
+ .attr('width', this.commonGraphProperties.rect_text_width)
+ .attr('height', this.commonGraphProperties.rect_text_height);
+
+ rectTextMetric.append('text')
+ .attr('class', 'text-metric')
+ .attr('x', currentTimeCoordinate + 35)
+ .attr('y', maxMetricValue + 35)
+ .text(timeFormat(currentData.time));
+
+ rectTextMetric.append('text')
+ .attr('class', 'text-metric-date')
+ .attr('x', currentTimeCoordinate + 15)
+ .attr('y', maxMetricValue + 15)
+ .text(dayFormat(currentData.time));
+
+ let currentMetricValue = formatRelevantDigits(currentData.value);
+ if (key === 'cpu_values') {
+ currentMetricValue = `${currentMetricValue}%`;
+ } else {
+ currentMetricValue = `${currentMetricValue} MB`;
+ }
- chart.append('circle')
- .attr('class', 'circle-metric')
- .attr('fill', graphSpecifics.line_color)
- .attr('cx', currentTimeCoordinate)
- .attr('cy', y(currentData.value))
- .attr('r', this.commonGraphProperties.circle_radius_metric);
-
- // The little box with text
- const rectTextMetric = chart.append('g')
- .attr('class', 'rect-text-metric')
- .attr('translate', `(${currentTimeCoordinate}, ${y(currentData.value)})`);
-
- rectTextMetric.append('rect')
- .attr('class', 'rect-metric')
- .attr('x', currentTimeCoordinate + 10)
- .attr('y', maxValueMetric)
- .attr('width', this.commonGraphProperties.rect_text_width)
- .attr('height', this.commonGraphProperties.rect_text_height);
-
- rectTextMetric.append('text')
- .attr('class', 'text-metric')
- .attr('x', currentTimeCoordinate + 35)
- .attr('y', maxValueMetric + 35)
- .text(timeFormat(currentData.time));
-
- rectTextMetric.append('text')
- .attr('class', 'text-metric-date')
- .attr('x', currentTimeCoordinate + 15)
- .attr('y', maxValueMetric + 15)
- .text(dayFormat(currentData.time));
-
- // Update the text
- d3.select(`${prometheusGraphContainer} .text-metric-usage`)
- .text(currentData.value.substring(0, 8));
+ d3.select(`${currentPrometheusGraphContainer} .text-metric-usage`)
+ .text(currentMetricValue);
+ });
}
configureGraph() {
@@ -263,12 +288,18 @@ class PrometheusGraph {
cpu_values: {
area_fill_color: '#edf3fc',
line_color: '#5b99f7',
- graph_legend_title: 'CPU utilization (%)',
+ graph_legend_title: 'CPU Usage (Cores)',
+ data: [],
+ xScale: {},
+ yScale: {},
},
memory_values: {
area_fill_color: '#fca326',
line_color: '#fc6d26',
- graph_legend_title: 'Memory usage (MB)',
+ graph_legend_title: 'Memory Usage (MB)',
+ data: [],
+ xScale: {},
+ yScale: {},
},
};
@@ -318,17 +349,17 @@ class PrometheusGraph {
}
transformData(metricsResponse) {
- const metricTypes = {};
Object.keys(metricsResponse.metrics).forEach((key) => {
if (key === 'cpu_values' || key === 'memory_values') {
const metricValues = (metricsResponse.metrics[key])[0];
- metricTypes[key] = metricValues.values.map(metric => ({
- time: new Date(metric[0] * 1000),
- value: metric[1],
- }));
+ if (typeof metricValues !== 'undefined') {
+ this.graphSpecificProperties[key].data = metricValues.values.map(metric => ({
+ time: new Date(metric[0] * 1000),
+ value: metric[1],
+ }));
+ }
}
});
- this.data = metricTypes;
}
}
diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss
index 3d91e0b22d8..6faa3794c83 100644
--- a/app/assets/stylesheets/pages/environments.scss
+++ b/app/assets/stylesheets/pages/environments.scss
@@ -159,6 +159,16 @@
text {
fill: $stat-graph-axis-fill;
}
+
+ .label-axis-text,
+ .text-metric-usage {
+ fill: $black;
+ font-weight: 500;
+ }
+
+ .legend-axis-text {
+ fill: $black;
+ }
}
.x-axis path,
diff --git a/app/views/projects/environments/_external_url.html.haml b/app/views/projects/environments/_external_url.html.haml
index bf0f1819073..a82ef5ee5bb 100644
--- a/app/views/projects/environments/_external_url.html.haml
+++ b/app/views/projects/environments/_external_url.html.haml
@@ -1,3 +1,4 @@
- if environment.external_url && can?(current_user, :read_environment, environment)
= link_to environment.external_url, target: '_blank', rel: 'noopener noreferrer', class: 'btn external-url' do
= icon('external-link')
+ View deployment
diff --git a/app/views/projects/environments/_metrics_button.html.haml b/app/views/projects/environments/_metrics_button.html.haml
index acbac1869fd..e27281d6917 100644
--- a/app/views/projects/environments/_metrics_button.html.haml
+++ b/app/views/projects/environments/_metrics_button.html.haml
@@ -4,3 +4,4 @@
= link_to environment_metrics_path(environment), title: 'See metrics', class: 'btn metrics-button' do
= icon('area-chart')
+ Monitoring
diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml
index 3b45162df52..92dc58cd38d 100644
--- a/app/views/projects/environments/metrics.html.haml
+++ b/app/views/projects/environments/metrics.html.haml
@@ -11,7 +11,7 @@
.col-sm-6
%h3.page-title
Environment:
- = @environment.name
+ = link_to @environment.name, environment_path(@environment)
.col-sm-6
.nav-controls
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index f463a429f65..ff6aaebda22 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -4,9 +4,9 @@
%div{ class: container_class }
.top-area.adjust
- .col-md-9
+ .col-md-7
%h3.page-title= @environment.name
- .col-md-3
+ .col-md-5
.nav-controls
= render 'projects/environments/metrics_button', environment: @environment
= render 'projects/environments/terminal_button', environment: @environment
diff --git a/changelogs/unreleased/environment-performance-improvements.yml b/changelogs/unreleased/environment-performance-improvements.yml
new file mode 100644
index 00000000000..43e8f0afcee
--- /dev/null
+++ b/changelogs/unreleased/environment-performance-improvements.yml
@@ -0,0 +1,4 @@
+---
+title: Improved UX for the environments metrics view
+merge_request: 9946
+author:
diff --git a/spec/javascripts/lib/utils/number_utility_spec.js b/spec/javascripts/lib/utils/number_utility_spec.js
new file mode 100644
index 00000000000..5fde8be9123
--- /dev/null
+++ b/spec/javascripts/lib/utils/number_utility_spec.js
@@ -0,0 +1,41 @@
+import { formatRelevantDigits } from '~/lib/utils/number_utils';
+
+describe('Number Utils', () => {
+ describe('formatRelevantDigits', () => {
+ it('returns an empty string when the number is NaN', () => {
+ expect(formatRelevantDigits('fail')).toBe('');
+ });
+
+ it('returns 4 decimals when there is 4 plus digits to the left', () => {
+ const formattedNumber = formatRelevantDigits('1000.1234567');
+ const rightFromDecimal = formattedNumber.split('.')[1];
+ const leftFromDecimal = formattedNumber.split('.')[0];
+ expect(rightFromDecimal.length).toBe(4);
+ expect(leftFromDecimal.length).toBe(4);
+ });
+
+ it('returns 3 decimals when there is 1 digit to the left', () => {
+ const formattedNumber = formatRelevantDigits('0.1234567');
+ const rightFromDecimal = formattedNumber.split('.')[1];
+ const leftFromDecimal = formattedNumber.split('.')[0];
+ expect(rightFromDecimal.length).toBe(3);
+ expect(leftFromDecimal.length).toBe(1);
+ });
+
+ it('returns 2 decimals when there is 2 digits to the left', () => {
+ const formattedNumber = formatRelevantDigits('10.1234567');
+ const rightFromDecimal = formattedNumber.split('.')[1];
+ const leftFromDecimal = formattedNumber.split('.')[0];
+ expect(rightFromDecimal.length).toBe(2);
+ expect(leftFromDecimal.length).toBe(2);
+ });
+
+ it('returns 1 decimal when there is 3 digits to the left', () => {
+ const formattedNumber = formatRelevantDigits('100.1234567');
+ const rightFromDecimal = formattedNumber.split('.')[1];
+ const leftFromDecimal = formattedNumber.split('.')[0];
+ expect(rightFromDecimal.length).toBe(1);
+ expect(leftFromDecimal.length).toBe(3);
+ });
+ });
+});
diff --git a/spec/javascripts/monitoring/prometheus_graph_spec.js b/spec/javascripts/monitoring/prometheus_graph_spec.js
index a3c1c5e1b7c..c2bcd9c0f7c 100644
--- a/spec/javascripts/monitoring/prometheus_graph_spec.js
+++ b/spec/javascripts/monitoring/prometheus_graph_spec.js
@@ -37,9 +37,11 @@ describe('PrometheusGraph', () => {
it('transforms the data', () => {
this.prometheusGraph.init(prometheusMockData.metrics);
- expect(this.prometheusGraph.data).toBeDefined();
- expect(this.prometheusGraph.data.cpu_values.length).toBe(121);
- expect(this.prometheusGraph.data.memory_values.length).toBe(121);
+ Object.keys(this.prometheusGraph.graphSpecificProperties, (key) => {
+ const graphProps = this.prometheusGraph.graphSpecificProperties[key];
+ expect(graphProps.data).toBeDefined();
+ expect(graphProps.data.length).toBe(121);
+ });
});
it('creates two graphs', () => {
@@ -68,7 +70,7 @@ describe('PrometheusGraph', () => {
expect($prometheusGraphContents.find('.label-y-axis-line')).toBeDefined();
expect($prometheusGraphContents.find('.label-axis-text')).toBeDefined();
expect($prometheusGraphContents.find('.rect-axis-text')).toBeDefined();
- expect($axisLabelContainer.find('rect').length).toBe(2);
+ expect($axisLabelContainer.find('rect').length).toBe(3);
expect($axisLabelContainer.find('text').length).toBe(4);
});
});