memory_graph.vue 3.37 KB
Newer Older
1
<script>
2 3
import { getTimeago } from '../../lib/utils/datetime_utility';

Fatih Acet's avatar
Fatih Acet committed
4 5 6 7
export default {
  name: 'MemoryGraph',
  props: {
    metrics: { type: Array, required: true },
8
    deploymentTime: { type: Number, required: true },
Fatih Acet's avatar
Fatih Acet committed
9 10 11 12 13 14 15
    width: { type: String, required: true },
    height: { type: String, required: true },
  },
  data() {
    return {
      pathD: '',
      pathViewBox: '',
16 17
      dotX: '',
      dotY: '',
Fatih Acet's avatar
Fatih Acet committed
18 19
    };
  },
20 21
  computed: {
    getFormattedMedian() {
22
      const deployedSince = getTimeago().format(this.deploymentTime * 1000);
23 24 25
      return `Deployed ${deployedSince}`;
    },
  },
26 27 28
  mounted() {
    this.renderGraph(this.deploymentTime, this.metrics);
  },
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
  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;
    },
  },
Fatih Acet's avatar
Fatih Acet committed
110
};
111 112 113 114 115 116 117 118
</script>

<template>
  <div class="memory-graph-container">
    <svg
      :title="getFormattedMedian"
      :width="width"
      :height="height"
119
      class="has-tooltip"
120 121 122 123 124 125 126 127
      xmlns="http://www.w3.org/2000/svg">
      <path
        :d="pathD"
        :viewBox="pathViewBox"
      />
      <circle
        :cx="dotX"
        :cy="dotY"
128
        r="1.5"
Kushal Pandya's avatar
Kushal Pandya committed
129
        transform="translate(0 -1)"
130 131 132 133
      />
    </svg>
  </div>
</template>