    /** * @abstract * @class Ext.chart.series.Cartesian * @extends Ext.chart.series.Series * * Common base class for series implementations that plot values using cartesian coordinates. * * @constructor */Ext.define('Ext.chart.series.Cartesian', {    extend: 'Ext.chart.series.Series',    config: {        /**         * @cfg {String} xField          * The field used to access the x axis value from the items from the data source.         */        xField: null,         /**         * @cfg {String|String[]} yField         * The field(s) used to access the y-axis value(s) of the items from the data source.         */        yField: null,         /**         * @cfg {Ext.chart.axis.Axis|Number|String}         * xAxis The chart axis the series is bound to in the 'X' direction.         * Normally, this would be set automatically by the series.         * For charts with multiple x-axes, this defines which x-axis is used by the series.         * It refers to either axis' ID or the (zero-based) index of the axis         * in the chart's {@link Ext.chart.AbstractChart#axes axes} config.         */        xAxis: null,         /**         * @cfg {Ext.chart.axis.Axis|Number|String}         * yAxis The chart axis the series is bound to in the 'Y' direction.         * Normally, this would be set automatically by the series.         * For charts with multiple y-axes, this defines which y-axis is used by the series.         * It refers to either axis' ID or the (zero-based) index of the axis         * in the chart's {@link Ext.chart.AbstractChart#axes axes} config.         */        yAxis: null    },     directions: ['X', 'Y'],     /**     * @private     *     * Tells which store record fields should be used for a specific axis direction. E.g. for     *     *     fieldCategory<direction>: ['<fieldConfig1>', '<fieldConfig2>', ...]     *     * the field names from the following configs will be used:     *     *     series.<fieldConfig1>Field, series.<fieldConfig2>Field, ...     *     */    fieldCategoryX: ['X'],    fieldCategoryY: ['Y'],     applyXAxis: function (newAxis, oldAxis) {        return this.getChart().getAxis(newAxis) || oldAxis;    },     applyYAxis: function (newAxis, oldAxis) {        return this.getChart().getAxis(newAxis) || oldAxis;    },     updateXAxis: function (axis) {        axis.processData(this);    },     updateYAxis: function (axis) {        axis.processData(this);    },     coordinateX: function () {        return this.coordinate('X', 0, 2);    },     coordinateY: function () {        return this.coordinate('Y', 1, 2);    },     getItemForPoint: function (x, y) {        if (this.getSprites()) {            var me = this,                sprite = me.getSprites()[0],                store = me.getStore(),                item, index;             if (me.getHidden()) {                return null;            }            if (sprite) {                index = sprite.getIndexNearPoint(x, y);                if (index !== -1) {                    item = {                        series: me,                        category: me.getItemInstancing() ? 'items' : 'markers',                        index: index,                        record: store.getData().items[index],                        field: me.getYField(),                        sprite: sprite                    };                    return item;                }            }        }    },     createSprite: function () {        var me = this,            sprite = me.callParent(),            chart = me.getChart(),            xAxis = me.getXAxis();         sprite.setAttributes({            flipXY: chart.getFlipXY(),            xAxis: xAxis        });        if (sprite.setAggregator && xAxis && xAxis.getAggregator) {            if (xAxis.getAggregator) {                sprite.setAggregator({strategy: xAxis.getAggregator()});            } else {                sprite.setAggregator({});            }        }        return sprite;    },     getSprites: function () {        var me = this,            chart = this.getChart(),            animation = me.getAnimation() || chart && chart.getAnimation(),            itemInstancing = me.getItemInstancing(),            sprites = me.sprites,            sprite;         if (!chart) {            return [];        }         if (!sprites.length) {            sprite = me.createSprite();        } else {            sprite = sprites[0];        }         if (animation) {            if (itemInstancing) {                sprite.itemsMarker.getTemplate().setAnimation(animation);            }            sprite.setAnimation(animation);        }        return sprites;    },     provideLegendInfo: function (target) {        var me = this,            style = me.getSubStyleWithTheme(),            fill = style.fillStyle;         if (Ext.isArray(fill)) {            fill = fill[0];        }        target.push({            name: me.getTitle() || me.getYField() || me.getId(),            mark: (Ext.isObject(fill) ? fill.stops && fill.stops[0].color : fill) || style.strokeStyle || 'black',            disabled: me.getHidden(),            series: me.getId(),            index: 0        });    },     getXRange: function () {        return [this.dataRange[0], this.dataRange[2]];    },     getYRange: function () {        return [this.dataRange[1], this.dataRange[3]];    }});