Revision 6c07db48
Added by Phil Davis about 10 years ago
usr/local/www/graph.php | ||
---|---|---|
43 | 43 |
require("globals.inc"); |
44 | 44 |
require("guiconfig.inc"); |
45 | 45 |
|
46 |
header("Last-Modified: " . gmdate( "D, j M Y H:i:s" ) . " GMT" );
|
|
47 |
header("Expires: " . gmdate( "D, j M Y H:i:s", time() ) . " GMT" );
|
|
48 |
header("Cache-Control: no-cache, no-store, must-revalidate" ); // HTTP/1.1
|
|
46 |
header("Last-Modified: " . gmdate("D, j M Y H:i:s") . " GMT");
|
|
47 |
header("Expires: " . gmdate("D, j M Y H:i:s", time()) . " GMT");
|
|
48 |
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP/1.1 |
|
49 | 49 |
header("Pragma: no-cache"); // HTTP/1.0 |
50 | 50 |
header("Content-type: image/svg+xml"); |
51 | 51 |
|
52 | 52 |
/********** HTTP GET Based Conf ***********/ |
53 |
$ifnum=@$_GET["ifnum"]; // BSD / SNMP interface name / number
|
|
53 |
$ifnum = @$_GET["ifnum"]; // BSD / SNMP interface name / number
|
|
54 | 54 |
$ifnum = get_real_interface($ifnum); |
55 |
$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum"; //Interface name that will be showed on top right of graph
|
|
55 |
$ifname = @$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum"; //Interface name that will be showed on top right of graph
|
|
56 | 56 |
|
57 | 57 |
/********* Other conf *******/ |
58 | 58 |
if (isset($config["widgets"]["trafficgraphs"]["scale_type"])) { |
... | ... | |
106 | 106 |
/********* Graph DATA **************/ |
107 | 107 |
print('<?xml version="1.0" encoding="UTF-8"?>' . "\n");?> |
108 | 108 |
<svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)"> |
109 |
<g id="graph">
|
|
110 |
<rect id="bg" x1="0" y1="0" width="100%" height="100%" fill="white"/>
|
|
111 |
<line id="axis_x" x1="0" y1="0" x2="0" y2="100%" <?=$attribs['axis']?>/>
|
|
112 |
<line id="axis_y" x1="0" y1="100%" x2="100%" y2="100%" <?=$attribs['axis']?>/>
|
|
113 |
<path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" <?=$attribs['graph_out']?>/>
|
|
114 |
<path id="graph_in" d="M0 <?=$height?> L 0 <?=$height?>" <?=$attribs['graph_in']?>/>
|
|
115 |
<path id="grid" d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" <?=$attribs['grid']?>/>
|
|
116 |
<text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
|
|
117 |
<text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
|
|
118 |
<text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
|
|
119 |
<text id="graph_in_lbl" x="5" y="8" <?=$attribs['in']?>><?=gettext("In"); ?></text>
|
|
120 |
<text id="graph_out_lbl" x="5" y="16" <?=$attribs['out']?>><?=gettext("Out"); ?></text>
|
|
121 |
<text id="graph_in_txt" x="20" y="8" <?=$attribs['in']?>> </text>
|
|
122 |
<text id="graph_out_txt" x="20" y="16" <?=$attribs['out']?>> </text>
|
|
123 |
<text id="ifname" x="<?=$width?>" y="8" <?=$attribs['graphname']?> text-anchor="end"><?=htmlspecialchars($ifname)?></text>
|
|
124 |
<text id="switch_unit" x="<?=$width*0.55?>" y="5" <?=$attribs['switch_unit']?>><?=gettext("Switch to bytes/s"); ?></text>
|
|
125 |
<text id="switch_scale" x="<?=$width*0.55?>" y="11" <?=$attribs['switch_scale']?>><?=gettext("AutoScale"); ?> (<?=$scale_type?>)</text>
|
|
126 |
<text id="date" x="<?=$width*0.33?>" y="5" <?=$attribs['legend']?>> </text>
|
|
127 |
<text id="time" x="<?=$width*0.33?>" y="11" <?=$attribs['legend']?>> </text>
|
|
128 |
<text id="graphlast" x="<?=$width*0.55?>" y="17" <?=$attribs['legend']?>><?=gettext("Graph shows last"); ?> <?=$time_interval*$nb_plot?> <?=gettext("seconds"); ?></text>
|
|
129 |
<polygon id="axis_arrow_x" <?=$attribs['axis']?> points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
|
|
130 |
<text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>" visibility="hidden" <?=$attribs['error']?> text-anchor="middle"><?=$error_text?></text>
|
|
131 |
<text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>" visibility="hidden" <?=$attribs['collect_initial']?> text-anchor="middle"><?=gettext("Collecting initial data, please wait"); ?>...</text>
|
|
132 |
</g>
|
|
133 |
<script type="text/ecmascript">
|
|
134 |
<![CDATA[
|
|
109 |
<g id="graph">
|
|
110 |
<rect id="bg" x1="0" y1="0" width="100%" height="100%" fill="white"/>
|
|
111 |
<line id="axis_x" x1="0" y1="0" x2="0" y2="100%" <?=$attribs['axis']?>/>
|
|
112 |
<line id="axis_y" x1="0" y1="100%" x2="100%" y2="100%" <?=$attribs['axis']?>/>
|
|
113 |
<path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" <?=$attribs['graph_out']?>/>
|
|
114 |
<path id="graph_in" d="M0 <?=$height?> L 0 <?=$height?>" <?=$attribs['graph_in']?>/>
|
|
115 |
<path id="grid" d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" <?=$attribs['grid']?>/>
|
|
116 |
<text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
|
|
117 |
<text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
|
|
118 |
<text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
|
|
119 |
<text id="graph_in_lbl" x="5" y="8" <?=$attribs['in']?>><?=gettext("In"); ?></text>
|
|
120 |
<text id="graph_out_lbl" x="5" y="16" <?=$attribs['out']?>><?=gettext("Out"); ?></text>
|
|
121 |
<text id="graph_in_txt" x="20" y="8" <?=$attribs['in']?>> </text>
|
|
122 |
<text id="graph_out_txt" x="20" y="16" <?=$attribs['out']?>> </text>
|
|
123 |
<text id="ifname" x="<?=$width?>" y="8" <?=$attribs['graphname']?> text-anchor="end"><?=htmlspecialchars($ifname)?></text>
|
|
124 |
<text id="switch_unit" x="<?=$width*0.55?>" y="5" <?=$attribs['switch_unit']?>><?=gettext("Switch to bytes/s"); ?></text>
|
|
125 |
<text id="switch_scale" x="<?=$width*0.55?>" y="11" <?=$attribs['switch_scale']?>><?=gettext("AutoScale"); ?> (<?=$scale_type?>)</text>
|
|
126 |
<text id="date" x="<?=$width*0.33?>" y="5" <?=$attribs['legend']?>> </text>
|
|
127 |
<text id="time" x="<?=$width*0.33?>" y="11" <?=$attribs['legend']?>> </text>
|
|
128 |
<text id="graphlast" x="<?=$width*0.55?>" y="17" <?=$attribs['legend']?>><?=gettext("Graph shows last"); ?> <?=$time_interval*$nb_plot?> <?=gettext("seconds"); ?></text>
|
|
129 |
<polygon id="axis_arrow_x" <?=$attribs['axis']?> points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
|
|
130 |
<text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>" visibility="hidden" <?=$attribs['error']?> text-anchor="middle"><?=$error_text?></text>
|
|
131 |
<text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>" visibility="hidden" <?=$attribs['collect_initial']?> text-anchor="middle"><?=gettext("Collecting initial data, please wait"); ?>...</text>
|
|
132 |
</g>
|
|
133 |
<script type="text/ecmascript">
|
|
134 |
<![CDATA[
|
|
135 | 135 |
|
136 | 136 |
/** |
137 | 137 |
* getURL is a proprietary Adobe function, but it's simplicity has made it very |
138 | 138 |
* popular. If getURL is undefined we spin our own by wrapping XMLHttpRequest. |
139 | 139 |
*/ |
140 | 140 |
if (typeof getURL == 'undefined') { |
141 |
getURL = function(url, callback) { |
|
142 |
if (!url) |
|
143 |
throw '<?=gettext("No URL for getURL"); ?>'; |
|
144 |
|
|
145 |
try { |
|
146 |
if (typeof callback.operationComplete == 'function') |
|
147 |
callback = callback.operationComplete; |
|
148 |
} catch (e) {} |
|
149 |
if (typeof callback != 'function') |
|
150 |
throw '<?=gettext("No callback function for getURL"); ?>'; |
|
151 |
|
|
152 |
var http_request = null; |
|
153 |
if (typeof XMLHttpRequest != 'undefined') { |
|
154 |
http_request = new XMLHttpRequest(); |
|
155 |
} else if (typeof ActiveXObject != 'undefined') { |
|
156 |
try { |
|
157 |
http_request = new ActiveXObject('Msxml2.XMLHTTP'); |
|
158 |
} catch (e) { |
|
159 |
try { |
|
160 |
http_request = new ActiveXObject('Microsoft.XMLHTTP'); |
|
161 |
} catch (e) {} |
|
162 |
} |
|
163 |
} |
|
164 |
if (!http_request) |
|
165 |
throw '<?=gettext("Both getURL and XMLHttpRequest are undefined"); ?>'; |
|
166 |
|
|
167 |
http_request.onreadystatechange = function() { |
|
168 |
if (http_request.readyState == 4) { |
|
169 |
callback( { success : true, |
|
170 |
content : http_request.responseText, |
|
171 |
contentType : http_request.getResponseHeader("Content-Type") } ); |
|
172 |
} |
|
173 |
} |
|
174 |
http_request.open('GET', url, true); |
|
175 |
http_request.send(null); |
|
176 |
} |
|
141 |
getURL = function(url, callback) { |
|
142 |
if (!url) { |
|
143 |
throw '<?=gettext("No URL for getURL"); ?>'; |
|
144 |
} |
|
145 |
|
|
146 |
try { |
|
147 |
if (typeof callback.operationComplete == 'function') { |
|
148 |
callback = callback.operationComplete; |
|
149 |
} |
|
150 |
} catch (e) {} |
|
151 |
if (typeof callback != 'function') { |
|
152 |
throw '<?=gettext("No callback function for getURL"); ?>'; |
|
153 |
} |
|
154 |
|
|
155 |
var http_request = null; |
|
156 |
if (typeof XMLHttpRequest != 'undefined') { |
|
157 |
http_request = new XMLHttpRequest(); |
|
158 |
} else if (typeof ActiveXObject != 'undefined') { |
|
159 |
try { |
|
160 |
http_request = new ActiveXObject('Msxml2.XMLHTTP'); |
|
161 |
} catch (e) { |
|
162 |
try { |
|
163 |
http_request = new ActiveXObject('Microsoft.XMLHTTP'); |
|
164 |
} catch (e) {} |
|
165 |
} |
|
166 |
} |
|
167 |
if (!http_request) { |
|
168 |
throw '<?=gettext("Both getURL and XMLHttpRequest are undefined"); ?>'; |
|
169 |
} |
|
170 |
|
|
171 |
http_request.onreadystatechange = function() { |
|
172 |
if (http_request.readyState == 4) { |
|
173 |
callback( { success : true, |
|
174 |
content : http_request.responseText, |
|
175 |
contentType : http_request.getResponseHeader("Content-Type") } ); |
|
176 |
} |
|
177 |
} |
|
178 |
http_request.open('GET', url, true); |
|
179 |
http_request.send(null); |
|
180 |
} |
|
177 | 181 |
} |
178 | 182 |
|
179 | 183 |
var SVGDoc = null; |
... | ... | |
190 | 194 |
var scale_type = '<?=$scale_type?>'; |
191 | 195 |
|
192 | 196 |
function init(evt) { |
193 |
SVGDoc = evt.target.ownerDocument;
|
|
194 |
SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
|
|
195 |
SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
|
|
197 |
SVGDoc = evt.target.ownerDocument;
|
|
198 |
SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
|
|
199 |
SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
|
|
196 | 200 |
|
197 |
fetch_data();
|
|
201 |
fetch_data();
|
|
198 | 202 |
} |
199 | 203 |
|
200 |
function switch_unit(event) |
|
201 |
{ |
|
202 |
SVGDoc.getElementById('switch_unit').firstChild.data = '<?=gettext("Switch to"); ?> ' + unit + '/s'; |
|
203 |
unit = (unit == 'bits') ? 'bytes' : 'bits'; |
|
204 |
function switch_unit(event) { |
|
205 |
SVGDoc.getElementById('switch_unit').firstChild.data = '<?=gettext("Switch to"); ?> ' + unit + '/s'; |
|
206 |
unit = (unit == 'bits') ? 'bytes' : 'bits'; |
|
204 | 207 |
} |
205 | 208 |
|
206 |
function switch_scale(event) |
|
207 |
{ |
|
208 |
scale_type = (scale_type == 'up') ? '<?=gettext("follow"); ?>' : '<?=gettext("up"); ?>'; |
|
209 |
SVGDoc.getElementById('switch_scale').firstChild.data = 'AutoScale (' + scale_type + ')'; |
|
209 |
function switch_scale(event) { |
|
210 |
scale_type = (scale_type == 'up') ? '<?=gettext("follow"); ?>' : '<?=gettext("up"); ?>'; |
|
211 |
SVGDoc.getElementById('switch_scale').firstChild.data = 'AutoScale (' + scale_type + ')'; |
|
210 | 212 |
} |
211 | 213 |
|
212 | 214 |
function fetch_data() { |
213 |
getURL('<?=$fetch_link?>', plot_data);
|
|
215 |
getURL('<?=$fetch_link?>', plot_data);
|
|
214 | 216 |
} |
215 | 217 |
|
216 | 218 |
function plot_data(obj) { |
217 |
// Show datetimelegend |
|
218 |
var now = new Date(); |
|
219 |
var time = LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds()); |
|
220 |
SVGDoc.getElementById('time').firstChild.data = time; |
|
221 |
var date = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear(); |
|
222 |
SVGDoc.getElementById('date').firstChild.data = date; |
|
223 |
|
|
224 |
if (!obj.success) |
|
225 |
return handle_error(); // getURL failed to get data |
|
226 |
|
|
227 |
var t = obj.content.split("|"); |
|
228 |
var ugmt = parseFloat(t[0]); // ugmt is an unixtimestamp style |
|
229 |
var ifin = parseInt(t[1], 10); // number of bytes received by the interface |
|
230 |
var ifout = parseInt(t[2], 10); // number of bytes sent by the interface |
|
231 |
var scale; |
|
232 |
|
|
233 |
if (!isNumber(ifin) || !isNumber(ifout)) |
|
234 |
return handle_error(); |
|
235 |
|
|
236 |
var diff_ugmt = ugmt - last_ugmt; |
|
237 |
var diff_ifin = ifin - last_ifin; |
|
238 |
var diff_ifout = ifout - last_ifout; |
|
239 |
|
|
240 |
if (diff_ugmt == 0) |
|
241 |
diff_ugmt = 1; /* avoid division by zero */ |
|
242 |
|
|
243 |
last_ugmt = ugmt; |
|
244 |
last_ifin = ifin; |
|
245 |
last_ifout = ifout; |
|
246 |
var graphTimerId = 0; |
|
247 |
switch (plot_in.length) { |
|
248 |
case 0: |
|
249 |
SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible'); |
|
250 |
plot_in[0] = diff_ifin / diff_ugmt; |
|
251 |
plot_out[0] = diff_ifout / diff_ugmt; |
|
252 |
setTimeout('fetch_data()',<?=1000*($time_interval + $init_delay)?>); |
|
253 |
return; |
|
254 |
case 1: |
|
255 |
SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden'); |
|
256 |
break; |
|
257 |
case max_num_points: |
|
258 |
// shift plot to left if the maximum number of plot points has been reached |
|
259 |
var i = 0; |
|
260 |
while (i < max_num_points) { |
|
261 |
plot_in[i] = plot_in[i+1]; |
|
262 |
plot_out[i] = plot_out[++i]; |
|
219 |
// Show datetimelegend |
|
220 |
var now = new Date(); |
|
221 |
var time = LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds()); |
|
222 |
SVGDoc.getElementById('time').firstChild.data = time; |
|
223 |
var date = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear(); |
|
224 |
SVGDoc.getElementById('date').firstChild.data = date; |
|
225 |
|
|
226 |
if (!obj.success) { |
|
227 |
return handle_error(); // getURL failed to get data |
|
228 |
} |
|
229 |
|
|
230 |
var t = obj.content.split("|"); |
|
231 |
var ugmt = parseFloat(t[0]); // ugmt is an unixtimestamp style |
|
232 |
var ifin = parseInt(t[1], 10); // number of bytes received by the interface |
|
233 |
var ifout = parseInt(t[2], 10); // number of bytes sent by the interface |
|
234 |
var scale; |
|
235 |
|
|
236 |
if (!isNumber(ifin) || !isNumber(ifout)) { |
|
237 |
return handle_error(); |
|
238 |
} |
|
239 |
|
|
240 |
var diff_ugmt = ugmt - last_ugmt; |
|
241 |
var diff_ifin = ifin - last_ifin; |
|
242 |
var diff_ifout = ifout - last_ifout; |
|
243 |
|
|
244 |
if (diff_ugmt == 0) { |
|
245 |
diff_ugmt = 1; /* avoid division by zero */ |
|
246 |
} |
|
247 |
|
|
248 |
last_ugmt = ugmt; |
|
249 |
last_ifin = ifin; |
|
250 |
last_ifout = ifout; |
|
251 |
var graphTimerId = 0; |
|
252 |
switch (plot_in.length) { |
|
253 |
case 0: |
|
254 |
SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible'); |
|
255 |
plot_in[0] = diff_ifin / diff_ugmt; |
|
256 |
plot_out[0] = diff_ifout / diff_ugmt; |
|
257 |
setTimeout('fetch_data()', <?=1000*($time_interval + $init_delay)?>); |
|
258 |
return; |
|
259 |
case 1: |
|
260 |
SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden'); |
|
261 |
break; |
|
262 |
case max_num_points: |
|
263 |
// shift plot to left if the maximum number of plot points has been reached |
|
264 |
var i = 0; |
|
265 |
while (i < max_num_points) { |
|
266 |
plot_in[i] = plot_in[i+1]; |
|
267 |
plot_out[i] = plot_out[++i]; |
|
268 |
} |
|
269 |
plot_in.length--; |
|
270 |
plot_out.length--; |
|
271 |
} |
|
272 |
|
|
273 |
plot_in[plot_in.length] = diff_ifin / diff_ugmt; |
|
274 |
plot_out[plot_out.length]= diff_ifout / diff_ugmt; |
|
275 |
var index_plot = plot_in.length - 1; |
|
276 |
|
|
277 |
SVGDoc.getElementById('graph_in_txt').firstChild.data = formatSpeed(plot_in[index_plot], unit); |
|
278 |
SVGDoc.getElementById('graph_out_txt').firstChild.data = formatSpeed(plot_out[index_plot], unit); |
|
279 |
|
|
280 |
/* determine peak for sensible scaling */ |
|
281 |
if (scale_type == 'up') { |
|
282 |
if (plot_in[index_plot] > max) { |
|
283 |
max = plot_in[index_plot]; |
|
284 |
} |
|
285 |
if (plot_out[index_plot] > max) { |
|
286 |
max = plot_out[index_plot]; |
|
287 |
} |
|
288 |
} else if (scale_type == 'follow') { |
|
289 |
i = 0; |
|
290 |
max = 0; |
|
291 |
while (i < plot_in.length) { |
|
292 |
if (plot_in[i] > max) { |
|
293 |
max = plot_in[i]; |
|
294 |
} |
|
295 |
if (plot_out[i] > max) { |
|
296 |
max = plot_out[i]; |
|
297 |
} |
|
298 |
i++; |
|
299 |
} |
|
300 |
} |
|
301 |
|
|
302 |
var rmax; // max, rounded up |
|
303 |
|
|
304 |
if (unit == 'bits') { |
|
305 |
/* round up max, such that |
|
306 |
100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */ |
|
307 |
rmax = 12500; |
|
308 |
i = 0; |
|
309 |
while (max > rmax) { |
|
310 |
i++; |
|
311 |
if (i && (i % 4 == 0)) { |
|
312 |
rmax *= 1.25; |
|
313 |
} else { |
|
314 |
rmax *= 2; |
|
315 |
} |
|
316 |
} |
|
317 |
} else { |
|
318 |
/* round up max, such that |
|
319 |
10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */ |
|
320 |
rmax = 10240; |
|
321 |
i = 0; |
|
322 |
while (max > rmax) { |
|
323 |
i++; |
|
324 |
if (i && (i % 4 == 0)) { |
|
325 |
rmax *= 1.25; |
|
326 |
} else { |
|
327 |
rmax *= 2; |
|
328 |
} |
|
329 |
|
|
330 |
if (i == 8) { |
|
331 |
rmax *= 1.024; |
|
332 |
} |
|
263 | 333 |
} |
264 |
plot_in.length--; |
|
265 |
plot_out.length--; |
|
266 |
} |
|
267 |
|
|
268 |
plot_in[plot_in.length] = diff_ifin / diff_ugmt; |
|
269 |
plot_out[plot_out.length]= diff_ifout / diff_ugmt; |
|
270 |
var index_plot = plot_in.length - 1; |
|
271 |
|
|
272 |
SVGDoc.getElementById('graph_in_txt').firstChild.data = formatSpeed(plot_in[index_plot], unit); |
|
273 |
SVGDoc.getElementById('graph_out_txt').firstChild.data = formatSpeed(plot_out[index_plot], unit); |
|
274 |
|
|
275 |
/* determine peak for sensible scaling */ |
|
276 |
if (scale_type == 'up') { |
|
277 |
if (plot_in[index_plot] > max) |
|
278 |
max = plot_in[index_plot]; |
|
279 |
if (plot_out[index_plot] > max) |
|
280 |
max = plot_out[index_plot]; |
|
281 |
} else if (scale_type == 'follow') { |
|
282 |
i = 0; |
|
283 |
max = 0; |
|
284 |
while (i < plot_in.length) { |
|
285 |
if (plot_in[i] > max) |
|
286 |
max = plot_in[i]; |
|
287 |
if (plot_out[i] > max) |
|
288 |
max = plot_out[i]; |
|
289 |
i++; |
|
290 |
} |
|
291 |
} |
|
292 |
|
|
293 |
var rmax; // max, rounded up |
|
294 |
|
|
295 |
if (unit == 'bits') { |
|
296 |
/* round up max, such that |
|
297 |
100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */ |
|
298 |
rmax = 12500; |
|
299 |
i = 0; |
|
300 |
while (max > rmax) { |
|
301 |
i++; |
|
302 |
if (i && (i % 4 == 0)) |
|
303 |
rmax *= 1.25; |
|
304 |
else |
|
305 |
rmax *= 2; |
|
306 |
} |
|
307 |
} else { |
|
308 |
/* round up max, such that |
|
309 |
10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */ |
|
310 |
rmax = 10240; |
|
311 |
i = 0; |
|
312 |
while (max > rmax) { |
|
313 |
i++; |
|
314 |
if (i && (i % 4 == 0)) |
|
315 |
rmax *= 1.25; |
|
316 |
else |
|
317 |
rmax *= 2; |
|
318 |
|
|
319 |
if (i == 8) |
|
320 |
rmax *= 1.024; |
|
321 |
} |
|
322 |
} |
|
323 |
|
|
324 |
scale = <?=$height?> / rmax; |
|
325 |
|
|
326 |
/* change labels accordingly */ |
|
327 |
SVGDoc.getElementById('grid_txt1').firstChild.data = formatSpeed(3*rmax/4,unit); |
|
328 |
SVGDoc.getElementById('grid_txt2').firstChild.data = formatSpeed(2*rmax/4,unit); |
|
329 |
SVGDoc.getElementById('grid_txt3').firstChild.data = formatSpeed(rmax/4,unit); |
|
330 |
|
|
331 |
var path_in = "M 0 " + (<?=$height?> - (plot_in[0] * scale)); |
|
332 |
var path_out = "M 0 " + (<?=$height?> - (plot_out[0] * scale)); |
|
333 |
for (i = 1; i < plot_in.length; i++) |
|
334 |
{ |
|
335 |
var x = step * i; |
|
336 |
var y_in = <?=$height?> - (plot_in[i] * scale); |
|
337 |
var y_out = <?=$height?> - (plot_out[i] * scale); |
|
338 |
path_in += " L" + x + " " + y_in; |
|
339 |
path_out += " L" + x + " " + y_out; |
|
340 |
} |
|
341 |
|
|
342 |
SVGDoc.getElementById('error').setAttributeNS(null, 'visibility', 'hidden'); |
|
343 |
SVGDoc.getElementById('graph_in').setAttributeNS(null, 'd', path_in); |
|
344 |
SVGDoc.getElementById('graph_out').setAttributeNS(null, 'd', path_out); |
|
345 |
|
|
346 |
setTimeout('fetch_data()',<?=1000*$time_interval?>); |
|
334 |
} |
|
335 |
|
|
336 |
scale = <?=$height?> / rmax; |
|
337 |
|
|
338 |
/* change labels accordingly */ |
|
339 |
SVGDoc.getElementById('grid_txt1').firstChild.data = formatSpeed(3*rmax/4, unit); |
|
340 |
SVGDoc.getElementById('grid_txt2').firstChild.data = formatSpeed(2*rmax/4, unit); |
|
341 |
SVGDoc.getElementById('grid_txt3').firstChild.data = formatSpeed(rmax/4, unit); |
|
342 |
|
|
343 |
var path_in = "M 0 " + (<?=$height?> - (plot_in[0] * scale)); |
|
344 |
var path_out = "M 0 " + (<?=$height?> - (plot_out[0] * scale)); |
|
345 |
for (i = 1; i < plot_in.length; i++) { |
|
346 |
var x = step * i; |
|
347 |
var y_in = <?=$height?> - (plot_in[i] * scale); |
|
348 |
var y_out = <?=$height?> - (plot_out[i] * scale); |
|
349 |
path_in += " L" + x + " " + y_in; |
|
350 |
path_out += " L" + x + " " + y_out; |
|
351 |
} |
|
352 |
|
|
353 |
SVGDoc.getElementById('error').setAttributeNS(null, 'visibility', 'hidden'); |
|
354 |
SVGDoc.getElementById('graph_in').setAttributeNS(null, 'd', path_in); |
|
355 |
SVGDoc.getElementById('graph_out').setAttributeNS(null, 'd', path_out); |
|
356 |
|
|
357 |
setTimeout('fetch_data()', <?=1000*$time_interval?>); |
|
347 | 358 |
} |
348 | 359 |
|
349 | 360 |
function handle_error() { |
350 |
SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
|
|
351 |
setTimeout('fetch_data()',<?=1000*$time_interval?>);
|
|
361 |
SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
|
|
362 |
setTimeout('fetch_data()', <?=1000*$time_interval?>);
|
|
352 | 363 |
} |
353 | 364 |
|
354 | 365 |
function isNumber(a) { |
355 |
return typeof a == 'number' && isFinite(a);
|
|
366 |
return typeof a == 'number' && isFinite(a);
|
|
356 | 367 |
} |
357 | 368 |
|
358 | 369 |
function formatSpeed(speed, unit) { |
359 |
if (unit == 'bits') |
|
360 |
return formatSpeedBits(speed); |
|
361 |
if (unit == 'bytes') |
|
362 |
return formatSpeedBytes(speed); |
|
370 |
if (unit == 'bits') { |
|
371 |
return formatSpeedBits(speed); |
|
372 |
} |
|
373 |
if (unit == 'bytes') { |
|
374 |
return formatSpeedBytes(speed); |
|
375 |
} |
|
363 | 376 |
} |
364 | 377 |
|
365 | 378 |
function formatSpeedBits(speed) { |
366 |
// format speed in bits/sec, input: bytes/sec |
|
367 |
if (speed < 125000) |
|
368 |
return Math.round(speed / 125) + " <?=gettext("Kbps"); ?>"; |
|
369 |
if (speed < 125000000) |
|
370 |
return Math.round(speed / 1250)/100 + " <?=gettext("Mbps"); ?>"; |
|
371 |
// else |
|
372 |
return Math.round(speed / 1250000)/100 + " <?=gettext("Gbps"); ?>"; /* wow! */ |
|
379 |
// format speed in bits/sec, input: bytes/sec |
|
380 |
if (speed < 125000) { |
|
381 |
return Math.round(speed / 125) + " <?=gettext("Kbps"); ?>"; |
|
382 |
} |
|
383 |
if (speed < 125000000) { |
|
384 |
return Math.round(speed / 1250)/100 + " <?=gettext("Mbps"); ?>"; |
|
385 |
} |
|
386 |
// else |
|
387 |
return Math.round(speed / 1250000)/100 + " <?=gettext("Gbps"); ?>"; /* wow! */ |
|
373 | 388 |
} |
374 | 389 |
|
375 | 390 |
function formatSpeedBytes(speed) { |
376 |
// format speed in bytes/sec, input: bytes/sec |
|
377 |
if (speed < 1048576) |
|
378 |
return Math.round(speed / 10.24)/100 + " <?=gettext("KB/s"); ?>"; |
|
379 |
if (speed < 1073741824) |
|
380 |
return Math.round(speed / 10485.76)/100 + " <?=gettext("MB/s"); ?>"; |
|
381 |
// else |
|
382 |
return Math.round(speed / 10737418.24)/100 + " <?=gettext("GB/s"); ?>"; /* wow! */ |
|
391 |
// format speed in bytes/sec, input: bytes/sec |
|
392 |
if (speed < 1048576) { |
|
393 |
return Math.round(speed / 10.24)/100 + " <?=gettext("KB/s"); ?>"; |
|
394 |
} |
|
395 |
if (speed < 1073741824) { |
|
396 |
return Math.round(speed / 10485.76)/100 + " <?=gettext("MB/s"); ?>"; |
|
397 |
} |
|
398 |
// else |
|
399 |
return Math.round(speed / 10737418.24)/100 + " <?=gettext("GB/s"); ?>"; /* wow! */ |
|
383 | 400 |
} |
384 | 401 |
|
385 | 402 |
function LZ(x) { |
386 |
return (x < 0 || x > 9 ? "" : "0") + x;
|
|
403 |
return (x < 0 || x > 9 ? "" : "0") + x;
|
|
387 | 404 |
} |
388 | 405 |
|
389 | 406 |
]]> |
390 |
</script>
|
|
407 |
</script>
|
|
391 | 408 |
</svg> |
Also available in: Unified diff
Code spacing
and other random stuff I noticed.
I think this finishes messing with code style. The codebase should match
the developer style guide closely enough that 99.9% of changes will not
feel the need to also massage the formatting.