diff options
author | Adriel Santiago <adriel@gitlab.com> | 2019-01-23 18:06:40 -0500 |
---|---|---|
committer | Adriel Santiago <adriel@gitlab.com> | 2019-02-04 08:04:45 -0500 |
commit | c974f4a82ee3cd4b5b73b95d66d99854a0e5d3bc (patch) | |
tree | 183122acce41af316c31515c5c7431e886db282b /app/assets/javascripts | |
parent | 2b0f4df0217b4a4aee53f964610d66ceedb68dca (diff) | |
download | gitlab-ce-c974f4a82ee3cd4b5b73b95d66d99854a0e5d3bc.tar.gz |
Handle window and container resize events
Resizes metrics graph on window and sidebard width changes
Diffstat (limited to 'app/assets/javascripts')
3 files changed, 65 insertions, 24 deletions
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index ae8b4b4d635..0ceff10a02a 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -221,6 +221,22 @@ export const scrollToElement = element => { }; /** + * Returns a function that can only be invoked once between + * each browser screen repaint. + * @param {Function} fn + */ +export const debounceByAnimationFrame = fn => { + let requestId; + + return function debounced(...args) { + if (requestId) { + window.cancelAnimationFrame(requestId); + } + requestId = window.requestAnimationFrame(() => fn.apply(this, args)); + }; +}; + +/** this will take in the `name` of the param you want to parse in the url if the name does not exist this function will return `null` otherwise it will return the value of the param key provided diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue index 5ca561259b6..91004ca54a9 100644 --- a/app/assets/javascripts/monitoring/components/charts/area.vue +++ b/app/assets/javascripts/monitoring/components/charts/area.vue @@ -1,6 +1,9 @@ <script> import { GlAreaChart } from '@gitlab/ui'; import dateFormat from 'dateformat'; +import { debounceByAnimationFrame } from '~/lib/utils/common_utils'; + +let debouncedResize; export default { components: { @@ -26,12 +29,22 @@ export default { ); }, }, + containerWidth: { + type: Number, + required: true, + }, alertData: { type: Object, required: false, default: () => ({}), }, }, + data() { + return { + width: 0, + height: 0, + }; + }, computed: { chartData() { return this.graphData.queries.reduce((accumulator, query) => { @@ -76,11 +89,26 @@ export default { return `${this.graphData.y_label} (${query.unit})`; }, }, + watch: { + containerWidth: 'onResize', + }, + beforeDestroy() { + window.removeEventListener('resize', debouncedResize); + }, + created() { + debouncedResize = debounceByAnimationFrame(this.onResize); + window.addEventListener('resize', debouncedResize); + }, methods: { formatTooltipText(params) { const [date, value] = params; return [dateFormat(date, 'dd mmm yyyy, h:MMtt'), value.toFixed(3)]; }, + onResize() { + const { width, height } = this.$refs.areaChart.$el.getBoundingClientRect(); + this.width = width; + this.height = height; + }, }, }; </script> @@ -92,11 +120,14 @@ export default { <div class="prometheus-graph-widgets"><slot></slot></div> </div> <gl-area-chart + ref="areaChart" v-bind="$attrs" :data="chartData" :option="chartOptions" :format-tooltip-text="formatTooltipText" :thresholds="alertData" + :width="width" + :height="height" /> </div> </template> diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 0b4bb9cc686..76059cb602d 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -1,5 +1,4 @@ <script> -import _ from 'underscore'; import { s__ } from '~/locale'; import Icon from '~/vue_shared/components/icon.vue'; import Flash from '../../flash'; @@ -9,6 +8,9 @@ import GraphGroup from './graph_group.vue'; import EmptyState from './empty_state.vue'; import MonitoringStore from '../stores/monitoring_store'; +const sidebarAnimationDuration = 150; +let sidebarMutationObserver; + export default { components: { MonitorAreaChart, @@ -89,39 +91,29 @@ export default { elWidth: 0, }; }, - computed: { - forceRedraw() { - return this.elWidth; - }, - }, created() { this.service = new MonitoringService({ metricsEndpoint: this.metricsEndpoint, deploymentEndpoint: this.deploymentEndpoint, environmentsEndpoint: this.environmentsEndpoint, }); - this.mutationObserverConfig = { - attributes: true, - childList: false, - subtree: false, - }; }, beforeDestroy() { - window.removeEventListener('resize', this.resizeThrottled, false); - this.sidebarMutationObserver.disconnect(); + if (sidebarMutationObserver) { + sidebarMutationObserver.disconnect(); + } }, mounted() { - this.resizeThrottled = _.debounce(this.resize, 100); if (!this.hasMetrics) { this.state = 'gettingStarted'; } else { this.getGraphsData(); - window.addEventListener('resize', this.resizeThrottled, false); - - const sidebarEl = document.querySelector('.nav-sidebar'); - // The sidebar listener - this.sidebarMutationObserver = new MutationObserver(this.resizeThrottled); - this.sidebarMutationObserver.observe(sidebarEl, this.mutationObserverConfig); + sidebarMutationObserver = new MutationObserver(this.onSidebarMutation); + sidebarMutationObserver.observe(document.querySelector('.layout-page'), { + attributes: true, + childList: false, + subtree: false, + }); } }, methods: { @@ -149,20 +141,21 @@ export default { this.showEmptyState = false; }) - .then(this.resize) .catch(() => { this.state = 'unableToConnect'; }); }, - resize() { - this.elWidth = this.$el.clientWidth; + onSidebarMutation() { + setTimeout(() => { + this.elWidth = this.$el.clientWidth; + }, sidebarAnimationDuration); }, }, }; </script> <template> - <div v-if="!showEmptyState" :key="forceRedraw" class="prometheus-graphs prepend-top-default"> + <div v-if="!showEmptyState" class="prometheus-graphs prepend-top-default"> <div class="environments d-flex align-items-center"> {{ s__('Metrics|Environment') }} <div class="dropdown prepend-left-10"> @@ -198,6 +191,7 @@ export default { :key="graphIndex" :graph-data="graphData" :alert-data="getGraphAlerts(graphData.id)" + :container-width="elWidth" group-id="monitor-area-chart" /> </graph-group> |