summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2019-02-01 08:37:48 +0000
committerPhil Hughes <me@iamphill.com>2019-02-01 08:37:48 +0000
commitfec135cb79698947dc4bd725dab4ab0279fc2a46 (patch)
treebac7b3e285eb91081501f4057711e7ce5becda18
parentc12863322595e77b03a5a089ff079bf13574a57b (diff)
parente7bb9b95e8b7dc29d6cf8417d74f249fc89d23b3 (diff)
downloadgitlab-ce-fec135cb79698947dc4bd725dab4ab0279fc2a46.tar.gz
Merge branch 'adriel-remove-d3-metrics-graph' into 'master'
Remove d3 metrics graph See merge request gitlab-org/gitlab-ce!24647
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue36
-rw-r--r--app/assets/javascripts/monitoring/components/graph.vue329
-rw-r--r--app/assets/javascripts/monitoring/components/graph/axis.vue118
-rw-r--r--app/assets/javascripts/monitoring/components/graph/deployment.vue48
-rw-r--r--app/assets/javascripts/monitoring/components/graph/flag.vue151
-rw-r--r--app/assets/javascripts/monitoring/components/graph/legend.vue62
-rw-r--r--app/assets/javascripts/monitoring/components/graph/path.vue65
-rw-r--r--app/assets/javascripts/monitoring/components/graph/track_info.vue28
-rw-r--r--app/assets/javascripts/monitoring/components/graph/track_line.vue33
-rw-r--r--app/assets/javascripts/monitoring/event_hub.js3
-rw-r--r--app/assets/javascripts/monitoring/mixins/monitoring_mixins.js86
-rw-r--r--app/assets/javascripts/monitoring/utils/date_time_formatters.js42
-rw-r--r--app/assets/javascripts/monitoring/utils/measurements.js44
-rw-r--r--app/assets/javascripts/monitoring/utils/multiple_time_series.js223
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/javascripts/monitoring/graph/axis_spec.js65
-rw-r--r--spec/javascripts/monitoring/graph/deployment_spec.js53
-rw-r--r--spec/javascripts/monitoring/graph/flag_spec.js133
-rw-r--r--spec/javascripts/monitoring/graph/legend_spec.js44
-rw-r--r--spec/javascripts/monitoring/graph/track_info_spec.js44
-rw-r--r--spec/javascripts/monitoring/graph/track_line_spec.js52
-rw-r--r--spec/javascripts/monitoring/graph_path_spec.js56
-rw-r--r--spec/javascripts/monitoring/graph_spec.js127
-rw-r--r--spec/javascripts/monitoring/utils/multiple_time_series_spec.js22
24 files changed, 2 insertions, 1868 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 973fc8e10c9..0b4bb9cc686 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -6,15 +6,12 @@ import Flash from '../../flash';
import MonitoringService from '../services/monitoring_service';
import MonitorAreaChart from './charts/area.vue';
import GraphGroup from './graph_group.vue';
-import Graph from './graph.vue';
import EmptyState from './empty_state.vue';
import MonitoringStore from '../stores/monitoring_store';
-import eventHub from '../event_hub';
export default {
components: {
MonitorAreaChart,
- Graph,
GraphGroup,
EmptyState,
Icon,
@@ -25,21 +22,11 @@ export default {
required: false,
default: true,
},
- showLegend: {
- type: Boolean,
- required: false,
- default: true,
- },
showPanels: {
type: Boolean,
required: false,
default: true,
},
- forceSmallGraph: {
- type: Boolean,
- required: false,
- default: false,
- },
documentationPath: {
type: String,
required: true,
@@ -99,14 +86,10 @@ export default {
store: new MonitoringStore(),
state: 'gettingStarted',
showEmptyState: true,
- hoverData: {},
elWidth: 0,
};
},
computed: {
- graphComponent() {
- return gon.features && gon.features.areaChart ? MonitorAreaChart : Graph;
- },
forceRedraw() {
return this.elWidth;
},
@@ -122,10 +105,8 @@ export default {
childList: false,
subtree: false,
};
- eventHub.$on('hoverChanged', this.hoverChanged);
},
beforeDestroy() {
- eventHub.$off('hoverChanged', this.hoverChanged);
window.removeEventListener('resize', this.resizeThrottled, false);
this.sidebarMutationObserver.disconnect();
},
@@ -176,9 +157,6 @@ export default {
resize() {
this.elWidth = this.$el.clientWidth;
},
- hoverChanged(data) {
- this.hoverData = data;
- },
},
};
</script>
@@ -215,23 +193,13 @@ export default {
:name="groupData.group"
:show-panels="showPanels"
>
- <component
- :is="graphComponent"
+ <monitor-area-chart
v-for="(graphData, graphIndex) in groupData.metrics"
:key="graphIndex"
:graph-data="graphData"
- :hover-data="hoverData"
- :deployment-data="store.deploymentData"
- :project-path="projectPath"
- :tags-path="tagsPath"
- :show-legend="showLegend"
- :small-graph="forceSmallGraph"
:alert-data="getGraphAlerts(graphData.id)"
group-id="monitor-area-chart"
- >
- <!-- EE content -->
- {{ null }}
- </component>
+ />
</graph-group>
</div>
<empty-state
diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue
deleted file mode 100644
index 309b73f5a4d..00000000000
--- a/app/assets/javascripts/monitoring/components/graph.vue
+++ /dev/null
@@ -1,329 +0,0 @@
-<script>
-import { scaleLinear, scaleTime } from 'd3-scale';
-import { axisLeft, axisBottom } from 'd3-axis';
-import _ from 'underscore';
-import { max, extent } from 'd3-array';
-import { select } from 'd3-selection';
-import GraphAxis from './graph/axis.vue';
-import GraphLegend from './graph/legend.vue';
-import GraphFlag from './graph/flag.vue';
-import GraphDeployment from './graph/deployment.vue';
-import GraphPath from './graph/path.vue';
-import MonitoringMixin from '../mixins/monitoring_mixins';
-import eventHub from '../event_hub';
-import measurements from '../utils/measurements';
-import { bisectDate, timeScaleFormat } from '../utils/date_time_formatters';
-import createTimeSeries from '../utils/multiple_time_series';
-import bp from '../../breakpoints';
-
-const d3 = { scaleLinear, scaleTime, axisLeft, axisBottom, max, extent, select };
-
-export default {
- components: {
- GraphAxis,
- GraphFlag,
- GraphDeployment,
- GraphPath,
- GraphLegend,
- },
- mixins: [MonitoringMixin],
- props: {
- graphData: {
- type: Object,
- required: true,
- },
- deploymentData: {
- type: Array,
- required: true,
- },
- hoverData: {
- type: Object,
- required: false,
- default: () => ({}),
- },
- projectPath: {
- type: String,
- required: true,
- },
- tagsPath: {
- type: String,
- required: true,
- },
- showLegend: {
- type: Boolean,
- required: false,
- default: true,
- },
- smallGraph: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- data() {
- return {
- baseGraphHeight: 450,
- baseGraphWidth: 600,
- graphHeight: 450,
- graphWidth: 600,
- graphHeightOffset: 120,
- margin: {},
- unitOfDisplay: '',
- yAxisLabel: '',
- legendTitle: '',
- reducedDeploymentData: [],
- measurements: measurements.large,
- currentData: {
- time: new Date(),
- value: 0,
- },
- currentXCoordinate: 0,
- currentCoordinates: {},
- showFlag: false,
- showFlagContent: false,
- timeSeries: [],
- graphDrawData: {},
- realPixelRatio: 1,
- seriesUnderMouse: [],
- };
- },
- computed: {
- outerViewBox() {
- return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`;
- },
- innerViewBox() {
- return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
- },
- axisTransform() {
- return `translate(70, ${this.graphHeight - 100})`;
- },
- paddingBottomRootSvg() {
- return {
- paddingBottom: `${Math.ceil(this.baseGraphHeight * 100) / this.baseGraphWidth || 0}%`,
- };
- },
- deploymentFlagData() {
- return this.reducedDeploymentData.find(deployment => deployment.showDeploymentFlag);
- },
- shouldRenderData() {
- return this.graphData.queries.filter(s => s.result.length > 0).length > 0;
- },
- },
- watch: {
- hoverData() {
- this.positionFlag();
- },
- },
- mounted() {
- this.draw();
- },
- methods: {
- showDot(path) {
- return this.showFlagContent && this.seriesUnderMouse.includes(path);
- },
- draw() {
- const breakpointSize = bp.getBreakpointSize();
- const svgWidth = this.$refs.baseSvg.getBoundingClientRect().width;
-
- this.margin = measurements.large.margin;
-
- if (this.smallGraph || breakpointSize === 'xs' || breakpointSize === 'sm') {
- this.graphHeight = 300;
- this.margin = measurements.small.margin;
- this.measurements = measurements.small;
- }
-
- this.yAxisLabel = this.graphData.y_label || 'Values';
- this.graphWidth = svgWidth - this.margin.left - this.margin.right;
- this.graphHeight = this.graphHeight - this.margin.top - this.margin.bottom;
- this.baseGraphHeight = this.graphHeight - 50;
- this.baseGraphWidth = this.graphWidth;
-
- // pixel offsets inside the svg and outside are not 1:1
- this.realPixelRatio = svgWidth / this.baseGraphWidth;
-
- // set the legends on the axes
- const [query] = this.graphData.queries;
- this.legendTitle = query ? query.label : 'Average';
- this.unitOfDisplay = query ? query.unit : '';
-
- if (this.shouldRenderData) {
- this.renderAxesPaths();
- this.formatDeployments();
- }
- },
- handleMouseOverGraph(e) {
- let point = this.$refs.graphData.createSVGPoint();
- point.x = e.clientX;
- point.y = e.clientY;
- point = point.matrixTransform(this.$refs.graphData.getScreenCTM().inverse());
- point.x += 7;
-
- this.seriesUnderMouse = this.timeSeries.filter(series => {
- const mouseX = series.timeSeriesScaleX.invert(point.x);
- let minDistance = Infinity;
-
- const closestTickMark = Object.keys(this.allXAxisValues).reduce((closest, x) => {
- const distance = Math.abs(Number(new Date(x)) - Number(mouseX));
- if (distance < minDistance) {
- minDistance = distance;
- return x;
- }
- return closest;
- });
-
- return series.values.find(v => v.time.toString() === closestTickMark);
- });
-
- const firstTimeSeries = this.seriesUnderMouse[0];
- const timeValueOverlay = firstTimeSeries.timeSeriesScaleX.invert(point.x);
- const overlayIndex = bisectDate(firstTimeSeries.values, timeValueOverlay, 1);
- const d0 = firstTimeSeries.values[overlayIndex - 1];
- const d1 = firstTimeSeries.values[overlayIndex];
- if (d0 === undefined || d1 === undefined) return;
- const evalTime = timeValueOverlay - d0[0] > d1[0] - timeValueOverlay;
- const hoveredDataIndex = evalTime ? overlayIndex : overlayIndex - 1;
- const hoveredDate = firstTimeSeries.values[hoveredDataIndex].time;
- const currentDeployXPos = this.mouseOverDeployInfo(point.x);
-
- eventHub.$emit('hoverChanged', {
- hoveredDate,
- currentDeployXPos,
- });
- },
- renderAxesPaths() {
- ({ timeSeries: this.timeSeries, graphDrawData: this.graphDrawData } = createTimeSeries(
- this.graphData.queries,
- this.graphWidth,
- this.graphHeight,
- this.graphHeightOffset,
- ));
-
- if (_.findWhere(this.timeSeries, { renderCanary: true })) {
- this.timeSeries = this.timeSeries.map(series => ({ ...series, renderCanary: true }));
- }
-
- const axisXScale = d3.scaleTime().range([0, this.graphWidth - 70]);
- const axisYScale = d3.scaleLinear().range([this.graphHeight - this.graphHeightOffset, 0]);
-
- const allValues = this.timeSeries.reduce((all, { values }) => all.concat(values), []);
- axisXScale.domain(d3.extent(allValues, d => d.time));
- axisYScale.domain([0, d3.max(allValues.map(d => d.value))]);
-
- this.allXAxisValues = this.timeSeries.reduce((obj, series) => {
- const seriesKeys = {};
- series.values.forEach(v => {
- seriesKeys[v.time] = true;
- });
- return {
- ...obj,
- ...seriesKeys,
- };
- }, {});
-
- const xAxis = d3
- .axisBottom()
- .scale(axisXScale)
- .ticks(this.graphWidth / 120)
- .tickFormat(timeScaleFormat);
-
- const yAxis = d3
- .axisLeft()
- .scale(axisYScale)
- .ticks(measurements.yTicks);
-
- d3.select(this.$refs.baseSvg)
- .select('.x-axis')
- .call(xAxis);
-
- const width = this.graphWidth;
- d3.select(this.$refs.baseSvg)
- .select('.y-axis')
- .call(yAxis)
- .selectAll('.tick')
- .each(function createTickLines(d, i) {
- if (i > 0) {
- d3.select(this)
- .select('line')
- .attr('x2', width)
- .attr('class', 'axis-tick');
- } // Avoid adding the class to the first tick, to prevent coloring
- }); // This will select all of the ticks once they're rendered
- },
- },
-};
-</script>
-
-<template>
- <div
- class="prometheus-graph"
- @mouseover="showFlagContent = true"
- @mouseleave="showFlagContent = false"
- >
- <div class="prometheus-graph-header">
- <h5 class="prometheus-graph-title">{{ graphData.title }}</h5>
- <div class="prometheus-graph-widgets"><slot></slot></div>
- </div>
- <div :style="paddingBottomRootSvg" class="prometheus-svg-container">
- <svg ref="baseSvg" :viewBox="outerViewBox">
- <g :transform="axisTransform" class="x-axis" />
- <g class="y-axis" transform="translate(70, 20)" />
- <graph-axis
- :graph-width="graphWidth"
- :graph-height="graphHeight"
- :margin="margin"
- :measurements="measurements"
- :y-axis-label="yAxisLabel"
- :unit-of-display="unitOfDisplay"
- />
- <svg v-if="shouldRenderData" ref="graphData" :viewBox="innerViewBox" class="graph-data">
- <slot name="additionalSvgContent" :graphDrawData="graphDrawData" />
- <graph-path
- v-for="(path, index) in timeSeries"
- :key="index"
- :generated-line-path="path.linePath"
- :generated-area-path="path.areaPath"
- :line-style="path.lineStyle"
- :line-color="path.lineColor"
- :area-color="path.areaColor"
- :current-coordinates="currentCoordinates[path.metricTag]"
- :show-dot="showDot(path)"
- />
- <graph-deployment
- :deployment-data="reducedDeploymentData"
- :graph-height="graphHeight"
- :graph-height-offset="graphHeightOffset"
- />
- <rect
- ref="graphOverlay"
- :width="graphWidth - 70"
- :height="graphHeight - 100"
- class="prometheus-graph-overlay"
- transform="translate(-5, 20)"
- @mousemove="handleMouseOverGraph($event)"
- />
- </svg>
- <svg v-else :viewBox="innerViewBox" class="js-no-data-to-display">
- <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">
- {{ s__('Metrics|No data to display') }}
- </text>
- </svg>
- </svg>
- <graph-flag
- v-if="shouldRenderData"
- :real-pixel-ratio="realPixelRatio"
- :current-x-coordinate="currentXCoordinate"
- :current-data="currentData"
- :graph-height="graphHeight"
- :graph-height-offset="graphHeightOffset"
- :show-flag-content="showFlagContent"
- :time-series="seriesUnderMouse"
- :unit-of-display="unitOfDisplay"
- :legend-title="legendTitle"
- :deployment-flag-data="deploymentFlagData"
- :current-coordinates="currentCoordinates"
- />
- </div>
- <graph-legend v-if="showLegend" :legend-title="legendTitle" :time-series="timeSeries" />
- </div>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/axis.vue b/app/assets/javascripts/monitoring/components/graph/axis.vue
deleted file mode 100644
index 8f046857a20..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/axis.vue
+++ /dev/null
@@ -1,118 +0,0 @@
-<script>
-import { convertToSentenceCase } from '~/lib/utils/text_utility';
-import { s__ } from '~/locale';
-
-export default {
- props: {
- graphWidth: {
- type: Number,
- required: true,
- },
- graphHeight: {
- type: Number,
- required: true,
- },
- margin: {
- type: Object,
- required: true,
- },
- measurements: {
- type: Object,
- required: true,
- },
- yAxisLabel: {
- type: String,
- required: true,
- },
- unitOfDisplay: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- yLabelWidth: 0,
- yLabelHeight: 0,
- };
- },
- computed: {
- textTransform() {
- const yCoordinate =
- (this.graphHeight - this.margin.top + this.measurements.axisLabelLineOffset) / 2 || 0;
-
- return `translate(15, ${yCoordinate}) rotate(-90)`;
- },
-
- rectTransform() {
- const yCoordinate =
- (this.graphHeight - this.margin.top + this.measurements.axisLabelLineOffset) / 2 +
- this.yLabelWidth / 2 || 0;
-
- return `translate(0, ${yCoordinate}) rotate(-90)`;
- },
-
- xPosition() {
- return (this.graphWidth + this.measurements.axisLabelLineOffset) / 2 - this.margin.right || 0;
- },
-
- yPosition() {
- return this.graphHeight - this.margin.top + this.measurements.axisLabelLineOffset || 0;
- },
-
- yAxisLabelSentenceCase() {
- return `${convertToSentenceCase(this.yAxisLabel)} (${this.unitOfDisplay})`;
- },
-
- timeString() {
- return s__('PrometheusDashboard|Time');
- },
- },
- mounted() {
- this.$nextTick(() => {
- const bbox = this.$refs.ylabel.getBBox();
- this.yLabelWidth = bbox.width + 10; // Added some padding
- this.yLabelHeight = bbox.height + 5;
- });
- },
-};
-</script>
-<template>
- <g class="axis-label-container">
- <line
- :y1="yPosition"
- :x2="graphWidth + 20"
- :y2="yPosition"
- class="label-x-axis-line"
- stroke="#000000"
- stroke-width="1"
- x1="10"
- />
- <line
- :x2="10"
- :y2="yPosition"
- class="label-y-axis-line"
- stroke="#000000"
- stroke-width="1"
- x1="10"
- y1="0"
- />
- <rect
- :transform="rectTransform"
- :width="yLabelWidth"
- :height="yLabelHeight"
- class="rect-axis-text"
- />
- <text
- ref="ylabel"
- :transform="textTransform"
- class="label-axis-text y-label-text"
- text-anchor="middle"
- >
- {{ yAxisLabelSentenceCase }}
- </text>
- <rect :x="xPosition + 60" :y="graphHeight - 80" class="rect-axis-text" width="35" height="50" />
- <text :x="xPosition + 60" :y="yPosition" class="label-axis-text x-label-text" dy=".35em">
- {{ timeString }}
- </text>
- </g>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/deployment.vue b/app/assets/javascripts/monitoring/components/graph/deployment.vue
deleted file mode 100644
index bee9784692c..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/deployment.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-<script>
-export default {
- props: {
- deploymentData: {
- type: Array,
- required: true,
- },
- graphHeight: {
- type: Number,
- required: true,
- },
- graphHeightOffset: {
- type: Number,
- required: true,
- },
- },
- computed: {
- calculatedHeight() {
- return this.graphHeight - this.graphHeightOffset;
- },
- },
- methods: {
- transformDeploymentGroup(deployment) {
- return `translate(${Math.floor(deployment.xPos) - 5}, 20)`;
- },
- },
-};
-</script>
-<template>
- <g class="deploy-info">
- <g
- v-for="(deployment, index) in deploymentData"
- :key="index"
- :transform="transformDeploymentGroup(deployment)"
- >
- <rect :height="calculatedHeight" x="0" y="0" width="3" fill="url(#shadow-gradient)" />
- <line :y2="calculatedHeight" class="deployment-line" x1="0" y1="0" x2="0" stroke="#000" />
- </g>
- <svg height="0" width="0">
- <defs>
- <linearGradient id="shadow-gradient">
- <stop offset="0%" stop-color="#000" stop-opacity="0.4" />
- <stop offset="100%" stop-color="#000" stop-opacity="0" />
- </linearGradient>
- </defs>
- </svg>
- </g>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue
deleted file mode 100644
index 9d6d1caef80..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/flag.vue
+++ /dev/null
@@ -1,151 +0,0 @@
-<script>
-import { dateFormat, timeFormat } from '../../utils/date_time_formatters';
-import { formatRelevantDigits } from '../../../lib/utils/number_utils';
-import Icon from '../../../vue_shared/components/icon.vue';
-import TrackLine from './track_line.vue';
-
-export default {
- components: {
- Icon,
- TrackLine,
- },
- props: {
- currentXCoordinate: {
- type: Number,
- required: true,
- },
- currentData: {
- type: Object,
- required: true,
- },
- deploymentFlagData: {
- type: Object,
- required: false,
- default: null,
- },
- graphHeight: {
- type: Number,
- required: true,
- },
- graphHeightOffset: {
- type: Number,
- required: true,
- },
- realPixelRatio: {
- type: Number,
- required: true,
- },
- showFlagContent: {
- type: Boolean,
- required: true,
- },
- timeSeries: {
- type: Array,
- required: true,
- },
- unitOfDisplay: {
- type: String,
- required: true,
- },
- legendTitle: {
- type: String,
- required: true,
- },
- currentCoordinates: {
- type: Object,
- required: true,
- },
- },
- computed: {
- formatTime() {
- return this.deploymentFlagData
- ? timeFormat(this.deploymentFlagData.time)
- : timeFormat(this.currentData.time);
- },
- formatDate() {
- return this.deploymentFlagData
- ? dateFormat(this.deploymentFlagData.time)
- : dateFormat(this.currentData.time);
- },
- cursorStyle() {
- const xCoordinate = this.deploymentFlagData
- ? this.deploymentFlagData.xPos
- : this.currentXCoordinate;
-
- const offsetTop = 20 * this.realPixelRatio;
- const offsetLeft = (70 + xCoordinate) * this.realPixelRatio;
- const height = (this.graphHeight - this.graphHeightOffset) * this.realPixelRatio;
-
- return {
- top: `${offsetTop}px`,
- left: `${offsetLeft}px`,
- height: `${height}px`,
- };
- },
- flagOrientation() {
- if (this.currentXCoordinate * this.realPixelRatio > 120) {
- return 'left';
- }
- return 'right';
- },
- },
- methods: {
- seriesMetricValue(seriesIndex, series) {
- const indexFromCoordinates = this.currentCoordinates[series.metricTag]
- ? this.currentCoordinates[series.metricTag].currentDataIndex
- : 0;
- const index = this.deploymentFlagData
- ? this.deploymentFlagData.seriesIndex
- : indexFromCoordinates;
- const value = series.values[index] && series.values[index].value;
- if (Number.isNaN(value)) {
- return '-';
- }
- return `${formatRelevantDigits(value)}${this.unitOfDisplay}`;
- },
- seriesMetricLabel(index, series) {
- if (this.timeSeries.length < 2) {
- return this.legendTitle;
- }
- if (series.metricTag) {
- return series.metricTag;
- }
- return `series ${index + 1}`;
- },
- },
-};
-</script>
-
-<template>
- <div :style="cursorStyle" class="prometheus-graph-cursor">
- <div v-if="showFlagContent" :class="flagOrientation" class="prometheus-graph-flag popover">
- <div class="arrow-shadow"></div>
- <div class="arrow"></div>
- <div class="popover-title">
- <h5 v-if="deploymentFlagData">Deployed</h5>
- {{ formatDate }} <strong>{{ formatTime }}</strong>
- </div>
- <div v-if="deploymentFlagData" class="popover-content deploy-meta-content">
- <div>
- <icon :size="12" name="commit" />
- <a :href="deploymentFlagData.commitUrl"> {{ deploymentFlagData.sha.slice(0, 8) }} </a>
- </div>
- <div v-if="deploymentFlagData.tag">
- <icon :size="12" name="label" />
- <a :href="deploymentFlagData.tagUrl"> {{ deploymentFlagData.ref }} </a>
- </div>
- </div>
- <div class="popover-content">
- <table class="prometheus-table">
- <tr v-for="(series, index) in timeSeries" :key="index">
- <track-line :track="series" />
- <td>{{ series.track }} {{ seriesMetricLabel(index, series) }}</td>
- <td>
- <strong>{{ seriesMetricValue(index, series) }}</strong>
- </td>
- </tr>
- </table>
- </div>
- </div>
- </div>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/legend.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue
deleted file mode 100644
index b5211c306a3..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/legend.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-<script>
-import TrackLine from './track_line.vue';
-import TrackInfo from './track_info.vue';
-
-export default {
- components: {
- TrackLine,
- TrackInfo,
- },
- props: {
- legendTitle: {
- type: String,
- required: true,
- },
- timeSeries: {
- type: Array,
- required: true,
- },
- },
- methods: {
- isStable(track) {
- return {
- 'prometheus-table-row-highlight': track.trackName !== 'Canary' && track.renderCanary,
- };
- },
- },
-};
-</script>
-<template>
- <div class="prometheus-graph-legends prepend-left-10">
- <table class="prometheus-table">
- <tr
- v-for="(series, index) in timeSeries"
- v-if="series.shouldRenderLegend"
- :key="index"
- :class="isStable(series)"
- >
- <td>
- <strong v-if="series.renderCanary">{{ series.trackName }}</strong>
- </td>
- <track-line :track="series" />
- <td v-if="timeSeries.length > 1" class="legend-metric-title">
- <track-info v-if="series.metricTag" :track="series" />
- <track-info v-else :track="series">
- <strong>{{ legendTitle }}</strong> series {{ index + 1 }}
- </track-info>
- </td>
- <td v-else>
- <track-info :track="series">
- <strong>{{ legendTitle }}</strong>
- </track-info>
- </td>
- <template v-for="(track, trackIndex) in series.tracksLegend">
- <track-line :key="`track-line-${trackIndex}`" :track="track" />
- <td :key="`track-info-${trackIndex}`">
- <track-info :track="track" class="legend-metric-title" />
- </td>
- </template>
- </tr>
- </table>
- </div>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/path.vue b/app/assets/javascripts/monitoring/components/graph/path.vue
deleted file mode 100644
index f2c237ec391..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/path.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-<script>
-export default {
- props: {
- generatedLinePath: {
- type: String,
- required: true,
- },
- generatedAreaPath: {
- type: String,
- required: true,
- },
- lineStyle: {
- type: String,
- required: false,
- default: '',
- },
- lineColor: {
- type: String,
- required: true,
- },
- areaColor: {
- type: String,
- required: true,
- },
- currentCoordinates: {
- type: Object,
- required: false,
- default: () => ({ currentX: 0, currentY: 0 }),
- },
- showDot: {
- type: Boolean,
- required: true,
- },
- },
- computed: {
- strokeDashArray() {
- if (this.lineStyle === 'dashed') return '3, 1';
- if (this.lineStyle === 'dotted') return '1, 1';
- return null;
- },
- },
-};
-</script>
-<template>
- <g transform="translate(-5, 20)">
- <circle
- v-if="showDot"
- :cx="currentCoordinates.currentX"
- :cy="currentCoordinates.currentY"
- :fill="lineColor"
- :stroke="lineColor"
- class="circle-path"
- r="3"
- />
- <path :d="generatedAreaPath" :fill="areaColor" class="metric-area" />
- <path
- :d="generatedLinePath"
- :stroke="lineColor"
- :stroke-dasharray="strokeDashArray"
- class="metric-line"
- fill="none"
- stroke-width="1"
- />
- </g>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/track_info.vue b/app/assets/javascripts/monitoring/components/graph/track_info.vue
deleted file mode 100644
index 3464067834f..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/track_info.vue
+++ /dev/null
@@ -1,28 +0,0 @@
-<script>
-import { formatRelevantDigits } from '~/lib/utils/number_utils';
-
-export default {
- name: 'TrackInfo',
- props: {
- track: {
- type: Object,
- required: true,
- },
- },
- computed: {
- summaryMetrics() {
- return `Avg: ${formatRelevantDigits(this.track.average)} · Max: ${formatRelevantDigits(
- this.track.max,
- )}`;
- },
- },
-};
-</script>
-<template>
- <span>
- <slot>
- <strong> {{ track.metricTag }} </strong>
- </slot>
- {{ summaryMetrics }}
- </span>
-</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/track_line.vue b/app/assets/javascripts/monitoring/components/graph/track_line.vue
deleted file mode 100644
index d2ed1ba113e..00000000000
--- a/app/assets/javascripts/monitoring/components/graph/track_line.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<script>
-export default {
- name: 'TrackLine',
- props: {
- track: {
- type: Object,
- required: true,
- },
- },
- computed: {
- stylizedLine() {
- if (this.track.lineStyle === 'dashed') return '6, 3';
- if (this.track.lineStyle === 'dotted') return '3, 3';
- return null;
- },
- },
-};
-</script>
-<template>
- <td>
- <svg width="16" height="8">
- <line
- :stroke-dasharray="stylizedLine"
- :stroke="track.lineColor"
- :x1="0"
- :x2="16"
- :y1="4"
- :y2="4"
- stroke-width="4"
- />
- </svg>
- </td>
-</template>
diff --git a/app/assets/javascripts/monitoring/event_hub.js b/app/assets/javascripts/monitoring/event_hub.js
deleted file mode 100644
index 0948c2e5352..00000000000
--- a/app/assets/javascripts/monitoring/event_hub.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Vue from 'vue';
-
-export default new Vue();
diff --git a/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js b/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
deleted file mode 100644
index 87c3d969de4..00000000000
--- a/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import { bisectDate } from '../utils/date_time_formatters';
-
-const mixins = {
- methods: {
- mouseOverDeployInfo(mouseXPos) {
- if (!this.reducedDeploymentData) return false;
-
- let dataFound = false;
- this.reducedDeploymentData = this.reducedDeploymentData.map(d => {
- const deployment = d;
- if (d.xPos >= mouseXPos - 10 && d.xPos <= mouseXPos + 10 && !dataFound) {
- dataFound = d.xPos + 1;
-
- deployment.showDeploymentFlag = true;
- } else {
- deployment.showDeploymentFlag = false;
- }
- return deployment;
- });
-
- return dataFound;
- },
-
- formatDeployments() {
- this.reducedDeploymentData = this.deploymentData.reduce((deploymentDataArray, deployment) => {
- const time = new Date(deployment.created_at);
- const xPos = Math.floor(this.timeSeries[0].timeSeriesScaleX(time));
-
- time.setSeconds(this.timeSeries[0].values[0].time.getSeconds());
-
- if (xPos >= 0) {
- const seriesIndex = bisectDate(this.timeSeries[0].values, time, 1);
-
- deploymentDataArray.push({
- id: deployment.id,
- time,
- sha: deployment.sha,
- commitUrl: `${this.projectPath}/commit/${deployment.sha}`,
- tag: deployment.tag,
- tagUrl: deployment.tag ? `${this.tagsPath}/${deployment.ref.name}` : null,
- ref: deployment.ref.name,
- xPos,
- seriesIndex,
- showDeploymentFlag: false,
- });
- }
-
- return deploymentDataArray;
- }, []);
- },
-
- positionFlag() {
- const timeSeries = this.seriesUnderMouse[0];
- if (!timeSeries) {
- return;
- }
- const hoveredDataIndex = bisectDate(timeSeries.values, this.hoverData.hoveredDate);
-
- this.currentData = timeSeries.values[hoveredDataIndex];
- this.currentXCoordinate = Math.floor(timeSeries.timeSeriesScaleX(this.currentData.time));
-
- this.currentCoordinates = {};
-
- this.seriesUnderMouse.forEach(series => {
- const currentDataIndex = bisectDate(series.values, this.hoverData.hoveredDate);
- const currentData = series.values[currentDataIndex];
- const currentX = Math.floor(series.timeSeriesScaleX(currentData.time));
- const currentY = Math.floor(series.timeSeriesScaleY(currentData.value));
-
- this.currentCoordinates[series.metricTag] = {
- currentX,
- currentY,
- currentDataIndex,
- };
- });
-
- if (this.hoverData.currentDeployXPos) {
- this.showFlag = false;
- } else {
- this.showFlag = true;
- }
- },
- },
-};
-
-export default mixins;
diff --git a/app/assets/javascripts/monitoring/utils/date_time_formatters.js b/app/assets/javascripts/monitoring/utils/date_time_formatters.js
deleted file mode 100644
index d88c13609dc..00000000000
--- a/app/assets/javascripts/monitoring/utils/date_time_formatters.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { timeFormat as time } from 'd3-time-format';
-import { timeSecond, timeMinute, timeHour, timeDay, timeWeek, timeMonth, timeYear } from 'd3-time';
-import { bisector } from 'd3-array';
-
-const d3 = {
- time,
- bisector,
- timeSecond,
- timeMinute,
- timeHour,
- timeDay,
- timeWeek,
- timeMonth,
- timeYear,
-};
-
-export const dateFormat = d3.time('%d %b %Y, ');
-export const timeFormat = d3.time('%-I:%M%p');
-export const dateFormatWithName = d3.time('%a, %b %-d');
-export const bisectDate = d3.bisector(d => d.time).left;
-
-export function timeScaleFormat(date) {
- let formatFunction;
- if (d3.timeSecond(date) < date) {
- formatFunction = d3.time('.%L');
- } else if (d3.timeMinute(date) < date) {
- formatFunction = d3.time(':%S');
- } else if (d3.timeHour(date) < date) {
- formatFunction = d3.time('%-I:%M');
- } else if (d3.timeDay(date) < date) {
- formatFunction = d3.time('%-I %p');
- } else if (d3.timeWeek(date) < date) {
- formatFunction = d3.time('%a %d');
- } else if (d3.timeMonth(date) < date) {
- formatFunction = d3.time('%b %d');
- } else if (d3.timeYear(date) < date) {
- formatFunction = d3.time('%B');
- } else {
- formatFunction = d3.time('%Y');
- }
- return formatFunction(date);
-}
diff --git a/app/assets/javascripts/monitoring/utils/measurements.js b/app/assets/javascripts/monitoring/utils/measurements.js
deleted file mode 100644
index 7c771f43eee..00000000000
--- a/app/assets/javascripts/monitoring/utils/measurements.js
+++ /dev/null
@@ -1,44 +0,0 @@
-export default {
- small: {
- // Covers both xs and sm screen sizes
- margin: {
- top: 40,
- right: 40,
- bottom: 50,
- left: 40,
- },
- legends: {
- width: 15,
- height: 3,
- offsetX: 20,
- offsetY: 32,
- },
- backgroundLegend: {
- width: 30,
- height: 50,
- },
- axisLabelLineOffset: -20,
- },
- large: {
- // This covers both md and lg screen sizes
- margin: {
- top: 80,
- right: 80,
- bottom: 100,
- left: 80,
- },
- legends: {
- width: 15,
- height: 3,
- offsetX: 20,
- offsetY: 34,
- },
- backgroundLegend: {
- width: 30,
- height: 150,
- },
- axisLabelLineOffset: 20,
- },
- xTicks: 8,
- yTicks: 3,
-};
diff --git a/app/assets/javascripts/monitoring/utils/multiple_time_series.js b/app/assets/javascripts/monitoring/utils/multiple_time_series.js
deleted file mode 100644
index 50ba14dfb2e..00000000000
--- a/app/assets/javascripts/monitoring/utils/multiple_time_series.js
+++ /dev/null
@@ -1,223 +0,0 @@
-import _ from 'underscore';
-import { scaleLinear, scaleTime } from 'd3-scale';
-import { line, area, curveLinear } from 'd3-shape';
-import { extent, max, sum } from 'd3-array';
-import { timeMinute, timeSecond } from 'd3-time';
-import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
-
-const d3 = {
- scaleLinear,
- scaleTime,
- line,
- area,
- curveLinear,
- extent,
- max,
- timeMinute,
- timeSecond,
- sum,
-};
-
-const defaultColorPalette = {
- blue: ['#1f78d1', '#8fbce8'],
- orange: ['#fc9403', '#feca81'],
- red: ['#db3b21', '#ed9d90'],
- green: ['#1aaa55', '#8dd5aa'],
- purple: ['#6666c4', '#d1d1f0'],
-};
-
-const defaultColorOrder = ['blue', 'orange', 'red', 'green', 'purple'];
-
-const defaultStyleOrder = ['solid', 'dashed', 'dotted'];
-
-function queryTimeSeries(query, graphDrawData, lineStyle) {
- let usedColors = [];
- let renderCanary = false;
- const timeSeriesParsed = [];
-
- function pickColor(name) {
- let pick;
- if (name && defaultColorPalette[name]) {
- pick = name;
- } else {
- const unusedColors = _.difference(defaultColorOrder, usedColors);
- if (unusedColors.length > 0) {
- [pick] = unusedColors;
- } else {
- usedColors = [];
- [pick] = defaultColorOrder;
- }
- }
- usedColors.push(pick);
- return defaultColorPalette[pick];
- }
-
- function findByDate(series, time) {
- const val = series.find(v => Math.abs(d3.timeSecond.count(time, v.time)) < 60);
- if (val) {
- return val.value;
- }
- return NaN;
- }
-
- // The timeseries data may have gaps in it
- // but we need a regularly-spaced set of time/value pairs
- // this gives us a complete range of one minute intervals
- // offset the same amount as the original data
- const [minX, maxX] = graphDrawData.xDom;
- const offset = d3.timeMinute(minX) - Number(minX);
- const datesWithoutGaps = d3.timeSecond
- .every(60)
- .range(d3.timeMinute.offset(minX, -1), maxX)
- .map(d => d - offset);
-
- query.result.forEach((timeSeries, timeSeriesNumber) => {
- let metricTag = '';
- let lineColor = '';
- let areaColor = '';
- let shouldRenderLegend = true;
- const timeSeriesValues = timeSeries.values.map(d => d.value);
- const maximumValue = d3.max(timeSeriesValues);
- const accum = d3.sum(timeSeriesValues);
- const trackName = capitalizeFirstCharacter(query.track ? query.track : 'Stable');
-
- if (trackName === 'Canary') {
- renderCanary = true;
- }
-
- const timeSeriesMetricLabel = timeSeries.metric[Object.keys(timeSeries.metric)[0]];
- const seriesCustomizationData =
- query.series != null && _.findWhere(query.series[0].when, { value: timeSeriesMetricLabel });
-
- if (seriesCustomizationData) {
- metricTag = seriesCustomizationData.value || timeSeriesMetricLabel;
- [lineColor, areaColor] = pickColor(seriesCustomizationData.color);
- if (timeSeriesParsed.length > 0) {
- shouldRenderLegend = false;
- } else {
- shouldRenderLegend = true;
- }
- } else {
- metricTag = timeSeriesMetricLabel || query.label || `series ${timeSeriesNumber + 1}`;
- [lineColor, areaColor] = pickColor();
- if (timeSeriesParsed.length > 1) {
- shouldRenderLegend = false;
- }
- }
-
- const values = datesWithoutGaps.map(time => ({
- time,
- value: findByDate(timeSeries.values, time),
- }));
-
- timeSeriesParsed.push({
- linePath: graphDrawData.lineFunction(values),
- areaPath: graphDrawData.areaBelowLine(values),
- timeSeriesScaleX: graphDrawData.timeSeriesScaleX,
- timeSeriesScaleY: graphDrawData.timeSeriesScaleY,
- values: timeSeries.values,
- max: maximumValue,
- average: accum / timeSeries.values.length,
- lineStyle,
- lineColor,
- areaColor,
- metricTag,
- trackName,
- shouldRenderLegend,
- renderCanary,
- });
-
- if (!shouldRenderLegend) {
- if (!timeSeriesParsed[0].tracksLegend) {
- timeSeriesParsed[0].tracksLegend = [];
- }
- timeSeriesParsed[0].tracksLegend.push({
- max: maximumValue,
- average: accum / timeSeries.values.length,
- lineStyle,
- lineColor,
- metricTag,
- });
- }
- });
-
- return timeSeriesParsed;
-}
-
-function xyDomain(queries) {
- const allValues = queries.reduce(
- (allQueryResults, query) =>
- allQueryResults.concat(
- query.result.reduce((allResults, result) => allResults.concat(result.values), []),
- ),
- [],
- );
-
- const xDom = d3.extent(allValues, d => d.time);
- const yDom = [0, d3.max(allValues.map(d => d.value))];
-
- return {
- xDom,
- yDom,
- };
-}
-
-export function generateGraphDrawData(queries, graphWidth, graphHeight, graphHeightOffset) {
- const { xDom, yDom } = xyDomain(queries);
-
- const timeSeriesScaleX = d3.scaleTime().range([0, graphWidth - 70]);
- const timeSeriesScaleY = d3.scaleLinear().range([graphHeight - graphHeightOffset, 0]);
-
- timeSeriesScaleX.domain(xDom);
- timeSeriesScaleX.ticks(d3.timeMinute, 60);
- timeSeriesScaleY.domain(yDom);
-
- const defined = d => !Number.isNaN(d.value) && d.value != null;
-
- const lineFunction = d3
- .line()
- .defined(defined)
- .curve(d3.curveLinear) // d3 v4 uses curbe instead of interpolate
- .x(d => timeSeriesScaleX(d.time))
- .y(d => timeSeriesScaleY(d.value));
-
- const areaBelowLine = d3
- .area()
- .defined(defined)
- .curve(d3.curveLinear)
- .x(d => timeSeriesScaleX(d.time))
- .y0(graphHeight - graphHeightOffset)
- .y1(d => timeSeriesScaleY(d.value));
-
- const areaAboveLine = d3
- .area()
- .defined(defined)
- .curve(d3.curveLinear)
- .x(d => timeSeriesScaleX(d.time))
- .y0(0)
- .y1(d => timeSeriesScaleY(d.value));
-
- return {
- lineFunction,
- areaBelowLine,
- areaAboveLine,
- xDom,
- yDom,
- timeSeriesScaleX,
- timeSeriesScaleY,
- };
-}
-
-export default function createTimeSeries(queries, graphWidth, graphHeight, graphHeightOffset) {
- const graphDrawData = generateGraphDrawData(queries, graphWidth, graphHeight, graphHeightOffset);
-
- const timeSeries = queries.reduce((series, query, index) => {
- const lineStyle = defaultStyleOrder[index % defaultStyleOrder.length];
- return series.concat(queryTimeSeries(query, graphDrawData, lineStyle));
- }, []);
-
- return {
- timeSeries,
- graphDrawData,
- };
-}
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index bb98fc06ed6..8caa876e6b0 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4447,9 +4447,6 @@ msgstr ""
msgid "Metrics|Learn about environments"
msgstr ""
-msgid "Metrics|No data to display"
-msgstr ""
-
msgid "Metrics|No deployed environments"
msgstr ""
@@ -5711,9 +5708,6 @@ msgstr ""
msgid "ProjectsDropdown|This feature requires browser localStorage support"
msgstr ""
-msgid "PrometheusDashboard|Time"
-msgstr ""
-
msgid "PrometheusService|%{exporters} with %{metrics} were found"
msgstr ""
diff --git a/spec/javascripts/monitoring/graph/axis_spec.js b/spec/javascripts/monitoring/graph/axis_spec.js
deleted file mode 100644
index c7adba00637..00000000000
--- a/spec/javascripts/monitoring/graph/axis_spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import Vue from 'vue';
-import GraphAxis from '~/monitoring/components/graph/axis.vue';
-import measurements from '~/monitoring/utils/measurements';
-
-const createComponent = propsData => {
- const Component = Vue.extend(GraphAxis);
-
- return new Component({
- propsData,
- }).$mount();
-};
-
-const defaultValuesComponent = {
- graphWidth: 500,
- graphHeight: 300,
- graphHeightOffset: 120,
- margin: measurements.large.margin,
- measurements: measurements.large,
- yAxisLabel: 'Values',
- unitOfDisplay: 'MB',
-};
-
-function getTextFromNode(component, selector) {
- return component.$el.querySelector(selector).firstChild.nodeValue.trim();
-}
-
-describe('Axis', () => {
- describe('Computed props', () => {
- it('textTransform', () => {
- const component = createComponent(defaultValuesComponent);
-
- expect(component.textTransform).toContain('translate(15, 120) rotate(-90)');
- });
-
- it('xPosition', () => {
- const component = createComponent(defaultValuesComponent);
-
- expect(component.xPosition).toEqual(180);
- });
-
- it('yPosition', () => {
- const component = createComponent(defaultValuesComponent);
-
- expect(component.yPosition).toEqual(240);
- });
-
- it('rectTransform', () => {
- const component = createComponent(defaultValuesComponent);
-
- expect(component.rectTransform).toContain('translate(0, 120) rotate(-90)');
- });
- });
-
- it('has 2 rect-axis-text rect svg elements', () => {
- const component = createComponent(defaultValuesComponent);
-
- expect(component.$el.querySelectorAll('.rect-axis-text').length).toEqual(2);
- });
-
- it('contains text to signal the usage, title and time with multiple time series', () => {
- const component = createComponent(defaultValuesComponent);
-
- expect(getTextFromNode(component, '.y-label-text')).toEqual('Values (MB)');
- });
-});
diff --git a/spec/javascripts/monitoring/graph/deployment_spec.js b/spec/javascripts/monitoring/graph/deployment_spec.js
deleted file mode 100644
index 7d39c4345d2..00000000000
--- a/spec/javascripts/monitoring/graph/deployment_spec.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import Vue from 'vue';
-import GraphDeployment from '~/monitoring/components/graph/deployment.vue';
-import { deploymentData } from '../mock_data';
-
-const createComponent = propsData => {
- const Component = Vue.extend(GraphDeployment);
-
- return new Component({
- propsData,
- }).$mount();
-};
-
-describe('MonitoringDeployment', () => {
- describe('Methods', () => {
- it('should contain a hidden gradient', () => {
- const component = createComponent({
- showDeployInfo: true,
- deploymentData,
- graphHeight: 300,
- graphWidth: 440,
- graphHeightOffset: 120,
- });
-
- expect(component.$el.querySelector('#shadow-gradient')).not.toBeNull();
- });
-
- it('transformDeploymentGroup translates an available deployment', () => {
- const component = createComponent({
- showDeployInfo: false,
- deploymentData,
- graphHeight: 300,
- graphWidth: 440,
- graphHeightOffset: 120,
- });
-
- expect(component.transformDeploymentGroup({ xPos: 16 })).toContain('translate(11, 20)');
- });
-
- describe('Computed props', () => {
- it('calculatedHeight', () => {
- const component = createComponent({
- showDeployInfo: true,
- deploymentData,
- graphHeight: 300,
- graphWidth: 440,
- graphHeightOffset: 120,
- });
-
- expect(component.calculatedHeight).toEqual(180);
- });
- });
- });
-});
diff --git a/spec/javascripts/monitoring/graph/flag_spec.js b/spec/javascripts/monitoring/graph/flag_spec.js
deleted file mode 100644
index 038bfffd44f..00000000000
--- a/spec/javascripts/monitoring/graph/flag_spec.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import Vue from 'vue';
-import GraphFlag from '~/monitoring/components/graph/flag.vue';
-import { deploymentData } from '../mock_data';
-
-const createComponent = propsData => {
- const Component = Vue.extend(GraphFlag);
-
- return new Component({
- propsData,
- }).$mount();
-};
-
-const defaultValuesComponent = {
- currentXCoordinate: 200,
- currentYCoordinate: 100,
- currentFlagPosition: 100,
- currentData: {
- time: new Date('2017-06-04T18:17:33.501Z'),
- value: '1.49609375',
- },
- graphHeight: 300,
- graphHeightOffset: 120,
- showFlagContent: true,
- realPixelRatio: 1,
- timeSeries: [
- {
- values: [
- {
- time: new Date('2017-06-04T18:17:33.501Z'),
- value: '1.49609375',
- },
- ],
- },
- ],
- unitOfDisplay: 'ms',
- currentDataIndex: 0,
- legendTitle: 'Average',
- currentCoordinates: {},
-};
-
-const deploymentFlagData = {
- ...deploymentData[0],
- ref: deploymentData[0].ref.name,
- xPos: 10,
- time: new Date(deploymentData[0].created_at),
-};
-
-describe('GraphFlag', () => {
- let component;
-
- it('has a line at the currentXCoordinate', () => {
- component = createComponent(defaultValuesComponent);
-
- expect(component.$el.style.left).toEqual(`${70 + component.currentXCoordinate}px`);
- });
-
- describe('Deployment flag', () => {
- it('shows a deployment flag when deployment data provided', () => {
- const deploymentFlagComponent = createComponent({
- ...defaultValuesComponent,
- deploymentFlagData,
- });
-
- expect(deploymentFlagComponent.$el.querySelector('.popover-title')).toContainText('Deployed');
- });
-
- it('contains the ref when a tag is available', () => {
- const deploymentFlagComponent = createComponent({
- ...defaultValuesComponent,
- deploymentFlagData: {
- ...deploymentFlagData,
- sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
- tag: true,
- ref: '1.0',
- },
- });
-
- expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).toContainText(
- 'f5bcd1d9',
- );
-
- expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).toContainText(
- '1.0',
- );
- });
-
- it('does not contain the ref when a tag is unavailable', () => {
- const deploymentFlagComponent = createComponent({
- ...defaultValuesComponent,
- deploymentFlagData: {
- ...deploymentFlagData,
- sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
- tag: false,
- ref: '1.0',
- },
- });
-
- expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).toContainText(
- 'f5bcd1d9',
- );
-
- expect(deploymentFlagComponent.$el.querySelector('.deploy-meta-content')).not.toContainText(
- '1.0',
- );
- });
- });
-
- describe('Computed props', () => {
- beforeEach(() => {
- component = createComponent(defaultValuesComponent);
- });
-
- it('formatTime', () => {
- expect(component.formatTime).toMatch(/\d:17PM/);
- });
-
- it('formatDate', () => {
- expect(component.formatDate).toEqual('04 Jun 2017, ');
- });
-
- it('cursorStyle', () => {
- expect(component.cursorStyle).toEqual({
- top: '20px',
- left: '270px',
- height: '180px',
- });
- });
-
- it('flagOrientation', () => {
- expect(component.flagOrientation).toEqual('left');
- });
- });
-});
diff --git a/spec/javascripts/monitoring/graph/legend_spec.js b/spec/javascripts/monitoring/graph/legend_spec.js
deleted file mode 100644
index 9209e77dcf4..00000000000
--- a/spec/javascripts/monitoring/graph/legend_spec.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import Vue from 'vue';
-import GraphLegend from '~/monitoring/components/graph/legend.vue';
-import createTimeSeries from '~/monitoring/utils/multiple_time_series';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import { singleRowMetricsMultipleSeries, convertDatesMultipleSeries } from '../mock_data';
-
-const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries);
-
-const defaultValuesComponent = {};
-
-const { timeSeries } = createTimeSeries(convertedMetrics[0].queries, 500, 300, 120);
-
-defaultValuesComponent.timeSeries = timeSeries;
-
-describe('Legend Component', () => {
- let vm;
- let Legend;
-
- beforeEach(() => {
- Legend = Vue.extend(GraphLegend);
- });
-
- describe('View', () => {
- beforeEach(() => {
- vm = mountComponent(Legend, {
- legendTitle: 'legend',
- timeSeries,
- currentDataIndex: 0,
- unitOfDisplay: 'Req/Sec',
- });
- });
-
- it('should render the usage, title and time with multiple time series', () => {
- const titles = vm.$el.querySelectorAll('.legend-metric-title');
-
- expect(titles[0].textContent.indexOf('1xx')).not.toEqual(-1);
- expect(titles[1].textContent.indexOf('2xx')).not.toEqual(-1);
- });
-
- it('should container the same number of rows in the table as time series', () => {
- expect(vm.$el.querySelectorAll('.prometheus-table tr').length).toEqual(vm.timeSeries.length);
- });
- });
-});
diff --git a/spec/javascripts/monitoring/graph/track_info_spec.js b/spec/javascripts/monitoring/graph/track_info_spec.js
deleted file mode 100644
index ce93ae28842..00000000000
--- a/spec/javascripts/monitoring/graph/track_info_spec.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import Vue from 'vue';
-import TrackInfo from '~/monitoring/components/graph/track_info.vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import createTimeSeries from '~/monitoring/utils/multiple_time_series';
-import { singleRowMetricsMultipleSeries, convertDatesMultipleSeries } from '../mock_data';
-
-const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries);
-const { timeSeries } = createTimeSeries(convertedMetrics[0].queries, 500, 300, 120);
-
-describe('TrackInfo component', () => {
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(TrackInfo);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('Computed props', () => {
- beforeEach(() => {
- vm = mountComponent(Component, { track: timeSeries[0] });
- });
-
- it('summaryMetrics', () => {
- expect(vm.summaryMetrics).toEqual('Avg: 0.000 · Max: 0.000');
- });
- });
-
- describe('Rendered output', () => {
- beforeEach(() => {
- vm = mountComponent(Component, { track: timeSeries[0] });
- });
-
- it('contains metric tag and the summary metrics', () => {
- const metricTag = vm.$el.querySelector('strong');
-
- expect(metricTag.textContent.trim()).toEqual(vm.track.metricTag);
- expect(vm.$el.textContent).toContain('Avg: 0.000 · Max: 0.000');
- });
- });
-});
diff --git a/spec/javascripts/monitoring/graph/track_line_spec.js b/spec/javascripts/monitoring/graph/track_line_spec.js
deleted file mode 100644
index 2a4f89ddf6e..00000000000
--- a/spec/javascripts/monitoring/graph/track_line_spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import Vue from 'vue';
-import TrackLine from '~/monitoring/components/graph/track_line.vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import createTimeSeries from '~/monitoring/utils/multiple_time_series';
-import { singleRowMetricsMultipleSeries, convertDatesMultipleSeries } from '../mock_data';
-
-const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries);
-const { timeSeries } = createTimeSeries(convertedMetrics[0].queries, 500, 300, 120);
-
-describe('TrackLine component', () => {
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(TrackLine);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('Computed props', () => {
- it('stylizedLine for dashed lineStyles', () => {
- vm = mountComponent(Component, { track: { ...timeSeries[0], lineStyle: 'dashed' } });
-
- expect(vm.stylizedLine).toEqual('6, 3');
- });
-
- it('stylizedLine for dotted lineStyles', () => {
- vm = mountComponent(Component, { track: { ...timeSeries[0], lineStyle: 'dotted' } });
-
- expect(vm.stylizedLine).toEqual('3, 3');
- });
- });
-
- describe('Rendered output', () => {
- it('has an svg with a line', () => {
- vm = mountComponent(Component, { track: { ...timeSeries[0] } });
- const svgEl = vm.$el.querySelector('svg');
- const lineEl = vm.$el.querySelector('svg line');
-
- expect(svgEl.getAttribute('width')).toEqual('16');
- expect(svgEl.getAttribute('height')).toEqual('8');
-
- expect(lineEl.getAttribute('stroke-width')).toEqual('4');
- expect(lineEl.getAttribute('x1')).toEqual('0');
- expect(lineEl.getAttribute('x2')).toEqual('16');
- expect(lineEl.getAttribute('y1')).toEqual('4');
- expect(lineEl.getAttribute('y2')).toEqual('4');
- });
- });
-});
diff --git a/spec/javascripts/monitoring/graph_path_spec.js b/spec/javascripts/monitoring/graph_path_spec.js
deleted file mode 100644
index fd167b83d51..00000000000
--- a/spec/javascripts/monitoring/graph_path_spec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import Vue from 'vue';
-import GraphPath from '~/monitoring/components/graph/path.vue';
-import createTimeSeries from '~/monitoring/utils/multiple_time_series';
-import { singleRowMetricsMultipleSeries, convertDatesMultipleSeries } from './mock_data';
-
-const createComponent = propsData => {
- const Component = Vue.extend(GraphPath);
-
- return new Component({
- propsData,
- }).$mount();
-};
-
-const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries);
-
-const { timeSeries } = createTimeSeries(convertedMetrics[0].queries, 428, 272, 120);
-const firstTimeSeries = timeSeries[0];
-
-describe('Monitoring Paths', () => {
- it('renders two paths to represent a line and the area underneath it', () => {
- const component = createComponent({
- generatedLinePath: firstTimeSeries.linePath,
- generatedAreaPath: firstTimeSeries.areaPath,
- lineColor: firstTimeSeries.lineColor,
- areaColor: firstTimeSeries.areaColor,
- showDot: false,
- });
- const metricArea = component.$el.querySelector('.metric-area');
- const metricLine = component.$el.querySelector('.metric-line');
-
- expect(metricArea.getAttribute('fill')).toBe('#8fbce8');
- expect(metricArea.getAttribute('d')).toBe(firstTimeSeries.areaPath);
- expect(metricLine.getAttribute('stroke')).toBe('#1f78d1');
- expect(metricLine.getAttribute('d')).toBe(firstTimeSeries.linePath);
- });
-
- describe('Computed properties', () => {
- it('strokeDashArray', () => {
- const component = createComponent({
- generatedLinePath: firstTimeSeries.linePath,
- generatedAreaPath: firstTimeSeries.areaPath,
- lineColor: firstTimeSeries.lineColor,
- areaColor: firstTimeSeries.areaColor,
- showDot: false,
- });
-
- component.lineStyle = 'dashed';
-
- expect(component.strokeDashArray).toBe('3, 1');
-
- component.lineStyle = 'dotted';
-
- expect(component.strokeDashArray).toBe('1, 1');
- });
- });
-});
diff --git a/spec/javascripts/monitoring/graph_spec.js b/spec/javascripts/monitoring/graph_spec.js
deleted file mode 100644
index 59d6d4f3a7f..00000000000
--- a/spec/javascripts/monitoring/graph_spec.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import Vue from 'vue';
-import Graph from '~/monitoring/components/graph.vue';
-import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins';
-import {
- deploymentData,
- convertDatesMultipleSeries,
- singleRowMetricsMultipleSeries,
- queryWithoutData,
-} from './mock_data';
-
-const tagsPath = 'http://test.host/frontend-fixtures/environments-project/tags';
-const projectPath = 'http://test.host/frontend-fixtures/environments-project';
-const createComponent = propsData => {
- const Component = Vue.extend(Graph);
-
- return new Component({
- propsData,
- }).$mount();
-};
-
-const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries);
-
-describe('Graph', () => {
- beforeEach(() => {
- spyOn(MonitoringMixins.methods, 'formatDeployments').and.returnValue({});
- });
-
- it('has a title', () => {
- const component = createComponent({
- graphData: convertedMetrics[1],
- updateAspectRatio: false,
- deploymentData,
- tagsPath,
- projectPath,
- });
-
- expect(component.$el.querySelector('.prometheus-graph-title').innerText.trim()).toBe(
- component.graphData.title,
- );
- });
-
- describe('Computed props', () => {
- it('axisTransform translates an element Y position depending of its height', () => {
- const component = createComponent({
- graphData: convertedMetrics[1],
- updateAspectRatio: false,
- deploymentData,
- tagsPath,
- projectPath,
- });
-
- const transformedHeight = `${component.graphHeight - 100}`;
-
- expect(component.axisTransform.indexOf(transformedHeight)).not.toEqual(-1);
- });
-
- it('outerViewBox gets a width and height property based on the DOM size of the element', () => {
- const component = createComponent({
- graphData: convertedMetrics[1],
- updateAspectRatio: false,
- deploymentData,
- tagsPath,
- projectPath,
- });
-
- const viewBoxArray = component.outerViewBox.split(' ');
-
- expect(typeof component.outerViewBox).toEqual('string');
- expect(viewBoxArray[2]).toEqual(component.graphWidth.toString());
- expect(viewBoxArray[3]).toEqual((component.graphHeight - 50).toString());
- });
- });
-
- it('has a title for the y-axis and the chart legend that comes from the backend', () => {
- const component = createComponent({
- graphData: convertedMetrics[1],
- updateAspectRatio: false,
- deploymentData,
- tagsPath,
- projectPath,
- });
-
- expect(component.yAxisLabel).toEqual(component.graphData.y_label);
- expect(component.legendTitle).toEqual(component.graphData.queries[0].label);
- });
-
- it('sets the currentData object based on the hovered data index', () => {
- const component = createComponent({
- graphData: convertedMetrics[1],
- updateAspectRatio: false,
- deploymentData,
- graphIdentifier: 0,
- hoverData: {
- hoveredDate: new Date('Sun Aug 27 2017 06:11:51 GMT-0500 (CDT)'),
- currentDeployXPos: null,
- },
- tagsPath,
- projectPath,
- });
-
- // simulate moving mouse over data series
- component.seriesUnderMouse = component.timeSeries;
-
- component.positionFlag();
-
- expect(component.currentData).toBe(component.timeSeries[0].values[10]);
- });
-
- describe('Without data to display', () => {
- it('shows a "no data to display" empty state on a graph', done => {
- const component = createComponent({
- graphData: queryWithoutData,
- deploymentData,
- tagsPath,
- projectPath,
- });
-
- Vue.nextTick(() => {
- expect(
- component.$el.querySelector('.js-no-data-to-display text').textContent.trim(),
- ).toEqual('No data to display');
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/monitoring/utils/multiple_time_series_spec.js b/spec/javascripts/monitoring/utils/multiple_time_series_spec.js
deleted file mode 100644
index 8937b7d9680..00000000000
--- a/spec/javascripts/monitoring/utils/multiple_time_series_spec.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import createTimeSeries from '~/monitoring/utils/multiple_time_series';
-import { convertDatesMultipleSeries, singleRowMetricsMultipleSeries } from '../mock_data';
-
-const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries);
-const { timeSeries } = createTimeSeries(convertedMetrics[0].queries, 428, 272, 120);
-const firstTimeSeries = timeSeries[0];
-
-describe('Multiple time series', () => {
- it('createTimeSeries returned array contains an object for each element', () => {
- expect(typeof firstTimeSeries.linePath).toEqual('string');
- expect(typeof firstTimeSeries.areaPath).toEqual('string');
- expect(typeof firstTimeSeries.timeSeriesScaleX).toEqual('function');
- expect(typeof firstTimeSeries.areaColor).toEqual('string');
- expect(typeof firstTimeSeries.lineColor).toEqual('string');
- expect(firstTimeSeries.values instanceof Array).toEqual(true);
- });
-
- it('createTimeSeries returns an array', () => {
- expect(timeSeries instanceof Array).toEqual(true);
- expect(timeSeries.length).toEqual(2);
- });
-});