DataSymbol.js 8.5 KB
Newer Older
L
lang 已提交
1 2 3
define(function (require) {

    var zrUtil = require('zrender/core/util');
L
lang 已提交
4
    var symbolUtil = require('../../util/symbol');
L
lang 已提交
5
    var graphic = require('../../util/graphic');
L
lang 已提交
6

L
lang 已提交
7 8 9 10 11 12 13
    function normalizeSymbolSize(symbolSize) {
        if (!zrUtil.isArray(symbolSize)) {
            symbolSize = [+symbolSize, +symbolSize];
        }
        return symbolSize;
    }

L
lang 已提交
14 15 16 17 18 19 20 21
    function isAroundEqual(a, b) {
        return Math.abs(a - b) < 1e-4;
    }

    function isSymbolSizeSame(a, b) {
        return isAroundEqual(a[0], b[0]) && isAroundEqual(a[1], b[1]);
    }

L
lang 已提交
22
    function createSymbol(data, idx, enableAnimation) {
L
lang 已提交
23
        var point = data.getItemLayout(idx);
L
lang 已提交
24
        var color = data.getItemVisual(idx, 'color');
L
lang 已提交
25

L
lang 已提交
26 27
        var symbolSize = data.getItemVisual(idx, 'symbolSize');
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
L
lang 已提交
28

L
lang 已提交
29 30 31 32
        if (!symbolType || symbolType === 'none') {
            return;
        }

L
lang 已提交
33 34
        symbolSize = normalizeSymbolSize(symbolSize);

L
lang 已提交
35 36 37 38 39
        var x = -symbolSize[0] / 2;
        var y = -symbolSize[1] / 2;
        var w = symbolSize[0];
        var h = symbolSize[1];
        var symbolEl = symbolUtil.createSymbol(
L
lang 已提交
40
            symbolType, x, y, w, h, color
L
lang 已提交
41 42
        );

L
lang 已提交
43 44 45
        var symbolElPos = symbolEl.position;
        symbolElPos[0] = point[0];
        symbolElPos[1] = point[1];
L
lang 已提交
46

L
lang 已提交
47 48
        symbolEl.z2 = 100;

L
lang 已提交
49 50
        if (enableAnimation) {

L
lang 已提交
51
            symbolEl.scale = [0, 0];
L
lang 已提交
52 53

            symbolEl.animateTo({
L
lang 已提交
54
                scale: [1, 1]
L
lang 已提交
55 56 57
            }, 500);
        }
        else {
L
lang 已提交
58
            symbolEl.scale = [1, 1];
L
lang 已提交
59 60 61 62 63
        }

        return symbolEl;
    }

L
lang 已提交
64
    function DataSymbol() {
L
lang 已提交
65
        this.group = new graphic.Group();
L
lang 已提交
66 67 68 69 70 71 72 73
    }

    DataSymbol.prototype = {

        getData: function () {
            return this._data;
        },

L
lang 已提交
74 75 76 77 78 79 80 81 82
        /**
         * @param {module:echarts/data/List} data
         * @param {module:echarts/model/Series} seriesModel
         * @param {boolean} enableAnimation
         * @param {Array.<boolean>} [ignoreMap]
         */
        updateData: function (
            data, seriesModel, enableAnimation, ignoreMap
        ) {
L
lang 已提交
83 84

            var group = this.group;
L
lang 已提交
85
            var oldData = this._data;
L
lang 已提交
86

L
lang 已提交
87 88
            data.diff(oldData)
                .add(function (newIdx) {
L
lang 已提交
89 90
                    // 空数据
                    // TODO
L
lang 已提交
91
                    if (!data.hasValue(newIdx)) {
92 93
                        return;
                    }
L
lang 已提交
94

L
lang 已提交
95 96 97 98
                    if (!(ignoreMap && ignoreMap[newIdx])) {
                        var symbolEl = createSymbol(
                            data, newIdx, enableAnimation
                        );
L
lang 已提交
99

L
lang 已提交
100 101
                        if (symbolEl) {
                            data.setItemGraphicEl(newIdx, symbolEl);
L
lang 已提交
102

L
lang 已提交
103 104
                            group.add(symbolEl);
                        }
L
lang 已提交
105
                    }
L
lang 已提交
106
                })
L
lang 已提交
107
                .update(function (newIdx, oldIdx) {
L
lang 已提交
108
                    var el = oldData.getItemGraphicEl(oldIdx);
109
                    // Empty data
L
lang 已提交
110 111 112
                    if (!data.hasValue(newIdx)
                        || (ignoreMap && ignoreMap[newIdx])
                    ) {
113
                        group.remove(el);
114 115
                        return;
                    }
L
lang 已提交
116

L
lang 已提交
117 118 119
                    var symbolSize = normalizeSymbolSize(
                        data.getItemVisual(newIdx, 'symbolSize')
                    );
L
lang 已提交
120
                    var point = data.getItemLayout(newIdx);
L
lang 已提交
121

L
lang 已提交
122
                    var symbolType = data.getItemVisual(newIdx, 'symbol');
123
                    // Symbol changed
L
lang 已提交
124 125 126 127
                    if (
                        oldData.getItemVisual(oldIdx, 'symbol') !== symbolType
                        || (!el && !(ignoreMap && ignoreMap[newIdx]))
                    ) {
128
                        // Remove the old one
L
lang 已提交
129
                        el && group.remove(el);
130
                        el = createSymbol(data, newIdx, enableAnimation);
L
lang 已提交
131 132 133 134
                        // Disable symbol by setting `symbol: 'none'`
                        if (!el) {
                            return;
                        }
L
lang 已提交
135 136
                    }
                    else {
137 138 139 140
                        // Update animation
                        if (!el) {
                            return;
                        }
L
lang 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
                        var newTarget = {};
                        if (!isSymbolSizeSame(
                            symbolSize, normalizeSymbolSize(
                                oldData.getItemVisual(oldIdx, 'symbolSize')
                            )
                        )) {
                            // FIXME symbol created with pathStr has symbolSizeChanged
                            newTarget = symbolUtil.getSymbolShape(
                                symbolType,
                                -symbolSize[0] / 2, -symbolSize[1] / 2,
                                symbolSize[0], symbolSize[1]
                            ) || {};
                        }

                        // TODO Merge animateTo and attr methods into one
L
lang 已提交
156
                        newTarget.position = point;
L
lang 已提交
157 158 159 160 161 162 163
                        if (!isAroundEqual(el.scale[0], 1)) {    // May have scale 0
                            newTarget.scale = [1, 1];
                        }
                        if (enableAnimation) {
                            el.animateTo(newTarget, 300, 'cubicOut');
                        }
                        else {
L
lang 已提交
164
                            newTarget.position = point.slice();
L
lang 已提交
165 166 167 168
                            // May still have animation. Must stop
                            el.stopAnimation();
                            el.attr(newTarget);
                        }
L
lang 已提交
169 170
                    }

L
lang 已提交
171
                    data.setItemGraphicEl(newIdx, el);
L
lang 已提交
172 173 174 175

                    // Add back
                    group.add(el);
                })
L
lang 已提交
176 177 178 179 180 181
                .remove(function (oldIdx) {
                    var el = oldData.getItemGraphicEl(oldIdx);
                    if (enableAnimation) {
                        el.animateTo({
                            scale: [0, 0]
                        }, 200, 'cubicOut', function () {
182
                            group.remove(el);
L
lang 已提交
183 184 185
                        });
                    }
                    else {
186
                        // console.log(oldIdx);
L
lang 已提交
187
                        group.remove(el);
L
lang 已提交
188 189 190 191 192
                    }
                })
                .execute();

            // Update common properties
L
lang 已提交
193 194
            var normalStyleAccessPath = ['itemStyle', 'normal'];
            var emphasisStyleAccessPath = [normalStyleAccessPath[0], 'emphasis'];
L
lang 已提交
195
            data.eachItemGraphicEl(function (el, idx) {
L
lang 已提交
196
                var itemModel = data.getItemModel(idx);
L
lang 已提交
197
                var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
198
                var labelModel = itemModel.getModel('label.normal');
L
lang 已提交
199 200
                var color = data.getItemVisual(idx, 'color');

L
lang 已提交
201 202
                el.setColor(color);

L
lang 已提交
203 204
                zrUtil.extend(
                    el.style,
L
lang 已提交
205
                    normalItemStyleModel.getItemStyle(['color'])
L
lang 已提交
206
                );
L
lang 已提交
207

L
lang 已提交
208 209 210 211 212 213 214
                if (labelModel.get('show')) {
                    var labelPosition = labelModel.get('position') || 'inside';
                    var labelColor = labelPosition === 'inside' ? 'white' : color;
                    // Text use the value of last dimension
                    var lastDim = data.dimensions[data.dimensions.length - 1];
                    el.setStyle({
                        // FIXME
L
lang 已提交
215 216
                        text: seriesModel.getFormattedLabel(idx, 'normal')
                            || data.get(lastDim, idx),
L
lang 已提交
217
                        textFont: labelModel.getModel('textStyle').getFont(),
218
                        textPosition: labelPosition,
L
lang 已提交
219 220 221 222
                        textFill: labelColor
                    });
                }

L
lang 已提交
223 224
                graphic.setHoverStyle(
                    el,
L
lang 已提交
225
                    itemModel.getModel(emphasisStyleAccessPath).getItemStyle()
L
lang 已提交
226
                );
L
lang 已提交
227
            }, this);
L
lang 已提交
228 229 230 231

            this._data = data;
        },

L
lang 已提交
232
        remove: function (enableAnimation) {
L
lang 已提交
233 234
            if (this._data) {
                var group = this.group;
L
lang 已提交
235 236 237 238 239 240 241
                if (enableAnimation) {
                    this._data.eachItemGraphicEl(function (el) {
                        el.animateTo({
                            scale: [0, 0]
                        }, 200, 'cubicOut', function () {
                            group.remove(el);
                        });
L
lang 已提交
242
                    });
L
lang 已提交
243 244 245 246
                }
                else {
                    group.removeAll();
                }
L
lang 已提交
247 248 249 250 251 252
            }
        }
    }

    return DataSymbol;
});