4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-chart-series-Gauge'>/**
19 </span> * @class Ext.chart.series.Gauge
20 * @extends Ext.chart.series.Series
22 * Creates a Gauge Chart. Gauge Charts are used to show progress in a certain variable. There are two ways of using the Gauge chart.
23 * One is setting a store element into the Gauge and selecting the field to be used from that store. Another one is instanciating the
24 * visualization and using the `setValue` method to adjust the value you want.
26 * A chart/series configuration for the Gauge visualization could look like this:
43 * colorSet: ['#F49D10', '#ddd']
47 * In this configuration we create a special Gauge axis to be used with the gauge visualization (describing half-circle markers), and also we're
48 * setting a maximum, minimum and steps configuration options into the axis. The Gauge series configuration contains the store field to be bound to
49 * the visual display and the color set to be used with the visualization.
53 Ext.define('Ext.chart.series.Gauge', {
55 /* Begin Definitions */
57 extend: 'Ext.chart.series.Series',
61 type: "gauge",
62 alias: 'series.gauge',
66 <span id='Ext-chart-series-Gauge-cfg-highlightDuration'> /**
67 </span> * @cfg {Number} highlightDuration
68 * The duration for the pie slice highlight effect.
70 highlightDuration: 150,
72 <span id='Ext-chart-series-Gauge-cfg-angleField'> /**
73 </span> * @cfg {String} angleField
74 * The store record field name to be used for the pie angles.
75 * The values bound to this field name must be positive real numbers.
76 * This parameter is required.
80 <span id='Ext-chart-series-Gauge-cfg-needle'> /**
81 </span> * @cfg {Boolean} needle
82 * Use the Gauge Series as an area series or add a needle to it. Default's false.
86 <span id='Ext-chart-series-Gauge-cfg-donut'> /**
87 </span> * @cfg {Boolean|Number} donut
88 * Use the entire disk or just a fraction of it for the gauge. Default's false.
92 <span id='Ext-chart-series-Gauge-cfg-showInLegend'> /**
93 </span> * @cfg {Boolean} showInLegend
94 * Whether to add the pie chart elements as legend items. Default's false.
98 <span id='Ext-chart-series-Gauge-cfg-style'> /**
99 </span> * @cfg {Object} style
100 * An object containing styles for overriding series styles from Theming.
104 constructor: function(config) {
105 this.callParent(arguments);
108 surface = chart.surface,
110 shadow = chart.shadow, i, l, cfg;
111 Ext.apply(me, config, {
113 "stroke-width": 6,
114 "stroke-opacity": 1,
115 stroke: 'rgb(200, 200, 200)',
122 "stroke-width": 4,
123 "stroke-opacity": 1,
124 stroke: 'rgb(150, 150, 150)',
131 "stroke-width": 2,
132 "stroke-opacity": 1,
133 stroke: 'rgb(100, 100, 100)',
140 me.group = surface.getGroup(me.seriesId);
142 for (i = 0, l = me.shadowAttributes.length; i < l; i++) {
143 me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i));
146 surface.customAttributes.segment = function(opt) {
147 return me.getSegment(opt);
151 //@private updates some onbefore render parameters.
152 initialize: function() {
154 store = me.chart.substore || me.chart.store;
155 //Add yFields to be used in Legend.js
157 if (me.label.field) {
158 store.each(function(rec) {
159 me.yField.push(rec.get(me.label.field));
164 // @private returns an object with properties for a Slice
165 getSegment: function(opt) {
173 x1 = 0, x2 = 0, x3 = 0, x4 = 0,
174 y1 = 0, y2 = 0, y3 = 0, y4 = 0,
176 r = opt.endRho - opt.startRho,
177 startAngle = opt.startAngle,
178 endAngle = opt.endAngle,
179 midAngle = (startAngle + endAngle) / 2 * rad,
180 margin = opt.margin || 0,
181 flag = abs(endAngle - startAngle) > 180,
182 a1 = Math.min(startAngle, endAngle) * rad,
183 a2 = Math.max(startAngle, endAngle) * rad,
186 x += margin * cos(midAngle);
187 y += margin * sin(midAngle);
189 x1 = x + opt.startRho * cos(a1);
190 y1 = y + opt.startRho * sin(a1);
192 x2 = x + opt.endRho * cos(a1);
193 y2 = y + opt.endRho * sin(a1);
195 x3 = x + opt.startRho * cos(a2);
196 y3 = y + opt.startRho * sin(a2);
198 x4 = x + opt.endRho * cos(a2);
199 y4 = y + opt.endRho * sin(a2);
201 if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) {
204 //Solves mysterious clipping bug with IE
208 ["M", x1, y1],
209 ["L", x2, y2],
210 ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
216 ["M", x1, y1],
217 ["L", x2, y2],
218 ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
219 ["L", x3, y3],
220 ["A", opt.startRho, opt.startRho, 0, +flag, 0, x1, y1],
226 // @private utility function to calculate the middle point of a pie slice.
227 calcMiddle: function(item) {
233 startAngle = slice.startAngle,
234 endAngle = slice.endAngle,
235 radius = Math.max(('rho' in slice) ? slice.rho: me.radius, me.label.minMargin),
237 a1 = Math.min(startAngle, endAngle) * rad,
238 a2 = Math.max(startAngle, endAngle) * rad,
239 midAngle = -(a1 + (a2 - a1) / 2),
240 xm = x + (item.endRho + item.startRho) / 2 * Math.cos(midAngle),
241 ym = y - (item.endRho + item.startRho) / 2 * Math.sin(midAngle);
249 <span id='Ext-chart-series-Gauge-method-drawSeries'> /**
250 </span> * Draws the series for the current chart.
252 drawSeries: function() {
255 store = chart.substore || chart.store,
257 animate = me.chart.animate,
258 axis = me.chart.axes.get(0),
259 minimum = axis && axis.minimum || me.minimum || 0,
260 maximum = axis && axis.maximum || me.maximum || 0,
261 field = me.angleField || me.field || me.xField,
262 surface = chart.surface,
263 chartBBox = chart.chartBBox,
268 seriesStyle = me.seriesStyle,
269 seriesLabelStyle = me.seriesLabelStyle,
270 colorArrayStyle = me.colorArrayStyle,
271 colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
272 gutterX = chart.maxGutter[0],
273 gutterY = chart.maxGutter[1],
276 rendererAttributes, centerX, centerY, slice, slices, sprite, value,
277 item, ln, record, i, j, startAngle, endAngle, middleAngle, sliceLength, path,
278 p, spriteOptions, bbox, splitAngle, sliceA, sliceB;
280 Ext.apply(seriesStyle, me.style || {});
285 //override theme colors
287 colorArrayStyle = me.colorSet;
288 colorArrayLength = colorArrayStyle.length;
291 //if not store or store is empty then there's nothing to draw
292 if (!store || !store.getCount()) {
296 centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
297 centerY = me.centerY = chartBBox.y + chartBBox.height;
298 me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y);
299 me.slices = slices = [];
300 me.items = items = [];
303 record = store.getAt(0);
304 me.value = record.get(field);
316 splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
319 splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
324 endAngle: splitAngle,
329 value: me.maximum - value,
330 startAngle: splitAngle,
334 slices.push(sliceA, sliceB);
337 //do pie slices after.
338 for (i = 0, ln = slices.length; i < ln; i++) {
340 sprite = group.getAt(i);
341 //set pie slice properties
342 rendererAttributes = Ext.apply({
344 startAngle: slice.startAngle,
345 endAngle: slice.endAngle,
348 startRho: slice.rho * +donut / 100,
351 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {}));
354 rendererAttributes.segment, {
361 // Create a new sprite if needed (no height)
363 spriteOptions = Ext.apply({
364 type: "path",
366 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {}));
367 sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
369 slice.sprite = slice.sprite || [];
370 item.sprite = sprite;
371 slice.sprite.push(sprite);
373 rendererAttributes = me.renderer(sprite, record, rendererAttributes, i, store);
374 sprite._to = rendererAttributes;
375 me.onAnimate(sprite, {
376 to: rendererAttributes
379 rendererAttributes = me.renderer(sprite, record, Ext.apply(rendererAttributes, {
382 sprite.setAttributes(rendererAttributes, true);
387 splitAngle = splitAngle * Math.PI / 180;
389 if (!me.needleSprite) {
390 me.needleSprite = me.chart.surface.add({
392 path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
393 centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
394 'L', centerX + me.radius * cos(splitAngle),
395 centerY + -Math.abs(me.radius * sin(splitAngle))],
401 me.onAnimate(me.needleSprite, {
403 path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
404 centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
405 'L', centerX + me.radius * cos(splitAngle),
406 centerY + -Math.abs(me.radius * sin(splitAngle))]
410 me.needleSprite.setAttributes({
412 path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
413 centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
414 'L', centerX + me.radius * cos(splitAngle),
415 centerY + -Math.abs(me.radius * sin(splitAngle))]
419 me.needleSprite.setAttributes({
427 <span id='Ext-chart-series-Gauge-method-setValue'> /**
428 </span> * Sets the Gauge chart to the current specified value.
430 setValue: function (value) {
435 // @private callback for when creating a label sprite.
436 onCreateLabel: function(storeItem, item, i, display) {},
438 // @private callback for when placing a label sprite.
439 onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {},
441 // @private callback for when placing a callout.
442 onPlaceCallout: function() {},
444 // @private handles sprite animation for the series.
445 onAnimate: function(sprite, attr) {
447 return this.callParent(arguments);
450 isItemInPoint: function(x, y, item, i) {
454 // @private shows all elements in the series.
455 showAll: function() {
456 if (!isNaN(this._index)) {
457 this.__excludes[this._index] = false;
462 <span id='Ext-chart-series-Gauge-method-getLegendColor'> /**
463 </span> * Returns the color of the series (to be displayed as color for the series legend item).
464 * @param item {Object} Info about the item; same format as returned by #getItemForPoint
466 getLegendColor: function(index) {
468 return me.colorArrayStyle[index % me.colorArrayStyle.length];