1
+ ( ( ) => {
2
+ window . addEventListener ( 'load' , async ( event ) => {
3
+ const containerChart = document . querySelector ( 'div#system_chart_div' ) ;
4
+ if ( ! containerChart ) {
5
+ return ;
6
+ }
7
+
8
+ google . charts . load ( 'current' , {
9
+ packages : [ 'corechart' , 'controls' ] ,
10
+ callback : drawCharts ,
11
+ } ) ;
12
+
13
+ function drawCharts ( ) {
14
+ const request = new XMLHttpRequest ( ) ;
15
+ request . open ( 'GET' , '/admin/stats/system.json' ) ;
16
+ request . overrideMimeType ( 'application/json' ) ;
17
+
18
+ request . onload = ( event ) => {
19
+ const data = JSON . parse ( request . response ) ;
20
+ drawSystemCodeChart ( data ) ;
21
+ } ;
22
+
23
+ request . onerror = ( event ) => {
24
+ console . error ( 'error from response: ' + request . response ) ;
25
+ flash . error ( 'Failed to load realm stats: ' + err ) ;
26
+ } ;
27
+
28
+ request . send ( ) ;
29
+ }
30
+
31
+ function drawSystemCodeChart ( data ) {
32
+ const charts = [
33
+ {
34
+ chartType : 'LineChart' ,
35
+ chartDiv : '#system_chart_div' ,
36
+ dashboardDiv : '#dashboard_div' ,
37
+ filterDiv : '#filter_div' ,
38
+ headerFunc : ( dataTable , hasKeyServerStats ) => {
39
+ dataTable . addColumn ( 'date' , 'Date' ) ;
40
+ dataTable . addColumn ( 'number' , 'Codes Issued' ) ;
41
+ dataTable . addColumn ( 'number' , 'Codes Claimed' ) ;
42
+ } ,
43
+ rowFunc : ( dataTable , row , hasKeyServerStats ) => {
44
+ if ( hasKeyServerStats ) {
45
+ dataTable . addRow ( [
46
+ utcDate ( row . date ) ,
47
+ row . data . codes_issued ,
48
+ row . data . codes_claimed ,
49
+ ] ) ;
50
+ } else {
51
+ dataTable . addRow ( [
52
+ utcDate ( row . date ) ,
53
+ row . data . codes_issued ,
54
+ row . data . codes_claimed ,
55
+ ] ) ;
56
+ }
57
+ } ,
58
+ } ,
59
+ ] ;
60
+
61
+ const dateFormatter = new google . visualization . DateFormat ( {
62
+ pattern : 'MMM dd' ,
63
+ } ) ;
64
+
65
+ for ( let i = 0 ; i < charts . length ; i ++ ) {
66
+ const chart = charts [ i ] ;
67
+ const chartContainer = document . querySelector ( chart . chartDiv ) ;
68
+ const dashboardContainer = document . querySelector ( chart . dashboardDiv ) ;
69
+ const filterContainer = document . querySelector ( chart . filterDiv ) ;
70
+
71
+ if ( ! chartContainer || ! dashboardContainer || ! filterContainer ) {
72
+ continue ;
73
+ }
74
+
75
+ if ( ! data || ! data . statistics ) {
76
+ const pContainer = chartContainer . querySelector ( 'p' ) ;
77
+ pContainer . innerText = 'No data yet.' ;
78
+ continue ;
79
+ }
80
+
81
+ const hasKeyServerStats = data . has_key_server_stats ;
82
+ const win = Math . min ( 30 , data . statistics . length - 1 ) ;
83
+ const startChart = new Date ( data . statistics [ win ] . date ) ;
84
+
85
+ const dataTable = new google . visualization . DataTable ( ) ;
86
+ chart . headerFunc ( dataTable , hasKeyServerStats ) ;
87
+ for ( let j = 0 ; j < data . statistics . length ; j ++ ) {
88
+ const stat = data . statistics [ j ] ;
89
+ chart . rowFunc ( dataTable , stat , hasKeyServerStats ) ;
90
+ }
91
+ dateFormatter . format ( dataTable , 0 ) ;
92
+
93
+ const dashboard = new google . visualization . Dashboard ( dashboardContainer ) ;
94
+ const filter = new google . visualization . ControlWrapper ( {
95
+ controlType : 'ChartRangeFilter' ,
96
+ containerId : filterContainer ,
97
+ state : {
98
+ range : {
99
+ start : startChart ,
100
+ } ,
101
+ } ,
102
+ options : {
103
+ filterColumnIndex : 0 ,
104
+ series : {
105
+ 0 : {
106
+ opacity : 0 ,
107
+ } ,
108
+ } ,
109
+ ui : {
110
+ chartType : 'LineChart' ,
111
+ chartOptions : {
112
+ colors : [ '#dddddd' ] ,
113
+ chartArea : {
114
+ width : '100%' ,
115
+ height : '100%' ,
116
+ top : 0 ,
117
+ right : 40 ,
118
+ bottom : 20 ,
119
+ left : 60 ,
120
+ } ,
121
+ isStacked : true ,
122
+ hAxis : { format : 'M/d' } ,
123
+ } ,
124
+ chartView : {
125
+ columns : [ 0 , 1 ] ,
126
+ } ,
127
+ minRangeSize : 86400000 , // ms for 1 day
128
+ } ,
129
+ } ,
130
+ } ) ;
131
+
132
+ const realmChart = new google . visualization . ChartWrapper ( {
133
+ chartType : chart . chartType ,
134
+ containerId : chartContainer ,
135
+ options : {
136
+ colors : [ '#007bff' , '#28a745' , '#dc3545' , '#6c757d' , '#ee8c00' ] ,
137
+ chartArea : {
138
+ left : 60 ,
139
+ right : 40 ,
140
+ bottom : 5 ,
141
+ top : 40 ,
142
+ width : '100%' ,
143
+ height : '300' ,
144
+ } ,
145
+ isStacked : true ,
146
+ hAxis : { textPosition : 'none' } ,
147
+ legend : { position : 'top' } ,
148
+ width : '100%' ,
149
+ } ,
150
+ } ) ;
151
+
152
+ dashboard . bind ( filter , realmChart ) ;
153
+ dashboard . draw ( dataTable ) ;
154
+ debounce ( 'resize' , async ( ) => dashboard . draw ( dataTable ) ) ;
155
+ }
156
+ }
157
+ } ) ;
158
+ } ) ( ) ;
159
+
0 commit comments