]> git.proxmox.com Git - pve-manager.git/commitdiff
add runningchart widget
authorDominik Csapak <d.csapak@proxmox.com>
Tue, 22 Nov 2016 11:32:12 +0000 (12:32 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 22 Nov 2016 15:37:24 +0000 (16:37 +0100)
this adds a new component 'runningchart', which is a simple linegraph

you define a timeFrame (default 5*60 seconds), and you regularly add
datapoints to it, and the graph shows the last timeFrame seconds of it

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
www/manager6/Makefile
www/manager6/panel/RunningChart.js [new file with mode: 0644]

index 84e57a188b1cdf8f36f387fced6dc5b9e1929b4f..0c58f015e86183e881d36a2bd507e3026e7eb15b 100644 (file)
@@ -75,6 +75,7 @@ JSSRC=                                                        \
        panel/GuestStatusView.js                        \
        panel/RRDView.js                                \
        panel/RRDChart.js                               \
+       panel/RunningChart.js                           \
        panel/InfoWidget.js                             \
        panel/TemplateStatusView.js                     \
        panel/InputPanel.js                             \
diff --git a/www/manager6/panel/RunningChart.js b/www/manager6/panel/RunningChart.js
new file mode 100644 (file)
index 0000000..37473fc
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * 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: '<h3>{title}:</h3>'
+       },
+       {
+           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: {
+               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) {
+                       var me = this.getChart();
+                       var date = new Date(record.data.time);
+                       var value = me.up().renderer(record.data.val);
+                       tooltip.setHtml(
+                           me.up().title + ': ' + value + '<br />' +
+                           Ext.Date.format(date, 'H:i:s')
+                       );
+                   }
+               },
+               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) {
+       var me = this.chart;
+       var panel = me.up();
+       var now = new Date();
+       var begin = new Date(now.getTime() - (1000*panel.timeFrame));
+
+       me.store.add({
+           time: time || now.getTime(),
+           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 (me.store.count() > panel.timeFrame * 20) {
+           var oldData = me.store.getData().createFiltered(function(item) {
+               return item.data.time < begin.getTime();
+           });
+
+           me.store.remove(oldData.getRange());
+       }
+
+       me.timeaxis.setMinimum(begin.getTime());
+       me.timeaxis.setMaximum(now.getTime());
+       me.valuesprite.setText(panel.renderer(value || 0).toString());
+       me.valuesprite.setAttributes({
+           x: me.getWidth() - 15,
+           y: me.getHeight()/2
+       }, true);
+       me.redraw();
+    },
+
+    setTitle: function(title) {
+       this.title = title;
+       var me = this.getComponent('title');
+       me.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
+           });
+       }
+    }
+});