4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/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 instantiating 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 (required)
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.
79 <span id='Ext-chart-series-Gauge-cfg-needle'> /**
80 </span> * @cfg {Boolean} needle
81 * Use the Gauge Series as an area series or add a needle to it. Default's false.
85 <span id='Ext-chart-series-Gauge-cfg-donut'> /**
86 </span> * @cfg {Boolean/Number} donut
87 * Use the entire disk or just a fraction of it for the gauge. Default's false.
91 <span id='Ext-chart-series-Gauge-cfg-showInLegend'> /**
92 </span> * @cfg {Boolean} showInLegend
93 * Whether to add the pie chart elements as legend items. Default's false.
97 <span id='Ext-chart-series-Gauge-cfg-style'> /**
98 </span> * @cfg {Object} style
99 * An object containing styles for overriding series styles from Theming.
103 constructor: function(config) {
104 this.callParent(arguments);
107 surface = chart.surface,
109 shadow = chart.shadow, i, l, cfg;
110 Ext.apply(me, config, {
112 "stroke-width": 6,
113 "stroke-opacity": 1,
114 stroke: 'rgb(200, 200, 200)',
121 "stroke-width": 4,
122 "stroke-opacity": 1,
123 stroke: 'rgb(150, 150, 150)',
130 "stroke-width": 2,
131 "stroke-opacity": 1,
132 stroke: 'rgb(100, 100, 100)',
139 me.group = surface.getGroup(me.seriesId);
141 for (i = 0, l = me.shadowAttributes.length; i < l; i++) {
142 me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i));
145 surface.customAttributes.segment = function(opt) {
146 return me.getSegment(opt);
150 //@private updates some onbefore render parameters.
151 initialize: function() {
153 store = me.chart.getChartStore();
154 //Add yFields to be used in Legend.js
156 if (me.label.field) {
157 store.each(function(rec) {
158 me.yField.push(rec.get(me.label.field));
163 // @private returns an object with properties for a Slice
164 getSegment: function(opt) {
172 x1 = 0, x2 = 0, x3 = 0, x4 = 0,
173 y1 = 0, y2 = 0, y3 = 0, y4 = 0,
175 r = opt.endRho - opt.startRho,
176 startAngle = opt.startAngle,
177 endAngle = opt.endAngle,
178 midAngle = (startAngle + endAngle) / 2 * rad,
179 margin = opt.margin || 0,
180 flag = abs(endAngle - startAngle) > 180,
181 a1 = Math.min(startAngle, endAngle) * rad,
182 a2 = Math.max(startAngle, endAngle) * rad,
185 x += margin * cos(midAngle);
186 y += margin * sin(midAngle);
188 x1 = x + opt.startRho * cos(a1);
189 y1 = y + opt.startRho * sin(a1);
191 x2 = x + opt.endRho * cos(a1);
192 y2 = y + opt.endRho * sin(a1);
194 x3 = x + opt.startRho * cos(a2);
195 y3 = y + opt.startRho * sin(a2);
197 x4 = x + opt.endRho * cos(a2);
198 y4 = y + opt.endRho * sin(a2);
200 if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) {
203 //Solves mysterious clipping bug with IE
207 ["M", x1, y1],
208 ["L", x2, y2],
209 ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
215 ["M", x1, y1],
216 ["L", x2, y2],
217 ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
218 ["L", x3, y3],
219 ["A", opt.startRho, opt.startRho, 0, +flag, 0, x1, y1],
225 // @private utility function to calculate the middle point of a pie slice.
226 calcMiddle: function(item) {
232 startAngle = slice.startAngle,
233 endAngle = slice.endAngle,
234 radius = Math.max(('rho' in slice) ? slice.rho: me.radius, me.label.minMargin),
236 a1 = Math.min(startAngle, endAngle) * rad,
237 a2 = Math.max(startAngle, endAngle) * rad,
238 midAngle = -(a1 + (a2 - a1) / 2),
239 xm = x + (item.endRho + item.startRho) / 2 * Math.cos(midAngle),
240 ym = y - (item.endRho + item.startRho) / 2 * Math.sin(midAngle);
248 <span id='Ext-chart-series-Gauge-method-drawSeries'> /**
249 </span> * Draws the series for the current chart.
251 drawSeries: function() {
254 store = chart.getChartStore(),
256 animate = me.chart.animate,
257 axis = me.chart.axes.get(0),
258 minimum = axis && axis.minimum || me.minimum || 0,
259 maximum = axis && axis.maximum || me.maximum || 0,
260 field = me.angleField || me.field || me.xField,
261 surface = chart.surface,
262 chartBBox = chart.chartBBox,
267 seriesStyle = me.seriesStyle,
268 seriesLabelStyle = me.seriesLabelStyle,
269 colorArrayStyle = me.colorArrayStyle,
270 colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
271 gutterX = chart.maxGutter[0],
272 gutterY = chart.maxGutter[1],
275 rendererAttributes, centerX, centerY, slice, slices, sprite, value,
276 item, ln, record, i, j, startAngle, endAngle, middleAngle, sliceLength, path,
277 p, spriteOptions, bbox, splitAngle, sliceA, sliceB;
279 Ext.apply(seriesStyle, me.style || {});
284 //override theme colors
286 colorArrayStyle = me.colorSet;
287 colorArrayLength = colorArrayStyle.length;
290 //if not store or store is empty then there's nothing to draw
291 if (!store || !store.getCount()) {
295 centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
296 centerY = me.centerY = chartBBox.y + chartBBox.height;
297 me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y);
298 me.slices = slices = [];
299 me.items = items = [];
302 record = store.getAt(0);
303 me.value = record.get(field);
315 splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
318 splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
323 endAngle: splitAngle,
328 value: me.maximum - value,
329 startAngle: splitAngle,
333 slices.push(sliceA, sliceB);
336 //do pie slices after.
337 for (i = 0, ln = slices.length; i < ln; i++) {
339 sprite = group.getAt(i);
340 //set pie slice properties
341 rendererAttributes = Ext.apply({
343 startAngle: slice.startAngle,
344 endAngle: slice.endAngle,
347 startRho: slice.rho * +donut / 100,
350 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {}));
353 rendererAttributes.segment, {
360 // Create a new sprite if needed (no height)
362 spriteOptions = Ext.apply({
363 type: "path",
365 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {}));
366 sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
368 slice.sprite = slice.sprite || [];
369 item.sprite = sprite;
370 slice.sprite.push(sprite);
372 rendererAttributes = me.renderer(sprite, record, rendererAttributes, i, store);
373 sprite._to = rendererAttributes;
374 me.onAnimate(sprite, {
375 to: rendererAttributes
378 rendererAttributes = me.renderer(sprite, record, Ext.apply(rendererAttributes, {
381 sprite.setAttributes(rendererAttributes, true);
386 splitAngle = splitAngle * Math.PI / 180;
388 if (!me.needleSprite) {
389 me.needleSprite = me.chart.surface.add({
391 path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
392 centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
393 'L', centerX + me.radius * cos(splitAngle),
394 centerY + -Math.abs(me.radius * sin(splitAngle))],
400 me.onAnimate(me.needleSprite, {
402 path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
403 centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
404 'L', centerX + me.radius * cos(splitAngle),
405 centerY + -Math.abs(me.radius * sin(splitAngle))]
409 me.needleSprite.setAttributes({
411 path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
412 centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
413 'L', centerX + me.radius * cos(splitAngle),
414 centerY + -Math.abs(me.radius * sin(splitAngle))]
418 me.needleSprite.setAttributes({
426 <span id='Ext-chart-series-Gauge-method-setValue'> /**
427 </span> * Sets the Gauge chart to the current specified value.
429 setValue: function (value) {
434 // @private callback for when creating a label sprite.
435 onCreateLabel: function(storeItem, item, i, display) {},
437 // @private callback for when placing a label sprite.
438 onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {},
440 // @private callback for when placing a callout.
441 onPlaceCallout: function() {},
443 // @private handles sprite animation for the series.
444 onAnimate: function(sprite, attr) {
446 return this.callParent(arguments);
449 isItemInPoint: function(x, y, item, i) {
453 // @private shows all elements in the series.
454 showAll: function() {
455 if (!isNaN(this._index)) {
456 this.__excludes[this._index] = false;
461 <span id='Ext-chart-series-Gauge-method-getLegendColor'> /**
462 </span> * Returns the color of the series (to be displayed as color for the series legend item).
463 * @param item {Object} Info about the item; same format as returned by #getItemForPoint
465 getLegendColor: function(index) {
467 return me.colorArrayStyle[index % me.colorArrayStyle.length];