You found a bug! We've classified it as EXTJS-6655 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Ext JS Premium Member anton.dimitrov's Avatar
    Join Date
    Nov 2011
    Location
    The Netherlands
    Posts
    130
    Vote Rating
    5
    anton.dimitrov is on a distinguished road

      1  

    Default [4.1] Chart Axis range is calculated wrong with stacked charts

    [4.1] Chart Axis range is calculated wrong with stacked charts


    REQUIRED INFORMATION
    Ext version tested:
    • Ext 4.1.1
    Browser versions tested against:
    • FF
    DOCTYPE tested against:
    • <!DOCTYPE HTML>
    Description:
    • When a chart data has negative values the Numeric axes minimum is not calculated correctly whick results in incorrect Axis range (minimum is always 0)
    Steps to reproduce the problem:
    • Run the test case
    The result that was expected: The result that occurs instead: Test Case:
    Code:
        Ext.require('Ext.chart.*');
            Ext.require(['Ext.layout.container.Fit', 'Ext.window.MessageBox']);
    
            Ext.onReady(function () {
                var store = Ext.create('Ext.data.JsonStore', {
                    fields: ['year', 'comedy', 'action', 'drama', 'thriller'],
                    data: [
                        {year: 2005, comedy: 34000000, action: 23890000, drama: 18450000, thriller: 20060000},
                        {year: 2006, comedy: -56703000, action: -38900000, drama: -12650000, thriller: -21000000},
                        {year: 2007, comedy: 42100000, action: 50410000, drama: 25780000, thriller: 23040000},
                        {year: 2008, comedy: 38910000, action: 56070000, drama: 24810000, thriller: 26940000}
                    ]
                });
    
                chart = Ext.create('Ext.chart.Chart',{
                    xtype: 'chart',
                    animate: true,
                    shadow: true,
                    store: store,
                    legend: {
                        position: 'right'
                    },
                    axes: [{
                        type: 'Numeric',
                        position: 'bottom',
                        fields: ['comedy', 'action', 'drama', 'thriller'],
                        title: false,
                        grid: true,
                        label: {
                            renderer: function(v) {
                                return String(v).replace(/(.)00000$/, '.$1M');
                            }
                        }
                    }, {
                        type: 'Category',
                        position: 'left',
                        fields: ['year'],
                        title: false
                    }],
                    series: [{
                        type: 'bar',
                        axis: 'bottom',
                        gutter: 80,
                        xField: 'year',
                        yField: ['comedy', 'action', 'drama', 'thriller'],
                        stacked: true,
                        tips: {
                            trackMouse: true,
                            width: 65,
                            height: 28,
                            renderer: function(storeItem, item) {
                                this.setTitle(String(item.value[1] / 1000000) + 'M');
                            }
                        }
                    }]
                });
    
    
                var panel1 = Ext.create('widget.panel', {
                    width: 800,
                    height: 400,
                    title: 'Stacked Bar Chart - Movies by Genre',
                    renderTo: Ext.getBody(),
                    layout: 'fit',
                    tbar: [{
                        text: 'Save Chart',
                        handler: function() {
                            Ext.MessageBox.confirm('Confirm Download', 'Would you like to download the chart as an image?', function(choice){
                                if(choice == 'yes'){
                                    chart.save({
                                        type: 'image/png'
                                    });
                                }
                            });
                        }
                    }],
                    items: chart
                });
            });
    HELPFUL INFORMATION
    Screenshot or Video:
    • attached
    See this URL for live test case: http:// Debugging already done:
    • none
    Possible fix:
    • It seems that the Ext.chart.axis.Axis.getRange() does not set the minimum.
    Additional CSS used:
    • only default ext-all.css
    • custom css (include details)
    Operating System:
    • Win7

  2. #2
    Ext JS Premium Member anton.dimitrov's Avatar
    Join Date
    Nov 2011
    Location
    The Netherlands
    Posts
    130
    Vote Rating
    5
    anton.dimitrov is on a distinguished road

      0  

    Default


    This is a possible fix, however I haven't tested it thoroughly with all kind of charts
    The resulting chat with 4.1.1 now is:
    Capture12.jpg

    Code:
    Ext.override(Ext.chart.axis.Axis,{
            getRange: function () {
                var me = this,
                    chart = me.chart,
                    store = chart.getChartStore(),
                    data = store.data.items,
                    series = chart.series.items,
                    position = me.position,
                    boundedAxes,
                    seriesClasses = Ext.chart.series,
                    aggregations = [],
                    min = Infinity, max = -Infinity,
                    vertical = me.position === 'left' || me.position === 'right',
                    i, ln, ln2, j, k, dataLength = data.length, aggregates,
                    countedFields = {},
                    allFields = {},
                    excludable = true,
                    fields, fieldMap, record, field, value;
                fields = me.fields;
                for (j = 0, ln = fields.length; j < ln; j++) {
                    allFields[fields[j]] = true;
                }
                for (i = 0, ln = series.length; i < ln; i++) {
                    if (series[i].seriesIsHidden) {
                        continue;
                    }
                    if (!series[i].getAxesForXAndYFields) {
                        continue;
                    }
                    boundedAxes = series[i].getAxesForXAndYFields();
                    if (boundedAxes.xAxis && boundedAxes.xAxis !== position && boundedAxes.yAxis && boundedAxes.yAxis !== position) {
    // If the series explicitly exclude current Axis, then exit.
                        continue;
                    }
                    if (seriesClasses.Bar && series[i] instanceof seriesClasses.Bar && !series[i].column) {
    // If this is a horizontal bar series, then flip xField and yField.
                        fields = vertical ? Ext.Array.from(series[i].xField) : Ext.Array.from(series[i].yField);
                    } else {
                        fields = vertical ? Ext.Array.from(series[i].yField) : Ext.Array.from(series[i].xField);
                    }
                    if (me.fields.length) {
                        for (j = 0, ln2 = fields.length; j < ln2; j++) {
                            if (allFields[fields[j]]) {
                                break;
                            }
                        }
                        if (j == ln2) {
    // Not matching fields, skipping this series.
                            continue;
                        }
                    }
                    if (aggregates = series[i].stacked) {
    // If this is a bar/column series, then it will be aggregated if it is of the same direction of the axis.
                        if (seriesClasses.Bar && series[i] instanceof seriesClasses.Bar) {
                            if (series[i].column != vertical) {
                                aggregates = false;
                                excludable = false;
                            }
                        }
    // Otherwise it is stacked vertically
                        else if (!vertical) {
                            aggregates = false;
                            excludable = false;
                        }
                    }
                    if (aggregates) {
                        fieldMap = {};
                        for (j = 0; j < fields.length; j++) {
                            if (excludable && series[i].__excludes && series[i].__excludes[j]) {
                                continue;
                            }
                            if (!allFields[fields[j]]) {
                                Ext.Logger.warn('Field `' + fields[j] + '` is not included in the ' + position + ' axis config.');
                            }
                            allFields[fields[j]] = fieldMap[fields[j]] = true;
                        }
                        aggregations.push({
                            fields: fieldMap,
                            value: 0
                        });
                    } else {
                        if (!fields || fields.length == 0) {
                            fields = me.fields;
                        }
                        for (j = 0; j < fields.length; j++) {
                            if (excludable && series[i].__excludes && series[i].__excludes[j]) {
                                continue;
                            }
                            allFields[fields[j]] = countedFields[fields[j]] = true;
                        }
                    }
                }
                for (i = 0; i < dataLength; i++) {
                    record = data[i];
                    for (k = 0; k < aggregations.length; k++) {
                        aggregations[k].value = 0;
                    }
                    for (field in allFields) {
                        value = record.get(field);
                        if (isNaN(value)) {
                            continue;
                        }
                        if (value === undefined) {
                            value = 0;
                        }
                        if (countedFields[field]) {
                            if (min > value) {
                                min = value;
                            }
                            if (max < value) {
                                max = value;
                            }
                        }
                        for (k = 0; k < aggregations.length; k++) {
                            if (aggregations[k].fields[field]) {
                                aggregations[k].value += value;
                                // If any aggregation is actually hit, then the min value should be at most 0.
                                if (min > 0) {
                                    min = 0;
                                }
    
                                if (max < aggregations[k].value && aggregations[k].value > 0) {
                                    max = aggregations[k].value;
                                }
    
                                if (min > aggregations[k].value && aggregations[k].value < 0) {
                                    min = aggregations[k].value;
                                }
                            }
                        }
                    }
                }
                if (!isFinite(max)) {
                    max = me.prevMax || 0;
                }
                if (!isFinite(min)) {
                    min = me.prevMin || 0;
                }
    //normalize min max for snapEnds.
                if (min != max && (max != Math.floor(max))) {
                    max = Math.floor(max) + 1;
                }
                if (!isNaN(me.minimum)) {
                    min = me.minimum;
                }
                if (!isNaN(me.maximum)) {
                    max = me.maximum;
                }
                if (min >= max) {
    // snapEnds will return NaN if max >= min;
                    max = min + 1;
                }
                return {min: min, max: max};
            }
        });

  3. #3
    Ext JS Premium Member anton.dimitrov's Avatar
    Join Date
    Nov 2011
    Location
    The Netherlands
    Posts
    130
    Vote Rating
    5
    anton.dimitrov is on a distinguished road

      0  

    Default


    Is somebody actually going to make an effort and check this bug ?

  4. #4
    Ext JS Premium Member
    Join Date
    Feb 2008
    Location
    SRC solution, Toulouse, FR
    Posts
    18
    Vote Rating
    2
    jfa is on a distinguished road

      0  

    Default


    Interested too, any news about this bug ?

  5. #5
    Sencha Premium Member
    Join Date
    Nov 2012
    Posts
    6
    Vote Rating
    0
    Snyder47 is on a distinguished road

      0  

    Default Any Progress???

    Any Progress???


    We are seeing the same problem. Has this issue been addressed?

    Using a normal column chart:

    Column_Chart.png

    Using a stacked column chart:

    Stacked_Column_Chart_ERROR.png

  6. #6
    Sencha Premium Member
    Join Date
    Nov 2012
    Posts
    6
    Vote Rating
    0
    Snyder47 is on a distinguished road

      0  

    Default


    Is anyone at Sencha paying attention here!

Thread Participants: 2

Tags for this Thread

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