/* * This is a running chart widget you add time datapoints to it, and we only * show the last x of it used for ceph performance charts */ Ext.define('PVE.widget.RunningChart', { extend: 'Ext.container.Container', alias: 'widget.pveRunningChart', layout: { type: 'hbox', align: 'center', }, items: [ { width: 80, xtype: 'box', itemId: 'title', data: { title: '', }, tpl: '

{title}:

', }, { flex: 1, xtype: 'cartesian', height: '100%', itemId: 'chart', border: false, axes: [ { type: 'numeric', position: 'left', hidden: true, minimum: 0, }, { type: 'numeric', position: 'bottom', hidden: true, }, ], store: { trackRemoved: false, data: {}, }, sprites: [{ id: 'valueSprite', type: 'text', text: '0 B/s', textAlign: 'end', textBaseline: 'middle', fontSize: 14, }], series: [{ type: 'line', xField: 'time', yField: 'val', fill: 'true', colors: ['#cfcfcf'], tooltip: { trackMouse: true, renderer: function(tooltip, record, ctx) { if (!record || !record.data) return; const view = this.getChart(); const date = new Date(record.data.time); const value = view.up().renderer(record.data.val); const line1 = `${view.up().title}: ${value}`; const line2 = Ext.Date.format(date, 'H:i:s'); tooltip.setHtml(`${line1}
${line2}`); }, }, style: { lineWidth: 1.5, opacity: 0.60, }, marker: { opacity: 0, scaling: 0.01, fx: { duration: 200, easing: 'easeOut', }, }, highlightCfg: { opacity: 1, scaling: 1.5, }, }], }, ], // the renderer for the tooltip and last value, default just the value renderer: Ext.identityFn, // show the last x seconds default is 5 minutes timeFrame: 5*60, addDataPoint: function(value, time) { let view = this.chart; let panel = view.up(); let now = new Date().getTime(); let begin = new Date(now - 1000 * panel.timeFrame).getTime(); view.store.add({ time: time || now, val: value || 0, }); // delete all old records when we have 20 times more datapoints // than seconds in our timeframe (so even a subsecond graph does // not trigger this often) // // records in the store do not take much space, but like this, // we prevent a memory leak when someone has the site open for a long time // with minimal graphical glitches if (view.store.count() > panel.timeFrame * 20) { var oldData = view.store.getData().createFiltered(function(item) { return item.data.time < begin; }); view.store.remove(oldData.getRange()); } view.timeaxis.setMinimum(begin); view.timeaxis.setMaximum(now); view.valuesprite.setText(panel.renderer(value || 0).toString()); view.valuesprite.setAttributes({ x: view.getWidth() - 15, y: view.getHeight()/2, }, true); view.redraw(); }, setTitle: function(title) { this.title = title; let titlebox = this.getComponent('title'); titlebox.update({ title: title }); }, initComponent: function() { var me = this; me.callParent(); if (me.title) { me.getComponent('title').update({ title: me.title }); } me.chart = me.getComponent('chart'); me.chart.timeaxis = me.chart.getAxes()[1]; me.chart.valuesprite = me.chart.getSurface('chart').get('valueSprite'); if (me.color) { me.chart.series[0].setStyle({ fill: me.color, stroke: me.color, }); } }, });