diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-01-08 19:19:52 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-01-08 19:19:52 +0000 |
commit | e2b759a2f483663e0771180de6b97bb9344a56cd (patch) | |
tree | 32cd72a70e405dc0858d774ca3354d6aef1bf445 /app/assets/javascripts/monitoring | |
parent | 7ca5a3f99dd3a3c1800f65da7b4f08395a97395a (diff) | |
parent | df74461014bbdbc691f4f4039b02962dad292362 (diff) | |
download | gitlab-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')
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; |