github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/public/analytics.js (about) 1 function memStuff(window,document,Chartist) { 2 'use strict'; 3 Chartist.plugins = Chartist.plugins || {}; 4 Chartist.plugins.byteUnits = function(options) { 5 options = Chartist.extend({},{},options); 6 7 return function byteUnits(chart) { 8 if(!chart instanceof Chartist.Line) return; 9 10 chart.on('created', function() { 11 log("running created") 12 const vbits = document.getElementsByClassName("ct-vertical"); 13 if(vbits==null) return; 14 15 let tbits = []; 16 for(let i=0; i<vbits.length; i++) { 17 tbits[i] = vbits[i].innerHTML; 18 } 19 log("tbits",tbits); 20 21 const calc = (places) => { 22 if(places==3) return; 23 24 const matcher = vbits[0].innerHTML; 25 let allMatch = true; 26 for(let i=0; i<tbits.length; i++) { 27 let val = convertByteUnit(tbits[i], places); 28 if(val!=matcher) allMatch = false; 29 vbits[i].innerHTML = val; 30 } 31 if(allMatch) calc(places + 1); 32 } 33 calc(0); 34 }); 35 }; 36 }; 37 } 38 39 function perfStuff(window,document,Chartist) { 40 'use strict'; 41 Chartist.plugins = Chartist.plugins || {}; 42 Chartist.plugins.perfUnits = function(options) { 43 options = Chartist.extend({},{},options); 44 45 return function perfUnits(chart) { 46 if(!chart instanceof Chartist.Line) return; 47 48 chart.on('created', function() { 49 log("running created") 50 const vbits = document.getElementsByClassName("ct-vertical"); 51 if(vbits==null) return; 52 53 let tbits = []; 54 for(let i=0; i<vbits.length; i++) { 55 tbits[i] = vbits[i].innerHTML; 56 } 57 log("tbits:",tbits); 58 59 const calc = (places) => { 60 if(places==3) return; 61 62 const matcher = vbits[0].innerHTML; 63 let allMatch = true; 64 for(let i=0; i<tbits.length; i++) { 65 let val = convertPerfUnit(tbits[i], places); 66 if(val!=matcher) allMatch = false; 67 vbits[i].innerHTML = val; 68 } 69 if(allMatch) calc(places + 1); 70 } 71 calc(0); 72 }); 73 }; 74 }; 75 } 76 77 const Kilobyte = 1024; 78 const Megabyte = Kilobyte * 1024; 79 const Gigabyte = Megabyte * 1024; 80 const Terabyte = Gigabyte * 1024; 81 const Petabyte = Terabyte * 1024; 82 83 function convertByteUnit(bytes, places = 0) { 84 let o; 85 if(bytes >= Petabyte) o = [bytes / Petabyte, "PB"]; 86 else if(bytes >= Terabyte) o = [bytes / Terabyte, "TB"]; 87 else if(bytes >= Gigabyte) o = [bytes / Gigabyte, "GB"]; 88 else if(bytes >= Megabyte) o = [bytes / Megabyte, "MB"]; 89 else if(bytes >= Kilobyte) o = [bytes / Kilobyte, "KB"]; 90 else o = [bytes,"b"]; 91 92 if(places==0) return Math.ceil(o[0]) + o[1]; 93 else { 94 let ex = Math.pow(10, places); 95 return (Math.round(o[0], ex) / ex) + o[1]; 96 } 97 } 98 99 let ms = 1000; 100 let sec = ms * 1000; 101 let min = sec * 60; 102 let hour = min * 60; 103 let day = hour * 24; 104 function convertPerfUnit(quan, places = 0) { 105 let o; 106 if(quan >= day) o = [quan / day, "d"]; 107 else if(quan >= hour) o = [quan / hour, "h"]; 108 else if(quan >= min) o = [quan / min, "m"]; 109 else if(quan >= sec) o = [quan / sec, "s"]; 110 else if(quan >= ms) o = [quan / ms, "ms"]; 111 else o = [quan,"μs"]; 112 113 if(places==0) return Math.ceil(o[0]) + o[1]; 114 else { 115 let ex = Math.pow(10, places); 116 return (Math.round(o[0], ex) / ex) + o[1]; 117 } 118 } 119 120 // TODO: Fully localise this 121 // TODO: Load rawLabels and seriesData dynamically rather than potentially fiddling with nonces for the CSP? 122 function buildStatsChart(rawLabels, seriesData, timeRange, legendNames, typ=0) { 123 log("buildStatsChart"); 124 log("seriesData",seriesData); 125 let labels = []; 126 let aphrases = phraseBox["analytics"]; 127 if(timeRange=="one-year") { 128 labels = [aphrases["analytics.now"],"1" + aphrases["analytics.months_short"]]; 129 for(let i = 2; i < 12; i++) { 130 labels.push(i + aphrases["analytics.months_short"]); 131 } 132 } else if(timeRange=="three-months") { 133 labels = [aphrases["analytics.now"],"3" + aphrases["analytics.days_short"]] 134 for(let i = 6; i < 90; i = i + 3) { 135 if (i%2==0) labels.push(""); 136 else labels.push(i + aphrases["analytics.days_short"]); 137 } 138 } else if(timeRange=="one-month") { 139 labels = [aphrases["analytics.now"],"1" + aphrases["analytics.days_short"]]; 140 for(let i = 2; i < 30; i++) { 141 if (i%2==0) labels.push(""); 142 else labels.push(i + aphrases["analytics.days_short"]); 143 } 144 } else if(timeRange=="one-week") { 145 labels = [aphrases["analytics.now"]]; 146 for(let i = 2; i < 14; i++) { 147 if (i%2==0) labels.push(""); 148 else labels.push(Math.floor(i/2) + aphrases["analytics.days"]); 149 } 150 } else if (timeRange=="two-days" || timeRange == "one-day" || timeRange == "twelve-hours") { 151 for(const i in rawLabels) { 152 if (i%2==0) { 153 labels.push(""); 154 continue; 155 } 156 let date = new Date(rawLabels[i]*1000); 157 log("date",date); 158 let minutes = "0" + date.getMinutes(); 159 let label = date.getHours() + ":" + minutes.substr(-2); 160 log("label",label); 161 labels.push(label); 162 } 163 } else { 164 for(const i in rawLabels) { 165 let date = new Date(rawLabels[i]*1000); 166 log("date",date); 167 let minutes = "0" + date.getMinutes(); 168 let label = date.getHours() + ":" + minutes.substr(-2); 169 log("label",label); 170 labels.push(label); 171 } 172 } 173 labels = labels.reverse() 174 for(let i = 0; i < seriesData.length; i++) { 175 seriesData[i] = seriesData[i].reverse(); 176 } 177 178 let config = {height: '250px', plugins:[]}; 179 if(legendNames.length > 0) config.plugins = [ 180 Chartist.plugins.legend({legendNames: legendNames}) 181 ]; 182 if(typ==1) config.plugins.push(Chartist.plugins.byteUnits()); 183 else if(typ==2) config.plugins.push(Chartist.plugins.perfUnits()); 184 Chartist.Line('.ct_chart', { 185 labels: labels, 186 series: seriesData, 187 }, config); 188 } 189 190 runInitHook("analytics_loaded");