1. #11
    Ext JS Premium Member devtig's Avatar
    Join Date
    Jan 2010
    Location
    Rotterdam, The Netherlands
    Posts
    389
    Vote Rating
    13
    devtig will become famous soon enough

      0  

    Default


    Works great in ExtJS 4.1.1. Thanks!

  2. #12
    Sencha Premium Member
    Join Date
    Sep 2012
    Location
    Argentina
    Posts
    34
    Vote Rating
    1
    grpbhb is on a distinguished road

      0  

    Default


    Thank you!

  3. #13
    Sencha User
    Join Date
    Feb 2012
    Posts
    26
    Vote Rating
    0
    Syntona is on a distinguished road

      0  

    Default


    Hi,
    Nice work.
    and I really need this control in my application which is in Sencha Chart 2.

    Please help me how to incorporate this in Sencha chart 2.

    many thanks in advance.

  4. #14
    Ext JS Premium Member troseberry's Avatar
    Join Date
    Feb 2010
    Location
    Dayton, OH
    Posts
    277
    Vote Rating
    9
    troseberry will become famous soon enough

      0  

    Default


    I have never looked at the sencha touch charts but I will take a look

  5. #15
    Sencha User
    Join Date
    Feb 2012
    Posts
    26
    Vote Rating
    0
    Syntona is on a distinguished road

      0  

    Default Modified code of KpiGauge for SenchaChart

    Modified code of KpiGauge for SenchaChart


    Hey, Thanks for your reply.

    I have tried to incorporate it into Sencha-chart 2.
    I have modified your code to adjust with existing SenchaChart library.

    However, when i tried to add a new series type, it is still giving an error.

    Uncaught Error: [Ext.create] Cannot create an instance of unrecognized class name / alias: Ext.chart.series.Kpigauge

    Code:
    Ext.define('Ext.chart.series.KPIGauge', {
    
    
        extend: 'Ext.chart.series.Gauge',
     
        alias: 'series.kpigauge',
    
        type: "kpigauge",
    
    
        rad: Math.PI / 180,
    
    
        config: {
            /**
            * @cfg {String} angleField
            * The store record field name to be used for the gauge angles.
            * The values bound to this field name must be positive real numbers.
            * This parameter is required.
            */
            angleField: false,
    
    
            ranges: [],
    
    
            /**
            * @cfg {Boolean} needle
            * Use the Gauge Series as an area series or add a needle to it. Default's false.
            */
            needle: false,
    
    
            /**
            * @cfg {Boolean/Number} donut
            * Use the entire disk or just a fraction of it for the gauge. Default's false.
            */
            donut: false,
    
    
            /**
            * @cfg {Boolean} showInLegend
            * Whether to add the gauge chart elements as legend items. Default's false.
            */
            showInLegend: false,
    
    
            /**
            * @cfg {Object} style
            * An object containing styles for overriding series styles from Theming.
            */
    
    
            minimum: 0,
    
    
            maximum: 100,
    
    
            colorSet: []
        },
    
    
        drawSeries: function () {
    
    
            var me = this,
                chart = me.getChart(),
                store = chart.substore || chart.getStore(),
                group = me.group,
                animate = me.getChart().getAnimate(),
                axis = me.getChart().getAxes().get(0),
                minimum = axis && axis.getMinimum() || me.getMinimum() || 0,
                maximum = axis && axis.getMaximum() || me.getMaximum() || 0,
                ranges = me.getRanges(),
                field = me.getAngleField() || me.field,
                surface = me.getSurface(),
                chartBBox = chart.chartBBox,
            //  rad = me.rad,
                donut = +me.getDonut(),
                values = {},
                items = [],
                seriesStyle = me.style,
                colors = chart.getColorsStyle(),
                colorArrayLength = colors && colors.length || 0,
                cos = Math.cos,
                sin = Math.sin,
                enableShadows = !!chart.getShadow(),
                rendererAttributes, centerX, centerY, slice, slices, sprite, value,
                item, ln, record, i, j, r, slice, splitAngle, rl, startAngle, endAngle, middleAngle, sliceLength, path,
                p, spriteOptions, bbox, valueAngle;
    
    
    
    
            if (ranges == undefined || ranges.length <= 0) {
                console.log(':((((');
            }
            else {
                console.log('Hurrey!!!');
            }
    
    
            if (me.fireEvent('beforedraw', me) === false) {
                return;
            }
    
    
            Ext.chart.series.Gauge.superclass.drawSeries.call(this);
            me.setBBox();
            bbox = me.bbox;
    
    
            //override theme colors
            if (me.getColorSet()) {
                colors = me.getColorSet();
                colorArrayLength = colors.length;
            }
    
    
            //if not store or store is empty then there's nothing to draw
            if (!me.getRecordCount()) {
                surface.getItems().hide(true);
                return;
            }
    
    
            centerX = me.centerX = (chartBBox.width / 2);
            centerY = me.centerY = chartBBox.height;
            me.radius = Math.min(centerX, centerY);
            me.slices = slices = [];
            me.items = items = [];
    
    
            if (!me.value) {
                record = store.getAt(0);
                me.value = record.get(field);
            }
    
    
            value = me.value;
            valueAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
    
    
            for (r = 0, rl = ranges.length; r < rl; r++) {
                splitFromAngle = -180 * (1 - (ranges[r].from - minimum) / (maximum - minimum));
                splitToAngle = -180 * (1 - (ranges[r].to - minimum) / (maximum - minimum));
    
    
                slices.push({
                    series: me,
                    startAngle: splitFromAngle,
                    endAngle: splitToAngle,
                    rho: me.radius,
                    value: value,
                    color: ranges[r].color
                });
            }
    
    
            //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, colors && { fill: colors[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, colors && { fill: colors[i % colorArrayLength]} || {}));
    
    
                    if (enableShadows) {
                        Ext.apply(spriteOptions, me.getShadowOptions());
                    }
    
    
                    sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
                }
                slice.sprite = slice.sprite || [];
                item.sprite = sprite;
                slice.sprite.push(sprite);
                if (animate) {
                    rendererAttributes = me.getRenderer()(sprite, record, rendererAttributes, i, store);
                    sprite._to = rendererAttributes;
                    me.onAnimate(sprite, {
                        to: rendererAttributes
                    });
                } else {
                    rendererAttributes = me.getRenderer()(sprite, record, Ext.apply(rendererAttributes, {
                        hidden: false
                    }), i, store);
                    sprite.setAttributes(rendererAttributes, true);
                }
            }
    
    
            valueAngle = valueAngle * Math.PI / 180;
    
    
            if (!me.needleSprite) {
    
    
                me.needleSprite = me.getSurface().add({
                    type: 'path',
                    path: ['M', centerX + (me.radius * +donut / 100) * cos(valueAngle),
                                    centerY + -Math.abs((me.radius * +donut / 100) * sin(valueAngle)),
                               'L', centerX + me.radius * cos(valueAngle),
                                    centerY + -Math.abs(me.radius * sin(valueAngle))],
                    'stroke-width': 4,
                    'stroke': '#222'
                });
    
    
            } else {
                if (animate) {
                    me.onAnimate(me.needleSprite, {
                        to: {
                            path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
                                    centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
                               'L', centerX + me.radius * cos(valueAngle),
                                    centerY + -Math.abs(me.radius * sin(valueAngle))]
                        }
                    });
                } else {
                    me.needleSprite.setAttributes({
                        type: 'path',
                        path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
                                    centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
                               'L', centerX + me.radius * cos(valueAngle),
                                    centerY + -Math.abs(me.radius * sin(valueAngle))]
                    });
                }
            }
    
    
            me.needleSprite.setAttributes({
                hidden: false
            }, true);
    
    
            delete me.value;
    
    
            me.fireEvent('draw', me);
        }
    
    
    });
    and if i replace the existing gaugeChart drawseries function, it is working fine.
    but then i am loosing original gauge series.

    Code:
    
    Ext.define('Ext.chart.series.Gauge', {
    
    
        extend: 'Ext.chart.series.Series',
    
    
        type: "gauge",
    
    
        rad: Math.PI / 180,
    
    
        config: {
            /**
            * @cfg {String} angleField
            * The store record field name to be used for the gauge angles.
            * The values bound to this field name must be positive real numbers.
            * This parameter is required.
            */
            angleField: false,
    
    
            ranges: [],
    
    
            /**
            * @cfg {Boolean} needle
            * Use the Gauge Series as an area series or add a needle to it. Default's false.
            */
            needle: false,
    
    
            /**
            * @cfg {Boolean/Number} donut
            * Use the entire disk or just a fraction of it for the gauge. Default's false.
            */
            donut: false,
    
    
            /**
            * @cfg {Boolean} showInLegend
            * Whether to add the gauge chart elements as legend items. Default's false.
            */
            showInLegend: false,
    
    
            /**
            * @cfg {Object} style
            * An object containing styles for overriding series styles from Theming.
            */
    
    
            minimum: 0,
    
    
            maximum: 100,
    
    
            colorSet: []
        },
    
    
        constructor: function (config) {
            if (!config.angleField && config.field) {
                console.warn('use angleField instead');
                config.angleField = config.field;
            }
    
    
            this.callParent(arguments);
    
    
            var me = this,
                chart = me.getChart(),
                surface = me.getSurface();
    
    
            surface.addCustomAttribute("segment", function (opt) {
                return me.getSegment(opt);
            });
        },
    
    
        //@private updates some onbefore render parameters.
        initialize: function () {
            var me = this;
            me.callParent();
        },
    
    
        // @private returns an object with properties for a PieSlice.
        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,
                startAngle = opt.startAngle,
                endAngle = opt.endAngle,
                midAngle = (startAngle + endAngle) / 2 * rad,
                margin = opt.margin || 0,
                flag = abs(endAngle - startAngle) > 180,
                auxValue = abs(endAngle % 360),
                flag2 = auxValue > 90 && auxValue < 270,
                a1 = Math.min(startAngle, endAngle) * rad,
                a2 = Math.max(startAngle, endAngle) * rad,
                singleSlice = false,
                fullCircle = 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;
            }
    
    
            fullCircle = singleSlice && (abs(x2 - x4) <= delta && abs(y2 - y4) <= delta);
            //Solves mysterious clipping bug with IE
            if (fullCircle) {
                return {
                    path: [
                    ["M", x4, y4 - 1e-4],
                    ["A", opt.endRho, opt.endRho, 0, +flag, +flag2, x4, y4],
                    ["Z"]]
                };
            } else 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],
                    ["M", 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,
                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
            };
        },
        drawSeries: function () {
    
    
            var me = this,
                chart = me.getChart(),
                store = chart.substore || chart.getStore(),
                group = me.group,
                animate = me.getChart().getAnimate(),
                axis = me.getChart().getAxes().get(0),
                minimum = axis && axis.getMinimum() || me.getMinimum() || 0,
                maximum = axis && axis.getMaximum() || me.getMaximum() || 0,
                ranges = me.getRanges(),
                field = me.getAngleField() || me.field,
                surface = me.getSurface(),
                chartBBox = chart.chartBBox,
            //  rad = me.rad,
                donut = +me.getDonut(),
                values = {},
                items = [],
                seriesStyle = me.style,
                colors = chart.getColorsStyle(),
                colorArrayLength = colors && colors.length || 0,
                cos = Math.cos,
                sin = Math.sin,
                enableShadows = !!chart.getShadow(),
                rendererAttributes, centerX, centerY, slice, slices, sprite, value,
                item, ln, record, i, j, r, slice, splitAngle, rl, startAngle, endAngle, middleAngle, sliceLength, path,
                p, spriteOptions, bbox, valueAngle;
    
    
    
    
            if (ranges == undefined || ranges.length <= 0) {
                console.log(':((((');
            }
            else {
                console.log('Hurrey!!!');
            }
    
    
            if (me.fireEvent('beforedraw', me) === false) {
                return;
            }
    
    
            Ext.chart.series.Gauge.superclass.drawSeries.call(this);
            me.setBBox();
            bbox = me.bbox;
    
    
            //override theme colors
            if (me.getColorSet()) {
                colors = me.getColorSet();
                colorArrayLength = colors.length;
            }
    
    
            //if not store or store is empty then there's nothing to draw
            if (!me.getRecordCount()) {
                surface.getItems().hide(true);
                return;
            }
    
    
            centerX = me.centerX = (chartBBox.width / 2);
            centerY = me.centerY = chartBBox.height;
            me.radius = Math.min(centerX, centerY);
            me.slices = slices = [];
            me.items = items = [];
    
    
            if (!me.value) {
                record = store.getAt(0);
                me.value = record.get(field);
            }
    
    
            value = me.value;
            valueAngle = -180 * (1 - (value - minimum) / (maximum - minimum));
    
    
            for (r = 0, rl = ranges.length; r < rl; r++) {
                splitFromAngle = -180 * (1 - (ranges[r].from - minimum) / (maximum - minimum));
                splitToAngle = -180 * (1 - (ranges[r].to - minimum) / (maximum - minimum));
    
    
                slices.push({
                    series: me,
                    startAngle: splitFromAngle,
                    endAngle: splitToAngle,
                    rho: me.radius,
                    value: value,
                    color: ranges[r].color
                });
            }
    
    
            //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, colors && { fill: colors[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, colors && { fill: colors[i % colorArrayLength]} || {}));
    
    
                    if (enableShadows) {
                        Ext.apply(spriteOptions, me.getShadowOptions());
                    }
    
    
                    sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes));
                }
                slice.sprite = slice.sprite || [];
                item.sprite = sprite;
                slice.sprite.push(sprite);
                if (animate) {
                    rendererAttributes = me.getRenderer()(sprite, record, rendererAttributes, i, store);
                    sprite._to = rendererAttributes;
                    me.onAnimate(sprite, {
                        to: rendererAttributes
                    });
                } else {
                    rendererAttributes = me.getRenderer()(sprite, record, Ext.apply(rendererAttributes, {
                        hidden: false
                    }), i, store);
                    sprite.setAttributes(rendererAttributes, true);
                }
            }
    
    
            valueAngle = valueAngle * Math.PI / 180;
    
    
            if (!me.needleSprite) {
    
    
                me.needleSprite = me.getSurface().add({
                    type: 'path',
                    path: ['M', centerX + (me.radius * +donut / 100) * cos(valueAngle),
                                    centerY + -Math.abs((me.radius * +donut / 100) * sin(valueAngle)),
                               'L', centerX + me.radius * cos(valueAngle),
                                    centerY + -Math.abs(me.radius * sin(valueAngle))],
                    'stroke-width': 4,
                    'stroke': '#222'
                });
    
    
            } else {
                if (animate) {
                    me.onAnimate(me.needleSprite, {
                        to: {
                            path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
                                    centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
                               'L', centerX + me.radius * cos(valueAngle),
                                    centerY + -Math.abs(me.radius * sin(valueAngle))]
                        }
                    });
                } else {
                    me.needleSprite.setAttributes({
                        type: 'path',
                        path: ['M', centerX + (me.radius * 0 / 100) * cos(valueAngle),
                                    centerY + -Math.abs((me.radius * 0 / 100) * sin(valueAngle)),
                               'L', centerX + me.radius * cos(valueAngle),
                                    centerY + -Math.abs(me.radius * sin(valueAngle))]
                    });
                }
            }
    
    
            me.needleSprite.setAttributes({
                hidden: false
            }, true);
    
    
            delete me.value;
    
    
            me.fireEvent('draw', me);
        },
    
    
    
    
        /**
        * 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: Ext.emptyFn,
    
    
        // @private callback for when placing a label sprite.
        onPlaceLabel: Ext.emptyFn,
    
    
        // @private callback for when placing a callout.
        onPlaceCallout: Ext.emptyFn,
    
    
        // @private handles sprite animation for the series.
        onAnimate: function (sprite, attr) {
            sprite.show();
            Ext.chart.series.Gauge.superclass.onAnimate.apply(this, arguments);
        },
    
    
        isItemInPoint: function () {
            return false;
        },
    
    
        // @private shows all elements in the series.
        showAll: function () {
            if (!isNaN(this._index)) {
                this.getExcludes()[this._index] = false;
                this.drawSeries();
            }
        },
    
    
        /**
        * Returns the color of the series (to be displayed as color for the series legend item).
        * @param index {Number} Info about the item; same format as returned by #getItemForPoint
        */
        getLegendColor: function (index) {
            var me = this,
                colors = me.getChart().getColorsStyle();
            return me.getColorFromStyle(colors[index % colors.length]);
        }
    });

    Thanks in advance
    Last edited by Syntona; 8 Jan 2013 at 4:44 AM. Reason: Error message changes

  6. #16
    Sencha User
    Join Date
    Jul 2012
    Posts
    12
    Vote Rating
    1
    Neethi is on a distinguished road

      0  

    Default


    Can we have a render for the ranges, like 10b, 20b... 100b or 10 m, 20m.. 100m , to show larger range values.

  7. #17
    Sencha User
    Join Date
    Jul 2012
    Posts
    12
    Vote Rating
    1
    Neethi is on a distinguished road

      0  

    Default


    I want to change the labels of the chart to white as chart background is black. I could do it for firefox and chrome using css on tspan, but couldn't do anything for IE. Does anyone have solution for this.

    Cheers,
    Niti

  8. #18
    Ext JS Premium Member troseberry's Avatar
    Join Date
    Feb 2010
    Location
    Dayton, OH
    Posts
    277
    Vote Rating
    9
    troseberry will become famous soon enough

      0  

    Default


    I updated the code to include support for resizing while animated.

  9. #19
    Ext JS Premium Member troseberry's Avatar
    Join Date
    Feb 2010
    Location
    Dayton, OH
    Posts
    277
    Vote Rating
    9
    troseberry will become famous soon enough

      0  

    Default


    Updated the code to also include support for applying custom styles and inherit chart theme.

    The default gauge axis does not allow because it hardcodes attributes and does not use the normal chart themes.

    So now if you have a different color background you can change the axis labels to use your own style or apply a theme to the chart and set the position of the axis to use the required theme config

  10. #20
    Sencha User
    Join Date
    Dec 2009
    Posts
    6
    Vote Rating
    0
    aihua is on a distinguished road

      0  

    Default


    Hi,

    There is a bug. When click 'Reload Data', the number in the chart is not right, only displayed the initial number. Maybe you should modify the handler function for 'Reload Data'.

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi