PiecewiseModel.js 9.9 KB
Newer Older
P
pah100 已提交
1 2
define(function(require) {

3
    var VisualMapModel = require('./VisualMapModel');
P
pah100 已提交
4
    var zrUtil = require('zrender/core/util');
P
pah100 已提交
5
    var VisualMapping = require('../../visual/VisualMapping');
P
pah100 已提交
6

P
pah100 已提交
7
    var PiecewiseModel = VisualMapModel.extend({
P
pah100 已提交
8

9
        type: 'visualMap.piecewise',
P
pah100 已提交
10

P
pah100 已提交
11 12 13
        /**
         * Order Rule:
         *
P
pah100 已提交
14
         * option.categories / option.pieces / option.text / option.selected:
P
pah100 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
         *     If !option.inverse,
         *     Order when vertical: ['top', ..., 'bottom'].
         *     Order when horizontal: ['left', ..., 'right'].
         *     If option.inverse, the meaning of
         *     the order should be reversed.
         *
         * this._pieceList:
         *     The order is always [low, ..., high].
         *
         * Mapping from location to low-high:
         *     If !option.inverse
         *     When vertical, top is high.
         *     When horizontal, right is high.
         *     If option.inverse, reverse.
         */

P
pah100 已提交
31 32 33 34
        /**
         * @protected
         */
        defaultOption: {
P
pah100 已提交
35 36 37 38 39 40
            selected: null,             // Object. If not specified, means selected.
                                        // When pieces and splitNumber: {'0': true, '5': true}
                                        // When categories: {'cate1': false, 'cate3': true}
            align: 'auto',              // 'auto', 'left', 'right'
            itemWidth: 20,              // 值域图形宽度
            itemHeight: 14,             // 值域图形高度
P
pah100 已提交
41
            itemSymbol: 'roundRect',
P
pah100 已提交
42 43 44 45
            pieceList: null,            // 值顺序:由高到低, item can be:
                                        // {min, max, value, color, colorSaturation, colorAlpha, symbol, symbolSize}
            categories: null,           // 描述 category 数据。如:['some1', 'some2', 'some3'],设置后,min max失效。
            splitNumber: 5,             // 分割段数,默认为5,为0时为线性渐变 (continous)
P
pah100 已提交
46
            selectedMode: 'multiple',
P
pah100 已提交
47 48
            itemGap: 10                 // 各个item之间的间隔,单位px,默认为10,
                                        // 横向布局时为水平间隔,纵向布局时为纵向间隔
P
pah100 已提交
49 50 51 52 53 54 55 56 57
        },

        /**
         * @override
         */
        mergeOption: function (newOption, isInit) {
            this.baseMergeOption(newOption);

            /**
P
pah100 已提交
58
             * The order is always [low, ..., high].
P
pah100 已提交
59 60 61 62 63 64 65 66 67
             * [{text: string, interval: Array.<number>}, ...]
             * @private
             * @type {Array.<Object>}
             */
            this._pieceList = [];

            this.resetTargetSeries(newOption, isInit);
            this.resetExtent();

P
pah100 已提交
68 69 70 71 72
            /**
             * 'pieces', 'categories', 'splitNumber'
             * @type {string}
             */
            var mode = this._mode = this._decideMode();
P
pah100 已提交
73

P
pah100 已提交
74
            resetMethods[this._mode].call(this);
P
pah100 已提交
75

P
pah100 已提交
76
            this._resetSelected(newOption, isInit);
P
pah100 已提交
77

P
pah100 已提交
78
            var categories = this.option.categories;
P
pah100 已提交
79
            this.resetVisual(function (mappingOption, state) {
P
pah100 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93
                if (mode === 'categories') {
                    mappingOption.mappingMethod = 'category';
                    mappingOption.categories = zrUtil.clone(categories);
                }
                else {
                    mappingOption.mappingMethod = 'piecewise';
                    mappingOption.pieceList = zrUtil.map(this._pieceList, function (piece) {
                        var piece = zrUtil.clone(piece);
                        if (state !== 'inRange') {
                            piece.visual = null;
                        }
                        return piece;
                    });
                }
P
pah100 已提交
94 95 96
            });
        },

P
pah100 已提交
97
        _resetSelected: function (newOption, isInit) {
P
pah100 已提交
98 99 100
            var thisOption = this.option;
            var pieceList = this._pieceList;

P
pah100 已提交
101 102 103 104 105 106 107 108 109
            // Selected do not merge but all override.
            var selected = (isInit ? thisOption : newOption).selected || {};
            thisOption.selected = selected;

            // Consider 'not specified' means true.
            zrUtil.each(pieceList, function (piece, index) {
                var key = this.getSelectedMapKey(piece);
                if (!(key in selected)) {
                    selected[key] = true;
P
pah100 已提交
110
                }
P
pah100 已提交
111
            }, this);
P
pah100 已提交
112

P
pah100 已提交
113
            if (thisOption.selectedMode === 'single') {
P
pah100 已提交
114 115
                // Ensure there is only one selected.
                var hasSel = false;
P
pah100 已提交
116

P
pah100 已提交
117
                zrUtil.each(pieceList, function (piece, index) {
P
pah100 已提交
118 119
                    var key = this.getSelectedMapKey(piece);
                    if (selected[key]) {
P
pah100 已提交
120
                        hasSel
P
pah100 已提交
121
                            ? (selected[key] = false)
P
pah100 已提交
122 123
                            : (hasSel = true);
                    }
P
pah100 已提交
124
                }, this);
P
pah100 已提交
125
            }
P
pah100 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
            // thisOption.selectedMode === 'multiple', default: all selected.
        },

        /**
         * @public
         */
        getSelectedMapKey: function (piece) {
            return this._mode === 'categories'
                ? piece.value + '' : piece.index + '';
        },

        /**
         * @public
         */
        getPieceList: function () {
            return this._pieceList;
        },

        /**
         * @private
         * @return {string}
         */
        _decideMode: function () {
            var option = this.option;

            return option.pieces && option.pieces.length > 0
                ? 'pieces'
                : this.option.categories
                ? 'categories'
                : 'splitNumber';
        },

        /**
         * @public
         * @override
         */
        setSelected: function (selected) {
            this.option.selected = zrUtil.clone(selected);
P
pah100 已提交
164 165
        },

P
pah100 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
        /**
         * @public
         * @override
         */
        getValueState: function (value) {
            var pieceList = this._pieceList;
            var index = VisualMapping.findPieceIndex(value, pieceList);

            return index != null
                ? (this.option.selected[this.getSelectedMapKey(pieceList[index])]
                    ? 'inRange' : 'outOfRange'
                )
                : 'outOfRange';
        }

    });

    /**
     * Key is this._mode
     * @type {Object}
     * @this {module:echarts/component/viusalMap/PiecewiseMode}
     */
    var resetMethods = {

        splitNumber: function () {
P
pah100 已提交
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
            var thisOption = this.option;
            var precision = thisOption.precision;
            var dataExtent = this.getExtent();
            var splitNumber = thisOption.splitNumber;
            splitNumber = Math.max(parseInt(splitNumber, 10), 1);
            thisOption.splitNumber = splitNumber;

            var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber;
            // Precision auto-adaption
            while (+splitStep.toFixed(precision) !== splitStep && precision < 5) {
                precision++;
            }
            thisOption.precision = precision;
            splitStep = +splitStep.toFixed(precision);

            for (var i = 0, curr = dataExtent[0]; i < splitNumber; i++, curr += splitStep) {
                var max = i === splitNumber - 1 ? dataExtent[1] : (curr + splitStep);

                this._pieceList.push({
P
pah100 已提交
210
                    text: this.formatValueText([curr, max]),
P
pah100 已提交
211
                    index: i,
P
pah100 已提交
212 213 214 215 216
                    interval: [curr, max]
                });
            }
        },

P
pah100 已提交
217
        categories: function () {
P
pah100 已提交
218 219 220 221
            var thisOption = this.option;
            zrUtil.each(thisOption.categories, function (cate) {
                // FIXME category模式也使用pieceList,但在visualMapping中不是使用pieceList。
                // 是否改一致。
P
pah100 已提交
222
                this._pieceList.push({
P
pah100 已提交
223
                    text: this.formatValueText(cate, true),
P
pah100 已提交
224 225 226
                    value: cate
                });
            }, this);
P
pah100 已提交
227 228

            // See "Order Rule".
P
pah100 已提交
229
            normalizeReverse(thisOption, this._pieceList);
P
pah100 已提交
230 231
        },

P
pah100 已提交
232
        pieces: function () {
P
pah100 已提交
233
            var thisOption = this.option;
P
pah100 已提交
234
            zrUtil.each(thisOption.pieces, function (pieceListItem, index) {
P
pah100 已提交
235

P
pah100 已提交
236 237
                if (!zrUtil.isObject(pieceListItem)) {
                    pieceListItem = {value: pieceListItem};
P
pah100 已提交
238 239
                }

P
pah100 已提交
240
                var item = {text: '', index: index};
P
pah100 已提交
241
                var hasLabel;
P
pah100 已提交
242

P
pah100 已提交
243 244
                if (pieceListItem.label != null) {
                    item.text = pieceListItem.label;
P
pah100 已提交
245
                    hasLabel = true;
P
pah100 已提交
246
                }
P
pah100 已提交
247

P
pah100 已提交
248 249
                if (pieceListItem.hasOwnProperty('value')) {
                    item.value = pieceListItem.value;
P
pah100 已提交
250 251 252 253

                    if (!hasLabel) {
                        item.text = this.formatValueText(item.value);
                    }
P
pah100 已提交
254 255
                }
                else {
P
pah100 已提交
256 257
                    var min = pieceListItem.min;
                    var max = pieceListItem.max;
P
pah100 已提交
258 259
                    min == null && (min = -Infinity);
                    max == null && (max = Infinity);
P
pah100 已提交
260 261 262 263 264
                    if (min === max) {
                        // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}],
                        // we use value to lift the priority when min === max
                        item.value = min;
                    }
P
pah100 已提交
265 266 267
                    item.interval = [min, max];

                    if (!hasLabel) {
P
pah100 已提交
268
                        item.text = this.formatValueText([min, max]);
P
pah100 已提交
269
                    }
P
pah100 已提交
270 271
                }

P
pah100 已提交
272
                item.visual = VisualMapping.retrieveVisuals(pieceListItem);
P
pah100 已提交
273 274

                this._pieceList.push(item);
P
pah100 已提交
275

P
pah100 已提交
276 277 278
            }, this);

            // See "Order Rule".
P
pah100 已提交
279
            normalizeReverse(thisOption, this._pieceList);
P
pah100 已提交
280
        }
P
pah100 已提交
281
    };
P
pah100 已提交
282

P
pah100 已提交
283 284 285 286 287 288
    function normalizeReverse(thisOption, arr) {
        var inverse = thisOption.inverse;
        if (thisOption.orient === 'vertical' ? !inverse : inverse) {
             arr.reverse();
        }
    }
P
pah100 已提交
289

P
pah100 已提交
290
    return PiecewiseModel;
P
pah100 已提交
291
});