Axis.js 5.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
define(function (require) {

    var linearMap = require('../util/number').linearMap;
    var zrUtil = require('zrender/core/util');

    function fixExtentWithBands(extent, nTick) {
        var size = extent[1] - extent[0];
        var len = nTick;
        var margin = size / len / 2;
        extent[0] += margin;
        extent[1] -= margin;
    }
    /**
     * @name module:echarts/coord/CartesianAxis
     * @constructor
     */
    var Axis = function (dim, scale, extent) {

        /**
         * Axis dimension. Such as 'x', 'y', 'z', 'angle', 'radius'
         * @type {string}
         */
        this.dim = dim;

        /**
         * Axis scale
         * @type {module:echarts/coord/scale/*}
         */
        this.scale = scale;

        /**
         * @type {Array.<number>}
         * @private
         */
L
lang 已提交
35
        this._extent = extent || [0, 0];
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

        /**
         * @type {boolean}
         */
        this.inverse = false;

        /**
         * Usually true when axis has a ordinal scale
         * @type {boolean}
         */
        this.onBand = false;
    };

    Axis.prototype = {

        constructor: Axis,

        /**
         * Get coord extent
         * @return {Array.<number>}
         */
        getExtent: function () {
            var ret = this._extent.slice();
            if (this.inverse) {
                ret.reverse();
            }
            return ret;
        },

        /**
         * Set coord extent
L
lang 已提交
67 68
         * @param {number} start
         * @param {number} end
69
         */
L
lang 已提交
70
        setExtent: function (start, end) {
71
            var extent = this._extent;
L
lang 已提交
72 73
            extent[0] = start;
            extent[1] = end;
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
        },

        /**
         * Map a data to extent. Data is the rank if it has a ordinal scale
         * @param {number} data
         * @param  {boolean} clamp
         * @return {number}
         */
        mapData: function (data, clamp) {
            // PENDING
            if (data == null || data === '-') {
                return NaN;
            }
            data = this.scale.normalize(data);

            var extent = this.getExtent();
L
lang 已提交
90
            if (this.onBand) {
L
lang 已提交
91
                fixExtentWithBands(extent, this.scale.count());
92 93 94 95 96 97 98 99 100 101 102 103 104 105
            }

            return linearMap(data, [0, 1], extent, clamp);
        },

        /**
         * Unmap a data. Data is the rank if it has a ordinal scale
         * @param {number} mapped
         * @param  {boolean} clamp
         * @return {number}
         */
        unmapData: function (mapped, clamp) {
            var extent = this.getExtent();

L
lang 已提交
106
            if (this.onBand) {
L
lang 已提交
107
                fixExtentWithBands(extent, this.scale.count());
108 109 110 111 112 113 114 115 116 117
            }

            var t = linearMap(mapped, extent, [0, 1], clamp);

            return this.scale.scale(t);
        },
        /**
         * @return {Array.<number>}
         */
        getTicksPositions: function () {
L
lang 已提交
118
            if (this.onBand) {
119
                var bands = this.getBands();
L
lang 已提交
120
                var positions = [];
121
                for (var i = 0; i < bands.length; i++) {
L
lang 已提交
122
                    positions.push(bands[i][0]);
123 124
                }
                if (bands[i - 1]) {
L
lang 已提交
125
                    positions.push(bands[i - 1][1]);
126
                }
L
lang 已提交
127
                return positions;
128 129
            }
            else {
L
lang 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
                return zrUtil.map(this.scale.getTicks(), this.mapData, this);
            }
        },

        /**
         * Positions of labels are on the ticks or on the middle of bands
         * @return {Array.<number>}
         */
        getLabelsPositions: function () {
            if (this.onBand) {
                var bands = this.getBands();
                var positions = [];
                var band;
                for (var i = 0; i < bands.length; i++) {
                    band = bands[i];
                    positions.push((band[0] + band[1]) / 2);
                }
                return positions;
            }
            else {
                return zrUtil.map(this.scale.getTicks(), this.mapData, this);
151 152 153 154 155 156 157 158 159 160 161 162 163
            }
        },

        /**
         * Get bands.
         * If axis has ticks [1, 2, 3, 4]. Bands on the axis are
         * |---1---|---2---|---3---|---4---|.
         *
         * @return {Array}
         */
        getBands: function () {
            var extent = this._extent;
            var bands = [];
164
            var len = this.scale.count();
165 166 167 168
            var start = extent[0];
            var end = extent[1];
            var size = end - start;

169
            for (var i = 0; i < len; i++) {
170
                bands.push([
171 172
                    size * i / len + start,
                    size * (i + 1) / len + start
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
                ]);
            }
            return bands;
        },

        /**
         * Get width of band
         * @return {number}
         */
        getBandWidth: function () {
            var axisExtent = this._extent;
            var extent = this.scale.getExtent();
            var len = extent[1] - extent[0] + 1;

            var size = axisExtent[1] - axisExtent[0];

            return Math.abs(size) / len;
        }
    };

    return Axis;
});