2abe78dac74cd091c83406543d0aba16dbf15842
4 'require statistics.rrdtool as rrdtool';
10 return L
.view
.extend({
12 return rrdtool
.load();
15 updatePluginTab: function(host
, span
, time
, ev
) {
16 var container
= ev
.target
,
17 plugin
= ev
.detail
.tab
,
18 plugin_instances
= rrdtool
.pluginInstances(host
.value
, plugin
);
20 activePlugin
= plugin
;
22 L
.dom
.content(container
, [
24 E('em', { 'class': 'spinning' }, [ _('Loading data…') ])
28 Promise
.all(plugin_instances
.map(function(instance
) {
29 return rrdtool
.render(plugin
, instance
, false, host
.value
, span
.value
, Math
.max(200, container
.offsetWidth
- 100));
30 })).then(function(blobs
) {
31 var multiple
= blobs
.length
> 1;
33 L
.dom
.content(container
, E('div', {}, blobs
.map(function(blobs
, i
) {
34 var plugin_instance
= plugin_instances
[i
];
38 'data-tab': multiple
? i
: null,
39 'data-tab-title': multiple
? '%s: %s'.format(rrdtool
.pluginTitle(plugin
), plugin_instances
[i
]) : null,
40 'data-plugin': plugin
,
41 'data-plugin-instance': plugin_instances
[i
],
42 'cbi-tab-active': function(ev
) { activeInstance
= ev
.target
.getAttribute('data-plugin-instance') }
43 }, blobs
.map(function(blob
) {
45 'src': URL
.createObjectURL(new Blob([blob
], { type
: 'image/png' }))
51 ui
.tabs
.initTabGroup(container
.lastElementChild
.childNodes
);
53 activeInstance
= plugin_instances
[0];
57 updateGraphs: function(host
, span
, time
, container
, ev
) {
58 var plugin_names
= rrdtool
.pluginNames(host
.value
);
60 container
.querySelectorAll('img').forEach(function(img
) {
61 URL
.revokeObjectURL(img
.src
);
64 L
.dom
.content(container
, null);
66 if (container
.hasAttribute('data-initialized')) {
67 container
.removeAttribute('data-initialized');
68 container
.parentNode
.removeChild(container
.previousElementSibling
);
71 for (var i
= 0; i
< plugin_names
.length
; i
++) {
72 if (!rrdtool
.hasDefinition(plugin_names
[i
]))
75 container
.appendChild(E('div', {
76 'data-tab': plugin_names
[i
],
77 'data-tab-title': rrdtool
.pluginTitle(plugin_names
[i
]),
78 'cbi-tab-active': L
.bind(this.updatePluginTab
, this, host
, span
, time
)
81 E('em', { 'class': 'spinning' }, [ _('Loading data…') ])
86 ui
.tabs
.initTabGroup(container
.childNodes
);
89 refreshGraphs: function(host
, span
, time
, container
) {
90 var div
= document
.querySelector('[data-plugin="%s"][data-plugin-instance="%s"]'.format(activePlugin
, activeInstance
|| ''));
92 return rrdtool
.render(activePlugin
, activeInstance
|| '', false, host
.value
, span
.value
, Math
.max(200, container
.offsetWidth
- 100)).then(function(blobs
) {
93 return Promise
.all(blobs
.map(function(blob
) {
94 return new Promise(function(resolveFn
, rejectFn
) {
95 var img
= E('img', { 'src': URL
.createObjectURL(new Blob([blob
], { type
: 'image/png' })) });
96 img
.onload = function(ev
) { resolveFn(img
) };
97 img
.onerror = function(ev
) { resolveFn(img
) };
99 })).then(function(imgs
) {
100 while (div
.childNodes
.length
> imgs
.length
)
101 div
.removeChild(div
.lastElementChild
);
103 for (var i
= 0; i
< imgs
.length
; i
++) {
104 if (i
< div
.childNodes
.length
) {
105 URL
.revokeObjectURL(div
.childNodes
[i
].src
);
106 div
.childNodes
[i
].src
= imgs
[i
].src
;
109 div
.appendChild(E('img', { 'src': imgs
[i
].src
}));
116 togglePolling: function(host
, span
, time
, container
, ev
) {
117 var btn
= ev
.currentTarget
;
120 L
.Poll
.remove(pollFn
);
124 if (time
.value
!= '0') {
125 pollFn
= L
.bind(this.refreshGraphs
, this, host
, span
, time
, container
);
126 L
.Poll
.add(pollFn
, +time
.value
);
131 var hosts
= rrdtool
.hostInstances();
132 return hosts
.length
? this.renderGraphs() : this.renderNoData();
135 renderNoData: function() {
136 ui
.showModal(_('No RRD data found'), [
137 E('p', {}, _('There is no RRD data available yet to render graphs.')),
138 E('p', {}, _('You need to configure <em>collectd</em> to gather data into <em>.rrd</em> files.')),
139 E('div', { 'class': 'right' }, [
141 'class': 'cbi-button',
142 'click': function(ev
) { location
.href
= 'collectd' }
143 }, [ _('Setup collectd') ])
148 renderGraphs: function() {
149 var hostSel
= E('select', { 'style': 'max-width:170px', 'data-name': 'host' }, rrdtool
.hostInstances().map(function(host
) {
151 'selected': (rrdtool
.opts
.host
== host
) ? 'selected' : null
155 var spanSel
= E('select', { 'style': 'max-width:170px', 'data-name': 'timespan' }, L
.toArray(uci
.get('luci_statistics', 'collectd_rrdtool', 'RRATimespans')).map(function(span
) {
157 'selected': (rrdtool
.opts
.timespan
== span
) ? 'selected' : null
161 var timeSel
= E('select', { 'style': 'max-width:170px', 'data-name': 'refresh' }, [
162 E('option', { 'value': 0 }, [ _('Do not refresh') ]),
163 E('option', { 'value': 5 }, [ _('Every 5 seconds') ]),
164 E('option', { 'value': 30 }, [ _('Every 30 seconds') ]),
165 E('option', { 'value': 60 }, [ _('Every minute') ])
168 var graphDiv
= E('div', { 'data-name': 'graphs' });
171 E('h2', {}, [ _('Statistics') ]),
176 'class': 'cbi-button cbi-button-apply',
177 'click': ui
.createHandlerFn(this, 'updateGraphs', hostSel
, spanSel
, timeSel
, graphDiv
, )
178 }, [ _('Display Host »') ]),
182 'class': 'cbi-button cbi-button-apply',
183 'click': ui
.createHandlerFn(this, 'updateGraphs', hostSel
, spanSel
, timeSel
, graphDiv
)
184 }, [ _('Display timespan »') ]),
188 'class': 'cbi-button cbi-button-apply',
189 'click': ui
.createHandlerFn(this, 'togglePolling', hostSel
, spanSel
, timeSel
, graphDiv
)
190 }, [ _('Apply interval »') ])
197 requestAnimationFrame(L
.bind(this.updateGraphs
, this, hostSel
, spanSel
, timeSel
, graphDiv
));
203 handleSaveApply
: null,