summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/monitoring
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2018-01-08 19:19:52 +0000
committerFilipa Lacerda <filipa@gitlab.com>2018-01-08 19:19:52 +0000
commite2b759a2f483663e0771180de6b97bb9344a56cd (patch)
tree32cd72a70e405dc0858d774ca3354d6aef1bf445 /app/assets/javascripts/monitoring
parent7ca5a3f99dd3a3c1800f65da7b4f08395a97395a (diff)
parentdf74461014bbdbc691f4f4039b02962dad292362 (diff)
downloadgitlab-ce-e2b759a2f483663e0771180de6b97bb9344a56cd.tar.gz
Merge branch 'master' into 34312-eslint-vue-plugin
* master: (140 commits) Add Gitter room link to I want to contribute since you always have questions Use workhorse 3.4.0 chore: remove symbolic link Add memoization for properties Resolve "Allow QA tests to run with `CHROME_HEADLESS=false`" Resolve "Add graph value to hover" Fix slash commands dropdown description disables the shortcut to the issue boards when issues are disabled Fix static analysys Disable STI of ActiveRecord. Refactoring specs. Fix StaticSnalysys Fix change log Add changelog Revert bulk_insert and bring back AR insert(one by one) Add a new test for emptified params Use batch update for Service deactivation Fix query to look for proper unmanaged kubernetes service Fix static anylysy Use bulk_insert instead of AR create Opitmize migration process by using both unmanaged_kubernetes_service and kubernetes_service_without_template ...
Diffstat (limited to 'app/assets/javascripts/monitoring')
-rw-r--r--app/assets/javascripts/monitoring/components/graph.vue158
-rw-r--r--app/assets/javascripts/monitoring/components/graph/deployment.vue157
-rw-r--r--app/assets/javascripts/monitoring/components/graph/flag.vue204
-rw-r--r--app/assets/javascripts/monitoring/mixins/monitoring_mixins.js5
-rw-r--r--app/assets/javascripts/monitoring/utils/date_time_formatters.js2
5 files changed, 254 insertions, 272 deletions
diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue
index 05e6e7829d6..61f06486d95 100644
--- a/app/assets/javascripts/monitoring/components/graph.vue
+++ b/app/assets/javascripts/monitoring/components/graph.vue
@@ -3,10 +3,10 @@
import { axisLeft, axisBottom } from 'd3-axis';
import { max, extent } from 'd3-array';
import { select } from 'd3-selection';
- 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 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';
@@ -17,15 +17,6 @@
const d3 = { scaleLinear, scaleTime, axisLeft, axisBottom, max, extent, select };
export default {
- components: {
- graphLegend,
- graphFlag,
- graphDeployment,
- graphPath,
- },
-
- mixins: [MonitoringMixin],
-
props: {
graphData: {
type: Object,
@@ -54,6 +45,8 @@
},
},
+ mixins: [MonitoringMixin],
+
data() {
return {
baseGraphHeight: 450,
@@ -76,21 +69,25 @@
currentFlagPosition: 0,
showFlag: false,
showFlagContent: false,
- showDeployInfo: true,
timeSeries: [],
+ realPixelRatio: 1,
};
},
+ components: {
+ GraphLegend,
+ GraphFlag,
+ GraphDeployment,
+ GraphPath,
+ },
+
computed: {
outerViewBox() {
return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`;
},
innerViewBox() {
- if ((this.baseGraphWidth - 150) > 0) {
- return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
- }
- return '0 0 0 0';
+ return `0 0 ${this.baseGraphWidth - 150} ${this.baseGraphHeight}`;
},
axisTransform() {
@@ -102,28 +99,12 @@
paddingBottom: `${(Math.ceil(this.baseGraphHeight * 100) / this.baseGraphWidth) || 0}%`,
};
},
- },
- watch: {
- updateAspectRatio() {
- if (this.updateAspectRatio) {
- this.graphHeight = 450;
- this.graphWidth = 600;
- this.measurements = measurements.large;
- this.draw();
- eventHub.$emit('toggleAspectRatio');
- }
- },
-
- hoverData() {
- this.positionFlag();
+ deploymentFlagData() {
+ return this.reducedDeploymentData.find(deployment => deployment.showDeploymentFlag);
},
},
- mounted() {
- this.draw();
- },
-
methods: {
draw() {
const breakpointSize = bp.getBreakpointSize();
@@ -142,6 +123,10 @@
this.graphHeight = this.graphHeight - this.margin.top - this.margin.bottom;
this.baseGraphHeight = this.graphHeight;
this.baseGraphWidth = this.graphWidth;
+
+ // pixel offsets inside the svg and outside are not 1:1
+ this.realPixelRatio = (this.$refs.baseSvg.clientWidth / this.baseGraphWidth);
+
this.renderAxesPaths();
this.formatDeployments();
},
@@ -212,6 +197,26 @@
}); // This will select all of the ticks once they're rendered
},
},
+
+ watch: {
+ updateAspectRatio() {
+ if (this.updateAspectRatio) {
+ this.graphHeight = 450;
+ this.graphWidth = 600;
+ this.measurements = measurements.large;
+ this.draw();
+ eventHub.$emit('toggleAspectRatio');
+ }
+ },
+
+ hoverData() {
+ this.positionFlag();
+ },
+ },
+
+ mounted() {
+ this.draw();
+ },
};
</script>
@@ -221,7 +226,7 @@
@mouseover="showFlagContent = true"
@mouseleave="showFlagContent = false">
<h5 class="text-center graph-title">
- {{ graphData.title }}
+ {{graphData.title}}
</h5>
<div
class="prometheus-svg-container"
@@ -231,12 +236,12 @@
ref="baseSvg">
<g
class="x-axis"
- :transform="axisTransform"
- />
+ :transform="axisTransform">
+ </g>
<g
class="y-axis"
- transform="translate(70, 20)"
- />
+ transform="translate(70, 20)">
+ </g>
<graph-legend
:graph-width="graphWidth"
:graph-height="graphHeight"
@@ -251,43 +256,44 @@
<svg
class="graph-data"
:viewBox="innerViewBox"
- ref="graphData"
- >
- <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"
- />
- <rect
- class="prometheus-graph-overlay"
- :width="(graphWidth - 70)"
- :height="(graphHeight - 100)"
- transform="translate(-5, 20)"
- ref="graphOverlay"
- @mousemove="handleMouseOverGraph($event)"
- />
- <graph-deployment
- :show-deploy-info="showDeployInfo"
- :deployment-data="reducedDeploymentData"
- :graph-width="graphWidth"
- :graph-height="graphHeight"
- :graph-height-offset="graphHeightOffset"
- />
- <graph-flag
- v-if="showFlag"
- :current-x-coordinate="currentXCoordinate"
- :current-data="currentData"
- :current-flag-position="currentFlagPosition"
- :graph-height="graphHeight"
- :graph-height-offset="graphHeightOffset"
- :show-flag-content="showFlagContent"
- />
+ ref="graphData">
+ <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"
+ />
+ <graph-deployment
+ :deployment-data="reducedDeploymentData"
+ :graph-height="graphHeight"
+ :graph-height-offset="graphHeightOffset"
+ />
+ <rect
+ class="prometheus-graph-overlay"
+ :width="(graphWidth - 70)"
+ :height="(graphHeight - 100)"
+ transform="translate(-5, 20)"
+ ref="graphOverlay"
+ @mousemove="handleMouseOverGraph($event)">
+ </rect>
</svg>
</svg>
+ <graph-flag
+ :real-pixel-ratio="realPixelRatio"
+ :current-x-coordinate="currentXCoordinate"
+ :current-data="currentData"
+ :graph-height="graphHeight"
+ :graph-height-offset="graphHeightOffset"
+ :show-flag-content="showFlagContent"
+ :time-series="timeSeries"
+ :unit-of-display="unitOfDisplay"
+ :current-data-index="currentDataIndex"
+ :legend-title="legendTitle"
+ :deployment-flag-data="deploymentFlagData"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/monitoring/components/graph/deployment.vue b/app/assets/javascripts/monitoring/components/graph/deployment.vue
index 0ce5464dd1e..8d6393d4ce5 100644
--- a/app/assets/javascripts/monitoring/components/graph/deployment.vue
+++ b/app/assets/javascripts/monitoring/components/graph/deployment.vue
@@ -1,16 +1,6 @@
<script>
- import { dateFormatWithName, timeFormat } from '../../utils/date_time_formatters';
- import icon from '../../../vue_shared/components/icon.vue';
-
export default {
- components: {
- icon,
- },
props: {
- showDeployInfo: {
- type: Boolean,
- required: true,
- },
deploymentData: {
type: Array,
required: true,
@@ -23,10 +13,6 @@
type: Number,
required: true,
},
- graphWidth: {
- type: Number,
- required: true,
- },
},
computed: {
@@ -36,165 +22,50 @@
},
methods: {
- refText(d) {
- return d.tag ? d.ref : d.sha.slice(0, 8);
- },
-
- formatTime(deploymentTime) {
- return timeFormat(deploymentTime);
- },
-
- formatDate(deploymentTime) {
- return dateFormatWithName(deploymentTime);
- },
-
- nameDeploymentClass(deployment) {
- return `deploy-info-${deployment.id}`;
- },
-
transformDeploymentGroup(deployment) {
- return `translate(${Math.floor(deployment.xPos) + 1}, 20)`;
- },
-
- positionFlag(deployment) {
- let xPosition = 3;
- if (deployment.xPos > (this.graphWidth - 225)) {
- xPosition = -142;
- }
- return xPosition;
- },
-
- svgContainerHeight(tag) {
- let svgHeight = 80;
- if (!tag) {
- svgHeight -= 20;
- }
- return svgHeight;
+ return `translate(${Math.floor(deployment.xPos) - 5}, 20)`;
},
},
};
</script>
<template>
- <g
- class="deploy-info"
- v-if="showDeployInfo">
+ <g class="deploy-info">
<g
v-for="(deployment, index) in deploymentData"
:key="index"
- :class="nameDeploymentClass(deployment)"
- :transform="transformDeploymentGroup(deployment)"
- >
+ :transform="transformDeploymentGroup(deployment)">
<rect
x="0"
y="0"
:height="calculatedHeight"
width="3"
- fill="url(#shadow-gradient)"
- />
+ fill="url(#shadow-gradient)">
+ </rect>
<line
class="deployment-line"
x1="0"
y1="0"
x2="0"
:y2="calculatedHeight"
- stroke="#000"
- />
- <svg
- v-if="deployment.showDeploymentFlag"
- class="js-deploy-info-box"
- :x="positionFlag(deployment)"
- y="0"
- width="134"
- :height="svgContainerHeight(deployment.tag)"
- >
- <rect
- class="rect-text-metric deploy-info-rect rect-metric"
- x="1"
- y="1"
- rx="2"
- width="132"
- :height="svgContainerHeight(deployment.tag) - 2"
- />
- <text
- class="deploy-info-text text-metric-bold"
- transform="translate(5, 2)"
- >
- Deployed
- </text>
- <!--The date info-->
- <g transform="translate(5, 20)">
- <text class="deploy-info-text">
- {{ formatDate(deployment.time) }}
- </text>
- <text
- class="deploy-info-text text-metric-bold"
- x="62"
- >
- {{ formatTime(deployment.time) }}
- </text>
- </g>
- <line
- class="divider-line"
- x1="0"
- y1="38"
- x2="132"
- :y2="38"
- stroke="#000"
- />
- <!--Commit information-->
- <g transform="translate(5, 40)">
- <icon
- name="commit"
- :width="12"
- :height="12"
- :y="3"
- />
- <a :xlink:href="deployment.commitUrl">
- <text
- class="deploy-info-text deploy-info-text-link"
- transform="translate(20, 2)">
- {{ refText(deployment) }}
- </text>
- </a>
- </g>
- <!--Tag information-->
- <g
- transform="translate(5, 55)"
- v-if="deployment.tag">
- <icon
- name="label"
- :width="12"
- :height="12"
- :y="5"
- />
- <a :xlink:href="deployment.tagUrl">
- <text
- class="deploy-info-text deploy-info-text-link"
- transform="translate(20, 2)"
- y="2"
- >
- {{ deployment.tag }}
- </text>
- </a>
- </g>
- </svg>
+ stroke="#000">
+ </line>
</g>
<svg
height="0"
- width="0"
- >
+ width="0">
<defs>
- <linearGradient id="shadow-gradient">
+ <linearGradient
+ id="shadow-gradient">
<stop
offset="0%"
stop-color="#000"
- stop-opacity="0.4"
- />
+ stop-opacity="0.4">
+ </stop>
<stop
offset="100%"
stop-color="#000"
- stop-opacity="0"
- />
+ stop-opacity="0">
+ </stop>
</linearGradient>
</defs>
</svg>
diff --git a/app/assets/javascripts/monitoring/components/graph/flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue
index f57dc787d3a..62ebc3f419c 100644
--- a/app/assets/javascripts/monitoring/components/graph/flag.vue
+++ b/app/assets/javascripts/monitoring/components/graph/flag.vue
@@ -1,5 +1,7 @@
<script>
import { dateFormat, timeFormat } from '../../utils/date_time_formatters';
+ import { formatRelevantDigits } from '../../../lib/utils/number_utils';
+ import Icon from '../../../vue_shared/components/icon.vue';
export default {
props: {
@@ -7,14 +9,15 @@
type: Number,
required: true,
},
- currentFlagPosition: {
- type: Number,
- required: true,
- },
currentData: {
type: Object,
required: true,
},
+ deploymentFlagData: {
+ type: Object,
+ required: false,
+ default: null,
+ },
graphHeight: {
type: Number,
required: true,
@@ -23,74 +26,173 @@
type: Number,
required: true,
},
+ realPixelRatio: {
+ type: Number,
+ required: true,
+ },
showFlagContent: {
type: Boolean,
required: true,
},
+ timeSeries: {
+ type: Array,
+ required: true,
+ },
+ unitOfDisplay: {
+ type: String,
+ required: true,
+ },
+ currentDataIndex: {
+ type: Number,
+ required: true,
+ },
+ legendTitle: {
+ type: String,
+ required: true,
+ },
},
- data() {
- return {
- circleColorRgb: '#8fbce8',
- };
+ components: {
+ Icon,
},
computed: {
formatTime() {
- return timeFormat(this.currentData.time);
+ return this.deploymentFlagData ?
+ timeFormat(this.deploymentFlagData.time) :
+ timeFormat(this.currentData.time);
},
formatDate() {
- return dateFormat(this.currentData.time);
+ 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`,
+ };
},
- calculatedHeight() {
- return this.graphHeight - this.graphHeightOffset;
+ flagOrientation() {
+ if (this.currentXCoordinate * this.realPixelRatio > 120) {
+ return 'left';
+ }
+ return 'right';
+ },
+ },
+
+ methods: {
+ seriesMetricValue(series) {
+ const index = this.deploymentFlagData ?
+ this.deploymentFlagData.seriesIndex :
+ this.currentDataIndex;
+ const value = series.values[index] &&
+ series.values[index].value;
+ if (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}`;
+ },
+
+ strokeDashArray(type) {
+ if (type === 'dashed') return '6, 3';
+ if (type === 'dotted') return '3, 3';
+ return null;
},
},
};
</script>
+
<template>
- <g class="mouse-over-flag">
- <line
- class="selected-metric-line"
- :x1="currentXCoordinate"
- :y1="0"
- :x2="currentXCoordinate"
- :y2="calculatedHeight"
- transform="translate(-5, 20)"
- />
- <svg
+ <div
+ class="prometheus-graph-cursor"
+ :style="cursorStyle"
+ >
+ <div
v-if="showFlagContent"
- class="rect-text-metric"
- :x="currentFlagPosition"
- y="0"
+ class="prometheus-graph-flag popover"
+ :class="flagOrientation"
>
- <rect
- class="rect-metric"
- x="4"
- y="1"
- rx="2"
- width="90"
- height="40"
- transform="translate(-3, 20)"
- />
- <text
- class="text-metric text-metric-bold"
- x="16"
- y="35"
- transform="translate(-5, 20)"
- >
- {{ formatTime }}
- </text>
- <text
- class="text-metric"
- x="16"
- y="15"
- transform="translate(-5, 20)"
+ <div class="arrow"></div>
+ <div class="popover-title">
+ <h5 v-if="this.deploymentFlagData">
+ Deployed
+ </h5>
+ {{formatDate}} at
+ <strong>{{formatTime}}</strong>
+ </div>
+ <div
+ v-if="this.deploymentFlagData"
+ class="popover-content deploy-meta-content"
>
- {{ formatDate }}
- </text>
- </svg>
- </g>
+ <div>
+ <icon
+ name="commit"
+ :size="12">
+ </icon>
+ <a :href="deploymentFlagData.commitUrl">
+ {{deploymentFlagData.sha.slice(0, 8)}}
+ </a>
+ </div>
+ <div
+ v-if="deploymentFlagData.tag">
+ <icon
+ name="label"
+ :size="12">
+ </icon>
+ <a :href="deploymentFlagData.tagUrl">
+ {{deploymentFlagData.ref}}
+ </a>
+ </div>
+ </div>
+ <div class="popover-content">
+ <table>
+ <tr
+ v-for="(series, index) in timeSeries"
+ :key="index"
+ >
+ <td>
+ <svg width="15" height="6">
+ <line
+ :stroke="series.lineColor"
+ :stroke-dasharray="strokeDashArray(series.lineStyle)"
+ stroke-width="4"
+ x1="0"
+ x2="15"
+ y1="2"
+ y2="2">
+ </line>
+ </svg>
+ </td>
+ <td>{{seriesMetricLabel(index, series)}}</td>
+ <td>
+ <strong>{{seriesMetricValue(series)}}</strong>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
</template>
diff --git a/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js b/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
index cbca14ede02..6cc67ba57ee 100644
--- a/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
+++ b/app/assets/javascripts/monitoring/mixins/monitoring_mixins.js
@@ -29,15 +29,18 @@ const mixins = {
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: `${this.tagsPath}/${deployment.tag}`,
+ tagUrl: deployment.tag ? `${this.tagsPath}/${deployment.ref.name}` : null,
ref: deployment.ref.name,
xPos,
+ seriesIndex,
showDeploymentFlag: false,
});
}
diff --git a/app/assets/javascripts/monitoring/utils/date_time_formatters.js b/app/assets/javascripts/monitoring/utils/date_time_formatters.js
index 068813ddee6..f3c9acdd93e 100644
--- a/app/assets/javascripts/monitoring/utils/date_time_formatters.js
+++ b/app/assets/javascripts/monitoring/utils/date_time_formatters.js
@@ -14,7 +14,7 @@ const d3 = {
timeYear,
};
-export const dateFormat = d3.time('%b %-d, %Y');
+export const dateFormat = d3.time('%a, %b %-d');
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;