List.js 10.5 KB
Newer Older
L
lang 已提交
1 2
// TODO entry.getLon(), entry.getLat()
// List supported for cartesian, polar coordinateSystem
L
lang 已提交
3 4 5 6
define(function(require) {
    'use strict';

    var zrUtil = require('zrender/core/util');
L
lang 已提交
7
    var Model = require('../model/Model');
L
lang 已提交
8
    var DataDiffer = require('./DataDiffer');
L
lang 已提交
9 10 11 12 13 14 15 16

    function createArrayIterWithDepth(maxDepth, properties, cb, context, iterType) {
        // Simple optimization to avoid read the undefined value in properties array
        var nestedProperties = properties.length > 0;
        return function eachAxis(array, depth) {
            if (depth === maxDepth) {
                return zrUtil[iterType](array, cb, context);
            }
L
lang 已提交
17 18 19 20 21 22 23
            else if (array) {
                var property = properties[depth];
                for (var i = 0; i < array.length; i++) {
                    var item = array[i];
                    // Access property of each item
                    if (nestedProperties && property && item) {
                        item = item[property];
L
lang 已提交
24
                    }
L
lang 已提交
25
                    array[i] = eachAxis(item, depth);
L
lang 已提交
26 27
                }
            }
P
pah100 已提交
28
        };
L
lang 已提交
29
    }
P
pah100 已提交
30 31 32

    var dimensions = ['x', 'y', 'z', 'value', 'radius', 'angle'];

L
lang 已提交
33 34 35
    /**
     * @name echarts/data/List~Entry
     * @extends {module:echarts/model/Model}
36 37 38 39 40 41
     *
     * @param {Object} option
     * @param {module:echarts/model/Model} parentModel
     * @param {number} dataIndex
     * @param {Array.<string>} [independentVar=['x']]
     * @param {Array.<string>} [dependentVar='y']
L
lang 已提交
42
     */
L
lang 已提交
43 44 45 46
    var Entry = Model.extend({

        layout: null,

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
        /**
         * @type {number}
         * @protected
         */
        xIndex: 0,

        /**
         * @type {number}
         * @protected
         */
        yIndex: 1,

        /**
         * @type {number}
         * @protected
         */
        zIndex: -1,

L
lang 已提交
65 66 67 68 69 70 71 72 73 74 75 76
        /**
         * @type {number}
         * @protected
         */
        radiusIndex: 0,

        /**
         * @type {number}
         * @protected
         */
        angleIndex: 1,

77 78 79 80 81
        /**
         * @type {number}
         * @protected
         */
        valueIndex: 1,
L
lang 已提交
82

P
pah100 已提交
83
        init: function (option, parentModel, rawDataIndex, independentVar, dependentVar) {
L
lang 已提交
84 85 86 87 88 89

            /**
             * @type {string}
             * @memeberOf module:echarts/data/List~Entry
             * @public
             */
L
lang 已提交
90 91
            this.name = option.name || '';

P
pah100 已提交
92 93 94 95 96 97 98
            /**
             * this.option **MUST NOT** be modified in List!
             * Different lists might share this option instance.
             *
             * @readOnly
             * @type {*}
             */
L
lang 已提交
99
            this.option = option;
L
lang 已提交
100

101 102
            var value = option.value == null ? option : option.value;

L
lang 已提交
103 104 105 106 107
            if (value === '-' || value == null) {
                value = [rawDataIndex, null];
            }
            else if (!isNaN(value)) {
                value = [rawDataIndex, +value];
P
pah100 已提交
108 109 110 111 112 113 114 115
                /**
                 * If dataIndex is persistent in entry, it should be udpated when modifying list.
                 * So use this.dataIndexIndex to mark that.
                 *
                 * @readOnly
                 * @type {number}
                 */
                this.dataIndexIndex = 0;
116 117
            }

L
lang 已提交
118 119 120
            if (independentVar) {
                for (var i = 0; i < independentVar.length; i++) {
                    this[independentVar[i] + 'Index'] = i;
121 122 123
                }
                this.valueIndex = value.length - 1;

L
lang 已提交
124
                this[dependentVar + 'Index'] = this.valueIndex;
125 126
            }

L
lang 已提交
127
            /**
P
pah100 已提交
128 129 130 131
             * All of the content **MUST NOT** be modified,
             * (because they are the same instance with option.value)
             * except this._value[this.dataIndexIndex].
             *
132
             * @type {Array.<number>}
L
lang 已提交
133 134 135
             * @memeberOf module:echarts/data/List~Entry
             * @private
             */
136
            this._value = value;
L
lang 已提交
137

L
lang 已提交
138
            /**
P
pah100 已提交
139 140
             * Data index before modifying list (filterSelf).
             *
L
lang 已提交
141 142
             * @readOnly
             */
P
pah100 已提交
143
            this.rawDataIndex = rawDataIndex;
L
lang 已提交
144 145 146 147 148
        },

        /**
         * @return {number}
         */
149
        getStackedValue: function () {
L
lang 已提交
150 151 152 153 154 155

        },

        setDataIndex: function (index) {
            if (this.dataIndexIndex != null) {
                this._value[this.dataIndexIndex] = index;
L
lang 已提交
156
            }
L
lang 已提交
157 158 159
        },

        clone: function () {
L
lang 已提交
160
            var entry = new Entry(this.option, this.parentModel, this.rawDataIndex);
L
lang 已提交
161
            entry.name = this.name;
L
lang 已提交
162 163 164

            for (var i = 0; i < dimensions.length; i++) {
                var key = dimensions[i] + 'Index';
L
lang 已提交
165 166 167
                if (this.hasOwnProperty(key)) {
                    entry[key] = this[key];
                }
L
lang 已提交
168
            }
L
lang 已提交
169
            return entry;
L
lang 已提交
170 171 172
        }
    });

L
lang 已提交
173
    zrUtil.each(dimensions, function (dim) {
174 175 176 177 178 179 180
        var capitalized = dim[0].toUpperCase() + dim.substr(1);
        var indexKey = dim + 'Index';
        Entry.prototype['get' + capitalized] = function () {
            var index = this[indexKey];
            if (index >= 0) {
                return this._value[index];
            }
P
pah100 已提交
181
        };
182
    });
L
lang 已提交
183

184
    function List() {
P
pah100 已提交
185 186 187 188
        /**
         * @readOnly
         * @type {Array}
         */
L
lang 已提交
189
        this.elements = [];
L
lang 已提交
190 191 192 193 194 195
    }

    List.prototype = {

        constructor: List,

L
lang 已提交
196 197
        type: 'list',

P
pah100 已提交
198 199 200 201
        count: function () {
            return this.elements.length;
        },

L
lang 已提交
202
        each: function (cb, context) {
P
pah100 已提交
203
            zrUtil.each(this.elements, cb, context || this);
L
lang 已提交
204 205
        },

L
lang 已提交
206 207
        /**
         * Data mapping, returned array is flatten
208
         * PENDING
L
lang 已提交
209 210 211
         */
        map: function (cb, context) {
            var ret = [];
P
pah100 已提交
212
            context = context || this;
L
lang 已提交
213
            this.each(function (item, idx) {
P
pah100 已提交
214
                ret.push(cb && cb.call(context, item));
L
lang 已提交
215 216 217 218
            }, context);
            return ret;
        },

P
pah100 已提交
219 220
        filterSelf: function (cb, context) {
            this.elements = zrUtil.filter(this.elements, cb, context || this);
L
lang 已提交
221
            this.each(this._setEntryDataIndex);
P
pah100 已提交
222 223
        },

L
lang 已提交
224 225
        _setEntryDataIndex: function (entry, dataIndex) {
            entry.setDataIndex(dataIndex);
L
lang 已提交
226 227
        },

L
lang 已提交
228 229 230 231 232 233 234 235 236 237 238
        /**
         * @return {module:echarts/data/List~Entry}
         */
        getByName: function (name) {
            // TODO deep hierarchy
            var elements = this.elements;
            for (var i = 0; i < elements.length; i++) {
                if (elements[i].name === name) {
                    return elements[i];
                }
            }
L
lang 已提交
239 240
        },

L
lang 已提交
241 242 243 244 245 246 247 248 249 250 251 252
        /**
         * @param {string} name
         * @param {*} option
         */
        append: function (name, option) {
            var elements = this.elements;
            var el = new Entry(option, null, elements.length);
            el.name = name;
            elements.push(el);
            return el;
        },

L
lang 已提交
253 254 255 256
        diff: function (oldList) {
            return new DataDiffer(oldList ? oldList.elements : [], this.elements);
        },

L
lang 已提交
257
        clone: function () {
L
lang 已提交
258 259 260 261 262 263
            var list = new List();
            var elements = this.elements;
            for (var i = 0; i < elements.length; i++) {
                list.elements.push(elements[i].clone());
            }
            return list;
L
lang 已提交
264 265 266
        }
    };

L
lang 已提交
267
    zrUtil.each(['X', 'Y', 'Z', 'Value'], function (name) {
L
lang 已提交
268 269 270 271 272 273 274 275 276 277 278 279 280
        List.prototype['each' + name] = function (cb, context) {
            this.each(function (item, idx) {
                cb && cb.call(context || this, item['get' + name](idx));
            }, context);
        };

        List.prototype['map' + name] = function (cb, context) {
            var ret = [];
            this.each(function (item) {
                ret.push(cb && cb.call(context || this, item['get' + name]()));
            }, context);
            return ret;
        };
L
lang 已提交
281 282
    });

283
    List.fromArray = function (data, seriesModel, ecModel) {
L
lang 已提交
284
        var coordinateSystem = seriesModel.get('coordinateSystem');
285 286 287
        var independentVar;
        var dependentVar;

L
lang 已提交
288 289 290 291 292 293
        // FIXME
        // 这里 List 跟几个坐标系和坐标系 Model 耦合了
        if (coordinateSystem === 'cartesian2d') {
            var xAxisModel = ecModel.getComponent('xAxis', seriesModel.get('xAxisIndex'));
            var yAxisModel = ecModel.getComponent('yAxis', seriesModel.get('yAxisIndex'));
            if (xAxisModel.get('type') === 'category') {
L
lang 已提交
294 295 296
                independentVar = ['x'];
                dependentVar = 'y';
            }
L
lang 已提交
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
            else if (yAxisModel.get('type') === 'category') {
                independentVar = ['y'];
                dependentVar = 'x';
            }
            else {
                // PENDING
                var dim = data[0] && data[0].length;
                if (dim === 2) {
                    independentVar = ['x'];
                    dependentVar = 'y';
                }
                else if (dim === 3) {
                    independentVar = ['x', 'y'];
                    dependentVar = 'z';
                }
            }
        }
        else if (coordinateSystem === 'polar') {
L
lang 已提交
315
            var axisFinder = function (axisModel) {
L
lang 已提交
316
                return axisModel.get('polarIndex') === polarIndex;
P
pah100 已提交
317
            }
L
lang 已提交
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
            var polarIndex = seriesModel.get('polarIndex') || 0;
            var angleAxisModel = ecModel.findComponent('angleAxis', axisFinder);
            var radiusAxisModel = ecModel.findComponent('radiusAxis', axisFinder);

            if (angleAxisModel.get('type') === 'category') {
                independentVar = ['angle'];
                dependentVar = 'radius';
            }
            else if (radiusAxisModel.get('type') === 'category') {
                independentVar = ['radius'];
                dependentVar = 'angle';
            }
            else {
                var dim = data[0] && data[0].length;
                if (dim === 2) {
                    independentVar = ['radius'];
                    dependentVar = 'angle';
                }
                else if (dim === 3) {
                    independentVar = ['radius', 'angle'];
                    dependentVar = 'value';
                }
L
lang 已提交
340 341
            }
        }
342

L
lang 已提交
343
        var list = new List();
344

L
lang 已提交
345
        // Normalize data
L
lang 已提交
346
        list.elements = zrUtil.map(data, function (dataItem, index) {
347
            var entry = new Entry(dataItem, seriesModel, index, independentVar, dependentVar);
L
lang 已提交
348
            // FIXME
L
lang 已提交
349 350 351
            if (! dataItem.name) {
                entry.name = index;
            }
L
lang 已提交
352
            return entry;
L
lang 已提交
353 354
        });
        return list;
L
lang 已提交
355 356 357
    };

    List.Entry = Entry;
L
lang 已提交
358 359 360

    return List;
});