PieView.js 8.8 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
    }

28 29 30 31 32 33 34 35
    /**
     * @param {module:zrender/graphic/Sector} el
     * @param {Object} layout
     * @param {boolean} isSelected
     * @param {number} selectedOffset
     * @inner
     */
    function toggleItemSelected(el, layout, isSelected, selectedOffset) {
L
lang 已提交
36
        var shape = el.shape;
L
lang 已提交
37
        var midAngle = (layout.startAngle + layout.endAngle) / 2;
L
lang 已提交
38 39 40 41

        var dx = Math.cos(midAngle);
        var dy = (shape.clockwise ? 1 : -1) * Math.sin(midAngle);

L
lang 已提交
42
        var offset = isSelected ? selectedOffset : 0;
L
lang 已提交
43 44 45 46 47 48 49 50 51

        // animateTo will stop revious animation like update transition
        el.animate()
            .when(200, {
                position: [dx * offset, dy * offset]
            })
            .start('bounceOut');
    }

52 53 54 55 56 57 58
    /**
     * 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 已提交
59 60 61 62 63 64 65 66 67 68 69 70
    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 已提交
71 72
            },
            silent: true
L
lang 已提交
73 74 75 76 77 78 79 80
        });

        var labelText = new graphic.Text({
            style: {
                text: text,
                textAlign: labelLayout.textAlign,
                textBaseline: labelLayout.textBaseline,
                font: labelLayout.font
L
lang 已提交
81 82 83 84
            },
            rotation: labelLayout.rotation,
            position: [labelLayout.x, labelLayout.y],
            silent: true
L
lang 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
        });

        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 已提交
102
    var Pie = require('../../view/Chart').extend({
L
lang 已提交
103

L
Add pie  
lang 已提交
104
        type: 'pie',
L
lang 已提交
105

L
lang 已提交
106 107 108 109 110
        init: function () {
            var sectorGroup = new graphic.Group();
            this._sectorGroup = sectorGroup;
        },

L
lang 已提交
111
        render: function (seriesModel, ecModel, api) {
L
Add pie  
lang 已提交
112 113
            var data = seriesModel.getData();
            var oldData = this._data;
L
lang 已提交
114
            var sectorGroup = this._sectorGroup;
L
Add pie  
lang 已提交
115
            var group = this.group;
L
lang 已提交
116 117 118 119 120

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

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

L
lang 已提交
123 124
            var selectedMode = seriesModel.get('selectedMode');

L
Add pie  
lang 已提交
125 126
            data.diff(oldData)
                .add(function (idx) {
L
lang 已提交
127
                    var layout = data.getItemLayout(idx);
L
Add pie  
lang 已提交
128

L
lang 已提交
129
                    var sector = createSectorAndLabel(
L
lang 已提交
130
                        layout, '', hasAnimation && !isFirstRender
L
lang 已提交
131
                    );
L
lang 已提交
132

L
lang 已提交
133 134
                    selectedMode
                        && sector.on('click', onSectorClick);
L
lang 已提交
135 136

                    data.setItemGraphicEl(idx, sector);
L
lang 已提交
137 138 139 140 141

                    sectorGroup.add(sector);

                    group.add(sector.__labelLine);
                    group.add(sector.__labelText);
L
lang 已提交
142 143

                    firstSector = firstSector || sector;
L
Add pie  
lang 已提交
144 145 146
                })
                .update(function (newIdx, oldIdx) {
                    var sector = oldData.getItemGraphicEl(oldIdx);
L
lang 已提交
147 148 149
                    var layout = data.getItemLayout(newIdx);
                    var labelLayout = layout.label;

L
lang 已提交
150 151 152 153 154 155
                    var labelLine = sector.__labelLine;
                    var labelText = sector.__labelText;

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

L
lang 已提交
157 158 159 160 161 162 163 164
                    api.updateGraphicEl(sector, {
                        shape: layout
                    });
                    labelLine && api.updateGraphicEl(labelLine, {
                        shape: {
                            points: labelLayout.linePoints
                        }
                    });
L
lang 已提交
165
                    if (labelText) {
L
lang 已提交
166
                        api.updateGraphicEl(labelText, {
L
lang 已提交
167 168
                            position: [labelLayout.x, labelLayout.y],
                            rotation: labelLayout.rotation
L
lang 已提交
169 170 171 172 173 174
                        });
                        labelText.setStyle({
                            textAlign: labelLayout.textAlign,
                            textBaseline: labelLayout.textBaseline,
                            font: labelLayout.font
                        });
L
lang 已提交
175
                    }
L
lang 已提交
176 177

                    sectorGroup.add(sector);
L
lang 已提交
178
                    data.setItemGraphicEl(newIdx, sector);
L
lang 已提交
179 180 181

                    group.add(labelLine);
                    group.add(labelText);
L
Add pie  
lang 已提交
182 183 184
                })
                .remove(function (idx) {
                    var sector = oldData.getItemGraphicEl(idx);
L
lang 已提交
185 186 187 188
                    sectorGroup.remove(sector);

                    group.remove(sector.__labelLine);
                    group.remove(sector.__labelText);
L
Add pie  
lang 已提交
189 190 191
                })
                .execute();

L
lang 已提交
192 193 194 195
            if (hasAnimation && isFirstRender && firstSector) {
                var shape = firstSector.shape;
                var r = Math.max(api.getWidth(), api.getHeight()) / 2;

L
lang 已提交
196 197
                var removeClipPath = zrUtil.bind(sectorGroup.removeClipPath, sectorGroup);
                sectorGroup.setClipPath(this._createClipPath(
L
lang 已提交
198 199 200 201
                    shape.cx, shape.cy, r, shape.startAngle, shape.clockwise, removeClipPath
                ));
            }

L
lang 已提交
202 203 204 205
            // Make sure sectors is on top of labels
            group.remove(sectorGroup);
            group.add(sectorGroup);

L
lang 已提交
206 207 208 209 210 211
            this._updateAll(data, seriesModel);

            this._data = data;
        },

        _updateAll: function (data, seriesModel) {
L
lang 已提交
212
            var selectedOffset = seriesModel.get('selectedOffset');
L
Add pie  
lang 已提交
213 214
            data.eachItemGraphicEl(function (sector, idx) {
                var itemModel = data.getItemModel(idx);
L
lang 已提交
215
                var itemStyleModel = itemModel.getModel('itemStyle');
L
lang 已提交
216

L
Add pie  
lang 已提交
217 218 219 220 221
                sector.setStyle(
                    zrUtil.extend(
                        {
                            fill: data.getItemVisual(idx, 'color')
                        },
L
lang 已提交
222
                        itemStyleModel.getModel('normal').getItemStyle()
L
Add pie  
lang 已提交
223 224 225 226
                    )
                );
                graphic.setHoverStyle(
                    sector,
L
lang 已提交
227
                    itemStyleModel.getModel('emphasis').getItemStyle()
L
Add pie  
lang 已提交
228
                );
L
lang 已提交
229

L
lang 已提交
230
                var labelText = sector.__labelText;
L
lang 已提交
231
                var labelLine = sector.__labelLine;
L
lang 已提交
232 233 234 235 236 237
                if (labelText) {
                    labelText.setStyle({
                        text: seriesModel.getFormattedLabel(idx, 'normal')
                            || data.getName(idx)
                    });
                }
L
lang 已提交
238 239 240
                if (labelLine) {
                    labelLine.setStyle(itemModel.getModel('labelLine').getLineStyle());
                }
L
lang 已提交
241

242
                toggleItemSelected(
L
lang 已提交
243 244 245 246 247
                    sector,
                    data.getItemLayout(idx),
                    itemModel.get('selected'),
                    selectedOffset
                );
L
lang 已提交
248 249 250 251 252 253 254 255 256 257 258 259 260 261
            });
        },

        _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 已提交
262
            });
L
lang 已提交
263 264 265 266 267 268 269 270

            clipPath.animateTo({
                shape: {
                    endAngle: startAngle + Math.PI * 2
                }
            }, 1000, 'cubicOut', cb);

            return clipPath;
L
lang 已提交
271 272 273 274 275 276 277
        },

        dispose: function () {}
    });

    return Pie;
});