127 lines
3.3 KiB
Vue
127 lines
3.3 KiB
Vue
<script>
|
|
import { getTimeago } from '../../lib/utils/datetime_utility';
|
|
|
|
export default {
|
|
name: 'MemoryGraph',
|
|
props: {
|
|
metrics: { type: Array, required: true },
|
|
deploymentTime: { type: Number, required: true },
|
|
width: { type: String, required: true },
|
|
height: { type: String, required: true },
|
|
},
|
|
data() {
|
|
return {
|
|
pathD: '',
|
|
pathViewBox: '',
|
|
dotX: '',
|
|
dotY: '',
|
|
};
|
|
},
|
|
computed: {
|
|
getFormattedMedian() {
|
|
const deployedSince = getTimeago().format(this.deploymentTime * 1000);
|
|
return `Deployed ${deployedSince}`;
|
|
},
|
|
},
|
|
mounted() {
|
|
this.renderGraph(this.deploymentTime, this.metrics);
|
|
},
|
|
methods: {
|
|
/**
|
|
* Returns metric value index in metrics array
|
|
* with timestamp closest to matching median
|
|
*/
|
|
getMedianMetricIndex(median, metrics) {
|
|
let matchIndex = 0;
|
|
let timestampDiff = 0;
|
|
let smallestDiff = 0;
|
|
|
|
const metricTimestamps = metrics.map(v => v[0]);
|
|
|
|
// Find metric timestamp which is closest to deploymentTime
|
|
timestampDiff = Math.abs(metricTimestamps[0] - median);
|
|
metricTimestamps.forEach((timestamp, index) => {
|
|
if (index === 0) {
|
|
// Skip first element
|
|
return;
|
|
}
|
|
|
|
smallestDiff = Math.abs(timestamp - median);
|
|
if (smallestDiff < timestampDiff) {
|
|
matchIndex = index;
|
|
timestampDiff = smallestDiff;
|
|
}
|
|
});
|
|
|
|
return matchIndex;
|
|
},
|
|
|
|
/**
|
|
* Get Graph Plotting values to render Line and Dot
|
|
*/
|
|
getGraphPlotValues(median, metrics) {
|
|
const renderData = metrics.map(v => v[1]);
|
|
const medianMetricIndex = this.getMedianMetricIndex(median, metrics);
|
|
let cx = 0;
|
|
let cy = 0;
|
|
|
|
// Find Maximum and Minimum values from `renderData` array
|
|
const maxMemory = Math.max.apply(null, renderData);
|
|
const minMemory = Math.min.apply(null, renderData);
|
|
|
|
// Find difference between extreme ends
|
|
const diff = maxMemory - minMemory;
|
|
const lineWidth = renderData.length;
|
|
|
|
// Iterate over metrics values and perform following
|
|
// 1. Find x & y co-ords for deploymentTime's memory value
|
|
// 2. Return line path against maxMemory
|
|
const linePath = renderData.map((y, x) => {
|
|
if (medianMetricIndex === x) {
|
|
cx = x;
|
|
cy = maxMemory - y;
|
|
}
|
|
return `${x} ${maxMemory - y}`;
|
|
});
|
|
|
|
return {
|
|
pathD: linePath,
|
|
pathViewBox: {
|
|
lineWidth,
|
|
diff,
|
|
},
|
|
dotX: cx,
|
|
dotY: cy,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Render Graph based on provided median and metrics values
|
|
*/
|
|
renderGraph(median, metrics) {
|
|
const { pathD, pathViewBox, dotX, dotY } = this.getGraphPlotValues(median, metrics);
|
|
|
|
// Set props and update graph on UI.
|
|
this.pathD = `M ${pathD}`;
|
|
this.pathViewBox = `0 0 ${pathViewBox.lineWidth} ${pathViewBox.diff}`;
|
|
this.dotX = dotX;
|
|
this.dotY = dotY;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="memory-graph-container">
|
|
<svg
|
|
:title="getFormattedMedian"
|
|
:width="width"
|
|
:height="height"
|
|
class="has-tooltip"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
>
|
|
<path :d="pathD" :viewBox="pathViewBox" />
|
|
<circle :cx="dotX" :cy="dotY" r="1.5" transform="translate(0 -1)" />
|
|
</svg>
|
|
</div>
|
|
</template>
|