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}