--- /dev/null
+<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-chart.series.Gauge'>/**
+</span> * @class Ext.chart.series.Gauge
+ * @extends Ext.chart.series.Series
+ *
+ * Creates a Gauge Chart. Gauge Charts are used to show progress in a certain variable. There are two ways of using the Gauge chart.
+ * One is setting a store element into the Gauge and selecting the field to be used from that store. Another one is instanciating the
+ * visualization and using the `setValue` method to adjust the value you want.
+ *
+ * A chart/series configuration for the Gauge visualization could look like this:
+ *
+ * {
+ * xtype: 'chart',
+ * store: store,
+ * axes: [{
+ * type: 'gauge',
+ * position: 'gauge',
+ * minimum: 0,
+ * maximum: 100,
+ * steps: 10,
+ * margin: -10
+ * }],
+ * series: [{
+ * type: 'gauge',
+ * field: 'data1',
+ * donut: false,
+ * colorSet: ['#F49D10', '#ddd']
+ * }]
+ * }
+ *
+ * In this configuration we create a special Gauge axis to be used with the gauge visualization (describing half-circle markers), and also we're
+ * setting a maximum, minimum and steps configuration options into the axis. The Gauge series configuration contains the store field to be bound to
+ * the visual display and the color set to be used with the visualization.
+ *
+ * @xtype gauge
+ */
+Ext.define('Ext.chart.series.Gauge', {
+
+ /* Begin Definitions */
+
+ extend: 'Ext.chart.series.Series',
+
+ /* End Definitions */
+
+ type: "gauge",
+ alias: 'series.gauge',
+
+ rad: Math.PI / 180,
+
+<span id='Ext-chart.series.Gauge-cfg-highlightDuration'> /**
+</span> * @cfg {Number} highlightDuration
+ * The duration for the pie slice highlight effect.
+ */
+ highlightDuration: 150,
+
+<span id='Ext-chart.series.Gauge-cfg-angleField'> /**
+</span> * @cfg {String} angleField
+ * The store record field name to be used for the pie angles.
+ * The values bound to this field name must be positive real numbers.
+ * This parameter is required.
+ */
+ angleField: false,
+
+<span id='Ext-chart.series.Gauge-cfg-needle'> /**
+</span> * @cfg {Boolean} needle
+ * Use the Gauge Series as an area series or add a needle to it. Default's false.
+ */
+ needle: false,
+
+<span id='Ext-chart.series.Gauge-cfg-donut'> /**
+</span> * @cfg {Boolean|Number} donut
+ * Use the entire disk or just a fraction of it for the gauge. Default's false.
+ */
+ donut: false,
+
+<span id='Ext-chart.series.Gauge-cfg-showInLegend'> /**
+</span> * @cfg {Boolean} showInLegend
+ * Whether to add the pie chart elements as legend items. Default's false.
+ */
+ showInLegend: false,
+
+<span id='Ext-chart.series.Gauge-cfg-style'> /**
+</span> * @cfg {Object} style
+ * An object containing styles for overriding series styles from Theming.
+ */
+ style: {},
+
+ constructor: function(config) {
+ this.callParent(arguments);
+ var me = this,
+ chart = me.chart,
+ surface = chart.surface,
+ store = chart.store,
+ shadow = chart.shadow, i, l, cfg;
+ Ext.apply(me, config, {
+ shadowAttributes: [{
+ "stroke-width": 6,
+ "stroke-opacity": 1,
+ stroke: 'rgb(200, 200, 200)',
+ translate: {
+ x: 1.2,
+ y: 2
+ }
+ },
+ {
+ "stroke-width": 4,
+ "stroke-opacity": 1,
+ stroke: 'rgb(150, 150, 150)',
+ translate: {
+ x: 0.9,
+ y: 1.5
+ }
+ },
+ {
+ "stroke-width": 2,
+ "stroke-opacity": 1,
+ stroke: 'rgb(100, 100, 100)',
+ translate: {
+ x: 0.6,
+ y: 1
+ }
+ }]
+ });
+ me.group = surface.getGroup(me.seriesId);
+ if (shadow) {
+ for (i = 0, l = me.shadowAttributes.length; i < l; i++) {
+ me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i));
+ }
+ }
+ surface.customAttributes.segment = function(opt) {
+ return me.getSegment(opt);
+ };
+ },
+
+ //@private updates some onbefore render parameters.
+ initialize: function() {
+ var me = this,
+ store = me.chart.substore || me.chart.store;
+ //Add yFields to be used in Legend.js
+ me.yField = [];
+ if (me.label.field) {
+ store.each(function(rec) {
+ me.yField.push(rec.get(me.label.field));
+ });
+ }
+ },
+
+ // @private returns an object with properties for a Slice
+ getSegment: function(opt) {
+ var me = this,
+ rad = me.rad,
+ cos = Math.cos,
+ sin = Math.sin,
+ abs = Math.abs,
+ x = me.centerX,
+ y = me.centerY,
+ x1 = 0, x2 = 0, x3 = 0, x4 = 0,
+ y1 = 0, y2 = 0, y3 = 0, y4 = 0,
+ delta = 1e-2,
+ r = opt.endRho - opt.startRho,
+ startAngle = opt.startAngle,
+ endAngle = opt.endAngle,
+ midAngle = (startAngle + endAngle) / 2 * rad,
+ margin = opt.margin || 0,
+ flag = abs(endAngle - startAngle) > 180,
+ a1 = Math.min(startAngle, endAngle) * rad,
+ a2 = Math.max(startAngle, endAngle) * rad,
+ singleSlice = false;
+
+ x += margin * cos(midAngle);
+ y += margin * sin(midAngle);
+
+ x1 = x + opt.startRho * cos(a1);
+ y1 = y + opt.startRho * sin(a1);
+
+ x2 = x + opt.endRho * cos(a1);
+ y2 = y + opt.endRho * sin(a1);
+
+ x3 = x + opt.startRho * cos(a2);
+ y3 = y + opt.startRho * sin(a2);
+
+ x4 = x + opt.endRho * cos(a2);
+ y4 = y + opt.endRho * sin(a2);
+
+ if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) {
+ singleSlice = true;
+ }
+ //Solves mysterious clipping bug with IE
+ if (singleSlice) {
+ return {
+ path: [
+ ["M", x1, y1],
+ ["L", x2, y2],
+ ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
+ ["Z"]]
+ };
+ } else {
+ return {
+ path: [
+ ["M", x1, y1],
+ ["L", x2, y2],
+ ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
+ ["L", x3, y3],
+ ["A", opt.startRho, opt.startRho, 0, +flag, 0, x1, y1],
+ ["Z"]]
+ };
+ }
+ },
+
+ // @private utility function to calculate the middle point of a pie slice.
+ calcMiddle: function(item) {
+ var me = this,
+ rad = me.rad,
+ slice = item.slice,
+ x = me.centerX,
+ y = me.centerY,
+ startAngle = slice.startAngle,
+ endAngle = slice.endAngle,
+ radius = Math.max(('rho' in slice) ? slice.rho: me.radius, me.label.minMargin),
+ donut = +me.donut,
+ a1 = Math.min(startAngle, endAngle) * rad,
+ a2 = Math.max(startAngle, endAngle) * rad,
+ midAngle = -(a1 + (a2 - a1) / 2),
+ xm = x + (item.endRho + item.startRho) / 2 * Math.cos(midAngle),
+ ym = y - (item.endRho + item.startRho) / 2 * Math.sin(midAngle);
+
+ item.middle = {
+ x: xm,
+ y: ym
+ };
+ },
+
+<span id='Ext-chart.series.Gauge-method-drawSeries'> /**
+</span> * Draws the series for the current chart.
+ */
+ drawSeries: function() {
+ var me = this,
+ chart = me.chart,
+ store = chart.substore || chart.store,
+ group = me.group,
+ animate = me.chart.animate,
+ axis = me.chart.axes.get(0),
+ minimum = axis && axis.minimum || me.minimum || 0,
+ maximum = axis && axis.maximum || me.maximum || 0,
+ field = me.angleField || me.field || me.xField,
+ surface = chart.surface,
+ chartBBox = chart.chartBBox,
+ rad = me.rad,
+ donut = +me.donut,
+ values = {},
+ items = [],
+ seriesStyle = me.seriesStyle,
+ seriesLabelStyle = me.seriesLabelStyle,
+ colorArrayStyle = me.colorArrayStyle,
+ colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
+ gutterX = chart.maxGutter[0],
+ gutterY = chart.maxGutter[1],
+ cos = Math.cos,
+ sin = Math.sin,
+ rendererAttributes, centerX, centerY, slice, slices, sprite, value,
+ item, ln, record, i, j, startAngle, endAngle, middleAngle, sliceLength, path,
+ p, spriteOptions, bbox, splitAngle, sliceA, sliceB;
+
+ Ext.apply(seriesStyle, me.style || {});
+
+ me.setBBox();
+ bbox = me.bbox;
+
+ //override theme colors
+ if (me.colorSet) {
+ colorArrayStyle = me.colorSet;
+ colorArrayLength = colorArrayStyle.length;
+ }
+
+ //if not store or store is empty then there's nothing to draw
+ if (!store || !store.getCount()) {
+ return;
+ }
+
+ centerX = me.centerX = chartBBox.x + (chartBBox.width / 2);
+ centerY = me.centerY = chartBBox.y + chartBBox.height;
+ me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y);
+ me.slices = slices = [];
+ me.items = items = [];
+
+ if (!me.value) {
+ record = store.getAt(0);
+ me.value = record.get(field);
+ }
+
+ value = me.value;
+ if (me.needle) {
+ sliceA = {
+ series: me,
+ value: value,
+ startAngle: -180,
+ endAngle: 0,
+ rho: me.radius
+ };
+ splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
+ slices.push(sliceA);
+ } else {
+ splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
+ sliceA = {
+ series: me,
+ value: value,
+ startAngle: -180,
+ endAngle: splitAngle,
+ rho: me.radius
+ };
+ sliceB = {
+ series: me,
+ value: me.maximum - value,
+ startAngle: splitAngle,
+ endAngle: 0,
+ rho: me.radius
+ };
+ slices.push(sliceA, sliceB);
+ }
+
+ //do pie slices after.
+ for (i = 0, ln = slices.length; i < ln; i++) {
+ slice = slices[i];
+ sprite = group.getAt(i);
+ //set pie slice properties
+ rendererAttributes = Ext.apply({
+ segment: {
+ startAngle: slice.startAngle,
+ endAngle: slice.endAngle,
+ margin: 0,
+ rho: slice.rho,
+ startRho: slice.rho * +donut / 100,
+ endRho: slice.rho
+ }
+ }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {}));
+
+ item = Ext.apply({},
+ rendererAttributes.segment, {
+ slice: slice,
+ series: me,
+ storeItem: record,
+ index: i
+ });
+ items[i] = item;
+ // Create a new sprite if needed (no height)
+ if (!sprite) {
+ spriteOptions = Ext.apply({
+ type: "path",
+ group: group
+ }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {}));
+ sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
+ }
+ slice.sprite = slice.sprite || [];
+ item.sprite = sprite;
+ slice.sprite.push(sprite);
+ if (animate) {
+ rendererAttributes = me.renderer(sprite, record, rendererAttributes, i, store);
+ sprite._to = rendererAttributes;
+ me.onAnimate(sprite, {
+ to: rendererAttributes
+ });
+ } else {
+ rendererAttributes = me.renderer(sprite, record, Ext.apply(rendererAttributes, {
+ hidden: false
+ }), i, store);
+ sprite.setAttributes(rendererAttributes, true);
+ }
+ }
+
+ if (me.needle) {
+ splitAngle = splitAngle * Math.PI / 180;
+
+ if (!me.needleSprite) {
+ me.needleSprite = me.chart.surface.add({
+ type: 'path',
+ path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
+ centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
+ 'L', centerX + me.radius * cos(splitAngle),
+ centerY + -Math.abs(me.radius * sin(splitAngle))],
+ 'stroke-width': 4,
+ 'stroke': '#222'
+ });
+ } else {
+ if (animate) {
+ me.onAnimate(me.needleSprite, {
+ to: {
+ path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
+ centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
+ 'L', centerX + me.radius * cos(splitAngle),
+ centerY + -Math.abs(me.radius * sin(splitAngle))]
+ }
+ });
+ } else {
+ me.needleSprite.setAttributes({
+ type: 'path',
+ path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle),
+ centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)),
+ 'L', centerX + me.radius * cos(splitAngle),
+ centerY + -Math.abs(me.radius * sin(splitAngle))]
+ });
+ }
+ }
+ me.needleSprite.setAttributes({
+ hidden: false
+ }, true);
+ }
+
+ delete me.value;
+ },
+
+<span id='Ext-chart.series.Gauge-method-setValue'> /**
+</span> * Sets the Gauge chart to the current specified value.
+ */
+ setValue: function (value) {
+ this.value = value;
+ this.drawSeries();
+ },
+
+ // @private callback for when creating a label sprite.
+ onCreateLabel: function(storeItem, item, i, display) {},
+
+ // @private callback for when placing a label sprite.
+ onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {},
+
+ // @private callback for when placing a callout.
+ onPlaceCallout: function() {},
+
+ // @private handles sprite animation for the series.
+ onAnimate: function(sprite, attr) {
+ sprite.show();
+ return this.callParent(arguments);
+ },
+
+ isItemInPoint: function(x, y, item, i) {
+ return false;
+ },
+
+ // @private shows all elements in the series.
+ showAll: function() {
+ if (!isNaN(this._index)) {
+ this.__excludes[this._index] = false;
+ this.drawSeries();
+ }
+ },
+
+<span id='Ext-chart.series.Gauge-method-getLegendColor'> /**
+</span> * Returns the color of the series (to be displayed as color for the series legend item).
+ * @param item {Object} Info about the item; same format as returned by #getItemForPoint
+ */
+ getLegendColor: function(index) {
+ var me = this;
+ return me.colorArrayStyle[index % me.colorArrayStyle.length];
+ }
+});
+
+</pre></pre></body></html>
\ No newline at end of file