• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1export class EchartsData {
2  /**
3   * Given a set of [key, value] pairs and title, create an object for further
4   * usage in Vue-Echarts.
5   * @param {Map} statisticData
6   * @param {String} title
7   * @param {String} unit
8   * @param {Number} maximumEntries
9   */
10  constructor(statisticData, title, unit, maximumEntries = 15) {
11    this.statisticData = statisticData
12    this.title = title
13    this.unit = unit
14    this.maximumEntries = maximumEntries
15  }
16
17  /**
18   * Convert the raw data into a string.
19   * @return {String} A list of [key, value].
20   */
21  listData() {
22    let /** String */ table = ''
23    for (let [key, value] of this.statisticData) {
24      table += key + ' : ' + value.toString() + ' Blocks' + '\n'
25    }
26    return table
27  }
28
29  /**
30   * Generate necessary parameters (option) for vue-echarts.
31   * Format of the parameters can be found here:
32   * https://echarts.apache.org/en/option.html
33   * @param {String} unit
34   * @return {Object} an ECharts option object.
35   */
36  getEchartsOption() {
37    if (this.statisticData.size > this.maximumEntries) {
38      this.statisticData = trimMap(this.statisticData, this.maximumEntries)
39    }
40    let /** Object */ option = new Object()
41    option.title = {
42      text: this.title,
43      left: "center"
44    }
45    option.tooltip = {
46      trigger: "item",
47      formatter: "{a} <br/>{b} : {c} " + this.unit + " ({d}%)"
48    }
49    option.legend = {
50      orient: "horizontal",
51      left: "top",
52      top: "10%",
53      data: Array.from(this.statisticData.keys())
54    }
55    option.series = [
56      {
57        name: this.title,
58        type: "pie",
59        radius: "55%",
60        center: ["50%", "60%"],
61        data: Array.from(this.statisticData).map((pair) => {
62          return { value: pair[1], name: pair[0] }
63        }),
64        emphasis: {
65          itemStyle: {
66            shadowBlur: 10,
67            shadowOffsetX: 0,
68            shadowColor: "rgba(0, 0, 0, 0.5)"
69          }
70        }
71      }
72    ]
73    return option
74  }
75}
76
77/**
78 * When there are too many entries in the map, the pie chart can be very
79 * crowded. This function will return the entries that have high values.
80 * Specifically, the top <maximumEntries> will be stored and the others
81 * will be added into an entry called 'other'.
82 * @param {Map} map
83 * @param {Number} maximumEntries
84 * @return {Map}
85 */
86function trimMap(map, maximumEntries) {
87  if (map.size <= maximumEntries) return map
88  let /** Map */ new_map = new Map()
89  for (let i=0; i<maximumEntries; i++) {
90    let /** Number */ curr = 0
91    let /** String */ currKey = ''
92    for (let [key, value] of map) {
93      if (!new_map.get(key)) {
94        if (value > curr) {
95          curr = value
96          currKey = key
97        }
98      }
99    }
100    new_map.set(currKey, curr)
101  }
102  let /** Number */ restTotal = 0
103  for (let [key, value] of map) {
104    if (!new_map.get(key)) {
105      restTotal += value
106    }
107  }
108  new_map.set('other', restTotal)
109  return new_map
110}