PieView.js 9.7 KB
Newer Older
L
lang 已提交
1 2
define(function (require) {

L
Add pie  
lang 已提交
3 4
    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');
L
lang 已提交
5

6 7 8 9 10
    /**
     * @param {module:echarts/model/Series} seriesModel
     * @inner
     */
    function updateDataSelected(seriesModel) {
L
lang 已提交
11 12 13
        var data = seriesModel.getData();
        var dataIndex = this.dataIndex;
        var name = data.getName(dataIndex);
L
lang 已提交
14
        var selectedOffset = seriesModel.get('selectedOffset');
L
lang 已提交
15

L
lang 已提交
16 17 18
        seriesModel.toggleSelected(name);

        data.each(function (idx) {
19
            toggleItemSelected(
L
lang 已提交
20 21 22 23 24 25
                data.getItemGraphicEl(idx),
                data.getItemLayout(idx),
                seriesModel.isSelected(data.getName(idx)),
                selectedOffset
            );
        });
L
lang 已提交
26 27
    }

L
lang 已提交
28 29 30 31 32 33 34 35
    function selectAnimate(el, pos) {
        // animateTo will stop revious animation like update transition
        el.animate()
            .when(200, {
                position: pos
            })
            .start('bounceOut');
    }
36 37 38 39 40 41 42 43
    /**
     * @param {module:zrender/graphic/Sector} el
     * @param {Object} layout
     * @param {boolean} isSelected
     * @param {number} selectedOffset
     * @inner
     */
    function toggleItemSelected(el, layout, isSelected, selectedOffset) {
L
lang 已提交
44
        var midAngle = (layout.startAngle + layout.endAngle) / 2;
L
lang 已提交
45 46

        var dx = Math.cos(midAngle);
L
lang 已提交
47
        var dy = Math.sin(midAngle);
L
lang 已提交
48

L
lang 已提交
49
        var offset = isSelected ? selectedOffset : 0;
L
lang 已提交
50

L
lang 已提交
51 52 53 54
        var position = [dx * offset, dy * offset];
        selectAnimate(el, position);
        selectAnimate(el.__labelLine, position);
        selectAnimate(el.__labelText, position);
L
lang 已提交
55 56
    }

57 58 59 60 61 62 63
    /**
     * Create sector, label, and label line for each data
     * @param {Object} layout
     * @param {string} text
     * @param {boolean} hasAnimations
     * @return {module:zrender/graphic/Sector}
     */
L
lang 已提交
64 65 66 67 68 69 70 71 72 73 74 75
    function createSectorAndLabel(layout, text, hasAnimation) {
        var shape = zrUtil.extend({}, layout);
        delete shape.label;

        var sector = new graphic.Sector({
            shape: shape
        });

        var labelLayout = layout.label;
        var labelLine = new graphic.Polyline({
            shape: {
                points: labelLayout.linePoints
L
lang 已提交
76 77
            },
            silent: true
L
lang 已提交
78 79 80 81
        });

        var labelText = new graphic.Text({
            style: {
L
lang 已提交
82 83
                x: labelLayout.x,
                y: labelLayout.y,
L
lang 已提交
84 85 86
                text: text,
                textAlign: labelLayout.textAlign,
                textBaseline: labelLayout.textBaseline,
L
lang 已提交
87
                textFont: labelLayout.font
L
lang 已提交
88 89
            },
            rotation: labelLayout.rotation,
L
lang 已提交
90 91 92
            origin: [labelLayout.x, labelLayout.y],
            silent: true,
            z2: 10
L
lang 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
        });

        sector.__labelLine = labelLine;
        sector.__labelText = labelText;

        if (hasAnimation) {
            sector.shape.endAngle = layout.startAngle;
            sector.animateTo({
                shape: {
                    endAngle: layout.endAngle
                }
            }, 300, 'cubicOut');
        }

        return sector;
    }

L
Add pie  
lang 已提交
110
    var Pie = require('../../view/Chart').extend({
L
lang 已提交
111

L
Add pie  
lang 已提交
112
        type: 'pie',
L
lang 已提交
113

L
lang 已提交
114 115 116 117 118
        init: function () {
            var sectorGroup = new graphic.Group();
            this._sectorGroup = sectorGroup;
        },

L
lang 已提交
119
        render: function (seriesModel, ecModel, api) {
L
Add pie  
lang 已提交
120 121
            var data = seriesModel.getData();
            var oldData = this._data;
L
lang 已提交
122
            var sectorGroup = this._sectorGroup;
L
Add pie  
lang 已提交
123
            var group = this.group;
L
lang 已提交
124 125 126 127 128

            var hasAnimation = ecModel.get('animation');
            var isFirstRender = !oldData;

            var firstSector;
129
            var onSectorClick = zrUtil.curry(updateDataSelected, seriesModel);
L
lang 已提交
130

L
lang 已提交
131 132
            var selectedMode = seriesModel.get('selectedMode');

L
Add pie  
lang 已提交
133 134
            data.diff(oldData)
                .add(function (idx) {
L
lang 已提交
135
                    var layout = data.getItemLayout(idx);
L
Add pie  
lang 已提交
136

L
lang 已提交
137
                    var sector = createSectorAndLabel(
L
lang 已提交
138
                        layout, '', hasAnimation && !isFirstRender
L
lang 已提交
139
                    );
L
lang 已提交
140

L
lang 已提交
141 142
                    selectedMode
                        && sector.on('click', onSectorClick);
L
lang 已提交
143 144

                    data.setItemGraphicEl(idx, sector);
L
lang 已提交
145 146 147 148 149

                    sectorGroup.add(sector);

                    group.add(sector.__labelLine);
                    group.add(sector.__labelText);
L
lang 已提交
150 151

                    firstSector = firstSector || sector;
L
Add pie  
lang 已提交
152 153 154
                })
                .update(function (newIdx, oldIdx) {
                    var sector = oldData.getItemGraphicEl(oldIdx);
L
lang 已提交
155

L
lang 已提交
156 157 158
                    var layout = data.getItemLayout(newIdx);
                    var labelLayout = layout.label;

L
lang 已提交
159 160 161 162 163 164
                    var labelLine = sector.__labelLine;
                    var labelText = sector.__labelText;

                    selectedMode
                        ? sector.on('click', onSectorClick)
                        : sector.off('click');
L
lang 已提交
165

L
lang 已提交
166 167 168
                    api.updateGraphicEl(sector, {
                        shape: layout
                    });
L
lang 已提交
169
                    api.updateGraphicEl(labelLine, {
L
lang 已提交
170 171 172 173
                        shape: {
                            points: labelLayout.linePoints
                        }
                    });
L
lang 已提交
174 175 176 177 178 179 180 181 182 183 184 185
                    api.updateGraphicEl(labelText, {
                        style: {
                            x: labelLayout.x,
                            y: labelLayout.y
                        },
                        rotation: labelLayout.rotation
                    });

                    // Set none animating style
                    labelText.setStyle({
                        textAlign: labelLayout.textAlign,
                        textBaseline: labelLayout.textBaseline,
L
lang 已提交
186
                        textFont: labelLayout.font
L
lang 已提交
187
                    });
L
lang 已提交
188 189

                    sectorGroup.add(sector);
L
lang 已提交
190
                    data.setItemGraphicEl(newIdx, sector);
L
lang 已提交
191 192 193

                    group.add(labelLine);
                    group.add(labelText);
L
Add pie  
lang 已提交
194 195 196
                })
                .remove(function (idx) {
                    var sector = oldData.getItemGraphicEl(idx);
L
lang 已提交
197 198 199 200
                    sectorGroup.remove(sector);

                    group.remove(sector.__labelLine);
                    group.remove(sector.__labelText);
L
Add pie  
lang 已提交
201 202 203
                })
                .execute();

L
lang 已提交
204 205 206 207
            if (hasAnimation && isFirstRender && firstSector) {
                var shape = firstSector.shape;
                var r = Math.max(api.getWidth(), api.getHeight()) / 2;

L
lang 已提交
208 209
                var removeClipPath = zrUtil.bind(sectorGroup.removeClipPath, sectorGroup);
                sectorGroup.setClipPath(this._createClipPath(
L
lang 已提交
210 211 212 213
                    shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath
                ));
            }

L
lang 已提交
214 215 216 217
            // Make sure sectors is on top of labels
            group.remove(sectorGroup);
            group.add(sectorGroup);

L
lang 已提交
218 219 220 221 222 223
            this._updateAll(data, seriesModel);

            this._data = data;
        },

        _updateAll: function (data, seriesModel) {
L
lang 已提交
224
            var selectedOffset = seriesModel.get('selectedOffset');
L
Add pie  
lang 已提交
225 226
            data.eachItemGraphicEl(function (sector, idx) {
                var itemModel = data.getItemModel(idx);
L
lang 已提交
227
                var itemStyleModel = itemModel.getModel('itemStyle');
L
lang 已提交
228
                var visualColor = data.getItemVisual(idx, 'color');
L
lang 已提交
229

L
Add pie  
lang 已提交
230 231 232
                sector.setStyle(
                    zrUtil.extend(
                        {
L
lang 已提交
233
                            fill: visualColor
L
Add pie  
lang 已提交
234
                        },
L
lang 已提交
235
                        itemStyleModel.getModel('normal').getItemStyle()
L
Add pie  
lang 已提交
236 237 238 239
                    )
                );
                graphic.setHoverStyle(
                    sector,
L
lang 已提交
240
                    itemStyleModel.getModel('emphasis').getItemStyle()
L
Add pie  
lang 已提交
241
                );
L
lang 已提交
242

L
lang 已提交
243
                // Set label style
L
lang 已提交
244
                var labelText = sector.__labelText;
L
lang 已提交
245
                var labelLine = sector.__labelLine;
L
lang 已提交
246 247 248 249 250 251 252 253 254
                var labelModel = itemModel.getModel('label.normal');
                var textStyleModel = labelModel.getModel('textStyle');
                var labelPosition = labelModel.get('position');
                var isLabelInside = labelPosition === 'inside';
                labelText.setStyle({
                    fill: textStyleModel.get('color')
                        || isLabelInside ? '#fff' : visualColor,
                    text: seriesModel.getFormattedLabel(idx, 'normal')
                        || data.getName(idx),
L
lang 已提交
255
                    textFont: textStyleModel.getFont()
L
lang 已提交
256 257 258 259 260 261 262
                });
                // Default use item visual color
                labelLine.attr('ignore', !itemModel.get('labelLine.show'));
                labelLine.setStyle({
                    stroke: visualColor
                });
                labelLine.setStyle(itemModel.getModel('labelLine').getLineStyle());
L
lang 已提交
263

264
                toggleItemSelected(
L
lang 已提交
265 266 267 268 269
                    sector,
                    data.getItemLayout(idx),
                    itemModel.get('selected'),
                    selectedOffset
                );
L
lang 已提交
270 271 272 273 274 275 276 277 278 279 280 281 282 283
            });
        },

        _createClipPath: function (cx, cy, r, startAngle, clockwise, cb) {
            var clipPath = new graphic.Sector({
                shape: {
                    cx: cx,
                    cy: cy,
                    r0: 0,
                    r: r,
                    startAngle: startAngle,
                    endAngle: startAngle,
                    clockwise: clockwise
                }
L
Add pie  
lang 已提交
284
            });
L
lang 已提交
285 286 287

            clipPath.animateTo({
                shape: {
L
lang 已提交
288
                    endAngle: startAngle + (clockwise ? 1 : -1) * Math.PI * 2
L
lang 已提交
289 290 291 292
                }
            }, 1000, 'cubicOut', cb);

            return clipPath;
L
lang 已提交
293 294 295 296 297 298 299
        },

        dispose: function () {}
    });

    return Pie;
});