]> git.proxmox.com Git - proxmox-widget-toolkit.git/commitdiff
add RRDChart class
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 29 Aug 2017 06:43:50 +0000 (08:43 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 29 Aug 2017 06:43:50 +0000 (08:43 +0200)
Makefile
panel/RRDChart.js [new file with mode: 0644]

index 46aea79822a0045949edbe87824733d2b814e16a..c9fc6df35eb446e3e13f43285f84c97a093a176c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,7 @@ JSSRC=                                        \
        grid/PendingObjectGrid.js       \
        panel/InputPanel.js             \
        panel/LogView.js                \
+       panel/RRDChart.js               \
        window/Edit.js                  \
        window/PasswordEdit.js          \
        window/TaskViewer.js            \
diff --git a/panel/RRDChart.js b/panel/RRDChart.js
new file mode 100644 (file)
index 0000000..83e3fcf
--- /dev/null
@@ -0,0 +1,173 @@
+Ext.define('Proxmox.widget.RRDChart', {
+    extend: 'Ext.chart.CartesianChart',
+    alias: 'widget.proxmoxRRDChart',
+
+    unit: undefined, // bytes, bytespersecond, percent
+    
+    controller: {
+       xclass: 'Ext.app.ViewController',
+
+       convertToUnits: function(value) {
+           var units = ['', 'k','M','G','T', 'P'];
+           var si = 0;
+           while(value >= 1000  && si < (units.length -1)){
+               value = value / 1000;
+               si++;
+           }
+
+           // javascript floating point weirdness
+           value = Ext.Number.correctFloat(value);
+           
+           // limit to 2 decimal points
+           value = Ext.util.Format.number(value, "0.##");
+           
+           return value.toString() + " " + units[si];
+       },
+
+       leftAxisRenderer: function(axis, label, layoutContext) {
+           var me = this;
+
+           return me.convertToUnits(label);
+       },
+
+       onSeriesTooltipRender: function(tooltip, record, item) {
+           var me = this.getView();
+           
+           var suffix = '';
+           
+           if (me.unit === 'percent') {
+               suffix = '%';
+           } else if (me.unit === 'bytes') {
+               suffix = 'B';
+           } else if (me.unit === 'bytespersecond') {
+               suffix = 'B/s';
+           }
+           
+           var prefix = item.field;
+           if (me.fieldTitles && me.fieldTitles[me.fields.indexOf(item.field)]) {
+               prefix = me.fieldTitles[me.fields.indexOf(item.field)];
+           }
+            tooltip.setHtml(prefix + ': ' + this.convertToUnits(record.get(item.field)) + suffix +
+                           '<br>' + new Date(record.get('time')));
+       },
+
+       onAfterAnimation: function(chart, eopts) {
+           // if the undobuton is disabled,
+           // disable our tool
+
+           var ourUndoZoomButton = chart.tools[0];
+           var undoButton = chart.interactions[0].getUndoButton();
+           ourUndoZoomButton.setDisabled(undoButton.isDisabled());
+       }
+    },
+    
+    width: 770,
+    height: 300,
+    animation: false,
+    interactions: [{
+       type: 'crosszoom'
+    }],
+    axes: [{
+       type: 'numeric',
+       position: 'left',
+       grid: true,
+       renderer: 'leftAxisRenderer',
+       //renderer: function(axis, label) { return label; },
+       minimum: 0
+    }, {
+       type: 'time',
+       position: 'bottom',
+       grid: true,
+       fields: ['time']
+    }],
+    legend: {
+       docked: 'bottom'
+    },
+    listeners: {
+       animationend: 'onAfterAnimation'
+    },
+
+
+    initComponent: function() {
+       var me = this;
+
+       if (!me.store) {
+           throw "cannot work without store";
+       }
+
+       if (!me.fields) {
+           throw "cannot work without fields";
+       }
+
+       me.callParent();
+
+       // add correct label for left axis
+       var axisTitle = "";
+       if (me.unit === 'percent') {
+           axisTitle = "%";
+       } else if (me.unit === 'bytes') {
+           axisTitle = "Bytes";
+       } else if (me.unit === 'bytespersecond') {
+           axisTitle = "Bytes/s";
+       }
+
+       me.axes[0].setTitle(axisTitle);
+
+       me.addTool([{
+           type: 'minus',
+           disabled: true,
+           tooltip: gettext('Undo Zoom'),
+           handler: function(){
+               var undoButton = me.interactions[0].getUndoButton();
+               if (undoButton.handler) {
+                   undoButton.handler();
+               }
+           }
+       },{
+           type: 'restore',
+           tooltip: gettext('Toggle Legend'),
+           handler: function(){
+               me.legend.setVisible(!me.legend.isVisible());
+           }
+       }]);
+       // add a series for each field we get
+       me.fields.forEach(function(item, index){
+           var title = item;
+           if (me.fieldTitles && me.fieldTitles[index]) {
+               title = me.fieldTitles[index];
+           }
+           me.addSeries({
+               type: 'line',
+               xField: 'time',
+               yField: item,
+               title: title,
+               fill: true,
+               style: {
+                   lineWidth: 1.5,
+                   opacity: 0.60
+               },
+               marker: {
+                   opacity: 0,
+                   scaling: 0.01,
+                   fx: {
+                       duration: 200,
+                       easing: 'easeOut'
+                   }
+               },
+               highlightCfg: {
+                   opacity: 1,
+                   scaling: 1.5
+               },
+               tooltip: {
+                   trackMouse: true,
+                   renderer: 'onSeriesTooltipRender'
+               }
+           });
+       });
+
+       // enable animation after the store is loaded
+       me.store.onAfter('load', function() {
+           me.setAnimation(true);
+       }, this, {single: true});
+    }
+});