]>
Commit | Line | Data |
---|---|---|
4226b8fb DC |
1 | /* |
2 | * This is a running chart widget | |
3 | * you add time datapoints to it, | |
4 | * and we only show the last x of it | |
5 | * used for ceph performance charts | |
6 | */ | |
7 | Ext.define('PVE.widget.RunningChart', { | |
8 | extend: 'Ext.container.Container', | |
9 | alias: 'widget.pveRunningChart', | |
10 | ||
11 | layout: { | |
12 | type: 'hbox', | |
13 | align: 'center' | |
14 | }, | |
15 | items: [ | |
16 | { | |
17 | width: 80, | |
18 | xtype: 'box', | |
19 | itemId: 'title', | |
20 | data: { | |
21 | title: '' | |
22 | }, | |
23 | tpl: '<h3>{title}:</h3>' | |
24 | }, | |
25 | { | |
26 | flex: 1, | |
27 | xtype: 'cartesian', | |
28 | height: '100%', | |
29 | itemId: 'chart', | |
30 | border: false, | |
31 | axes: [ | |
32 | { | |
33 | type: 'numeric', | |
34 | position: 'left', | |
35 | hidden: true, | |
36 | minimum: 0 | |
37 | }, | |
38 | { | |
39 | type: 'numeric', | |
40 | position: 'bottom', | |
41 | hidden: true | |
42 | } | |
43 | ], | |
44 | ||
45 | store: { | |
46 | data: {} | |
47 | }, | |
48 | ||
49 | sprites: [{ | |
50 | id: 'valueSprite', | |
51 | type: 'text', | |
52 | text: '0 B/s', | |
53 | textAlign: 'end', | |
54 | textBaseline: 'middle', | |
55 | fontSize: 14 | |
56 | }], | |
57 | ||
58 | series: [{ | |
59 | type: 'line', | |
60 | xField: 'time', | |
61 | yField: 'val', | |
62 | fill: 'true', | |
63 | colors: ['#cfcfcf'], | |
64 | tooltip: { | |
65 | trackMouse: true, | |
66 | renderer: function( tooltip, record, ctx) { | |
67 | var me = this.getChart(); | |
68 | var date = new Date(record.data.time); | |
69 | var value = me.up().renderer(record.data.val); | |
70 | tooltip.setHtml( | |
71 | me.up().title + ': ' + value + '<br />' + | |
72 | Ext.Date.format(date, 'H:i:s') | |
73 | ); | |
74 | } | |
75 | }, | |
76 | style: { | |
77 | lineWidth: 1.5, | |
78 | opacity: 0.60 | |
79 | }, | |
80 | marker: { | |
81 | opacity: 0, | |
82 | scaling: 0.01, | |
83 | fx: { | |
84 | duration: 200, | |
85 | easing: 'easeOut' | |
86 | } | |
87 | }, | |
88 | highlightCfg: { | |
89 | opacity: 1, | |
90 | scaling: 1.5 | |
91 | } | |
92 | }] | |
93 | } | |
94 | ], | |
95 | ||
96 | // the renderer for the tooltip and last value, | |
97 | // default just the value | |
98 | renderer: Ext.identityFn, | |
99 | ||
100 | // show the last x seconds | |
101 | // default is 5 minutes | |
102 | timeFrame: 5*60, | |
103 | ||
104 | addDataPoint: function(value, time) { | |
105 | var me = this.chart; | |
106 | var panel = me.up(); | |
107 | var now = new Date(); | |
108 | var begin = new Date(now.getTime() - (1000*panel.timeFrame)); | |
109 | ||
110 | me.store.add({ | |
111 | time: time || now.getTime(), | |
112 | val: value || 0 | |
113 | }); | |
114 | ||
115 | // delete all old records when we have 20 times more datapoints | |
116 | // than seconds in our timeframe (so even a subsecond graph does | |
117 | // not trigger this often) | |
118 | // | |
119 | // records in the store do not take much space, but like this, | |
120 | // we prevent a memory leak when someone has the site open for a long time | |
121 | // with minimal graphical glitches | |
122 | if (me.store.count() > panel.timeFrame * 20) { | |
123 | var oldData = me.store.getData().createFiltered(function(item) { | |
124 | return item.data.time < begin.getTime(); | |
125 | }); | |
126 | ||
127 | me.store.remove(oldData.getRange()); | |
128 | } | |
129 | ||
130 | me.timeaxis.setMinimum(begin.getTime()); | |
131 | me.timeaxis.setMaximum(now.getTime()); | |
132 | me.valuesprite.setText(panel.renderer(value || 0).toString()); | |
133 | me.valuesprite.setAttributes({ | |
134 | x: me.getWidth() - 15, | |
135 | y: me.getHeight()/2 | |
136 | }, true); | |
137 | me.redraw(); | |
138 | }, | |
139 | ||
140 | setTitle: function(title) { | |
141 | this.title = title; | |
142 | var me = this.getComponent('title'); | |
143 | me.update({title: title}); | |
144 | }, | |
145 | ||
146 | initComponent: function(){ | |
147 | var me = this; | |
148 | me.callParent(); | |
149 | ||
150 | if (me.title) { | |
151 | me.getComponent('title').update({title: me.title}); | |
152 | } | |
153 | me.chart = me.getComponent('chart'); | |
154 | me.chart.timeaxis = me.chart.getAxes()[1]; | |
155 | me.chart.valuesprite = me.chart.getSurface('chart').get('valueSprite'); | |
156 | if (me.color) { | |
157 | me.chart.series[0].setStyle({ | |
158 | fill: me.color, | |
159 | stroke: me.color | |
160 | }); | |
161 | } | |
162 | } | |
163 | }); |