TreeView.js 11.6 KB
Newer Older
D
deqingli 已提交
1 2 3 4 5 6 7 8
/**
 * @file  This file used to draw tree view
 */

define(function (require) {

    var graphic = require('../../util/graphic');
    var zrUtil = require('zrender/core/util');
D
deqingli 已提交
9 10 11 12
    var Symbol = require('../helper/Symbol');
    var layoutHelper = require('./layoutHelper');
    var radialCoordinate = layoutHelper.radialCoordinate;

D
deqingli 已提交
13 14 15 16
    return require('../../echarts').extendChartView({

        type: 'tree',

D
deqingli 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
        /**
         * Init the chart
         * @override
         * @param  {module:echarts/model/Global} ecModel
         * @param  {module:echarts/ExtensionAPI} api
         */
        init: function (ecModel, api) {

            /**
             * @private
             * @type {module:echarts/data/Tree}
             */
            this._oldTree;

            /**
             * @private
             * @type {module:zrender/container/Group}
             */
            this._mainGroup = new graphic.Group();

            this.group.add(this._mainGroup);
        },

        render: function (seriesModel, ecModel, api, payload) {

            var data = seriesModel.getData();
D
deqingli 已提交
43 44 45

            var layoutInfo = seriesModel.layoutInfo;

D
deqingli 已提交
46 47
            var group = this._mainGroup;

D
deqingli 已提交
48 49
            group.position = [layoutInfo.x, layoutInfo.y];

D
deqingli 已提交
50 51 52
            var oldData = this._data;

            var seriesScope = {
D
deqingli 已提交
53
                expandAndCollapse: seriesModel.get('expandAndCollapse'),
D
deqingli 已提交
54 55 56 57 58 59
                layout: seriesModel.get('layout'),
                orient: seriesModel.get('orient'),
                curvature: seriesModel.get('lineStyle.normal.curveness'),
                symbolRotate: seriesModel.get('symbolRotate'),
                symbolOffset: seriesModel.get('symbolOffset'),
                hoverAnimation: seriesModel.get('hoverAnimation'),
S
sushuang 已提交
60 61
                useNameLabel: true,
                fadeIn: true
D
deqingli 已提交
62
            };
D
deqingli 已提交
63

D
deqingli 已提交
64 65 66 67 68
            data.diff(oldData)
                .add(function (newIdx) {
                    if (symbolNeedsDraw(data, newIdx)) {
                        // create node and edge
                        updateNode(data, newIdx, null, group, seriesModel, seriesScope);
D
deqingli 已提交
69
                    }
D
deqingli 已提交
70 71 72 73 74 75
                })
                .update(function (newIdx, oldIdx) {
                    var symbolEl = oldData.getItemGraphicEl(oldIdx);
                    if (!symbolNeedsDraw(data, newIdx)) {
                        symbolEl && removeNode(data, newIdx, symbolEl, group, seriesModel, seriesScope);
                        return;
D
deqingli 已提交
76
                    }
D
deqingli 已提交
77 78 79 80 81 82 83 84 85 86 87
                    // update  node and edge
                    updateNode(data, newIdx, symbolEl, group, seriesModel, seriesScope);
                })
                .remove(function (oldIdx) {
                    var symbolEl = oldData.getItemGraphicEl(oldIdx);
                    removeNode(data, oldIdx, symbolEl, group, seriesModel, seriesScope);
                })
                .execute();

            // TODO
            // view.remove ...
D
deqingli 已提交
88 89 90 91 92 93 94 95
            if (seriesScope.expandAndCollapse === true) {
                data.eachItemGraphicEl(function (el, dataIndex) {
                    el.off('click').on('click', function () {
                        api.dispatchAction({
                            type: 'treeExpandAndCollapse',
                            seriesId: seriesModel.id,
                            dataIndex: dataIndex
                        });
D
deqingli 已提交
96
                    });
D
deqingli 已提交
97
                });
D
deqingli 已提交
98
            }
D
deqingli 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

            this._data = data;
        },

        dispose: function () {}

    });

    function symbolNeedsDraw(data, dataIndex) {
        var layout = data.getItemLayout(dataIndex);

        return layout
            && !isNaN(layout.x) && !isNaN(layout.y)
            && data.getItemVisual(dataIndex, 'symbol') !== 'none';
    }

    function getTreeNodeStyle(node, itemModel, seriesScope) {
        seriesScope.itemModel = itemModel;
        seriesScope.itemStyle = itemModel.getModel('itemStyle.normal').getItemStyle();
        seriesScope.hoverItemStyle = itemModel.getModel('itemStyle.emphasis').getItemStyle();
        seriesScope.lineStyle = itemModel.getModel('lineStyle.normal').getLineStyle();
        seriesScope.labelModel = itemModel.getModel('label.normal');
        seriesScope.hoverLabelModel = itemModel.getModel('label.emphasis');
D
deqingli 已提交
122

D
deqingli 已提交
123 124 125 126 127 128 129 130 131 132 133
        if (node.isExpand === false && node.children.length !== 0) {
            seriesScope.symbolInnerColor = seriesScope.itemStyle.fill;
        }
        else {
            seriesScope.symbolInnerColor = '#fff';
        }

        return seriesScope;
    }

    function updateNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) {
134
        var isInit = !symbolEl;
D
deqingli 已提交
135 136 137 138 139
        var node = data.tree.getNodeByDataIndex(dataIndex);
        var itemModel = node.getModel();
        var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope);
        var virtualRoot = data.tree.root;

140
        var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
D
deqingli 已提交
141 142 143
        var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
        var sourceLayout = source.getLayout();
        var sourceOldLayout = sourceSymbolEl
D
deqingli 已提交
144 145 146 147 148 149
            ? {
                x: sourceSymbolEl.position[0],
                y: sourceSymbolEl.position[1],
                rawX: sourceSymbolEl.__radialOldRawX,
                rawY: sourceSymbolEl.__radialOldRawY
            }
D
deqingli 已提交
150 151 152
            : sourceLayout;
        var targetLayout = node.getLayout();

153
        if (isInit) {
S
sushuang 已提交
154
            symbolEl = new Symbol(data, dataIndex, seriesScope);
D
deqingli 已提交
155
            symbolEl.attr('position', [sourceOldLayout.x, sourceOldLayout.y]);
S
sushuang 已提交
156 157 158
        }
        else {
            symbolEl.updateData(data, dataIndex, seriesScope);
D
deqingli 已提交
159 160
        }

D
deqingli 已提交
161 162 163 164 165
        symbolEl.__radialOldRawX = symbolEl.__radialRawX;
        symbolEl.__radialOldRawY = symbolEl.__radialRawY;
        symbolEl.__radialRawX = targetLayout.rawX;
        symbolEl.__radialRawY = targetLayout.rawY;

D
deqingli 已提交
166 167
        group.add(symbolEl);
        data.setItemGraphicEl(dataIndex, symbolEl);
D
deqingli 已提交
168 169
        graphic.updateProps(symbolEl, {
            position: [targetLayout.x, targetLayout.y]
170 171
        }, seriesModel);

D
deqingli 已提交
172 173
        var symbolPath = symbolEl.getSymbolPath();

174 175 176
        if (seriesScope.layout === 'radial') {
            var realRoot = virtualRoot.children[0];
            var rootLayout = realRoot.getLayout();
177 178
            var length = realRoot.children.length;
            var rad;
179
            var isLeft;
180

181
            if (targetLayout.x === rootLayout.x && node.isExpand === true) {
182 183 184 185 186 187 188 189
                var center = {};
                center.x = (realRoot.children[0].getLayout().x + realRoot.children[length - 1].getLayout().x) / 2;
                center.y = (realRoot.children[0].getLayout().y + realRoot.children[length - 1].getLayout().y) / 2;
                rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x);
                if (rad < 0) {
                    rad = Math.PI * 2 + rad;
                }
                isLeft = center.x < rootLayout.x;
190 191 192 193 194
                if (isLeft) {
                    rad = rad - Math.PI;
                }
            }
            else {
195 196 197 198 199 200 201 202 203
                rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x);
                if (rad < 0) {
                    rad = Math.PI * 2 + rad;
                }
                if (node.children.length === 0 || (node.children.length !== 0 && node.isExpand === false)) {
                    isLeft = targetLayout.x < rootLayout.x;
                    if (isLeft) {
                        rad = rad - Math.PI;
                    }
204 205 206 207 208 209 210 211
                }
                else {
                    isLeft = targetLayout.x > rootLayout.x;
                    if (!isLeft) {
                        rad = rad - Math.PI;
                    }
                }
            }
D
deqingli 已提交
212

213
            var textPosition = isLeft ? 'left' : 'right';
214 215 216 217 218 219 220 221
            symbolPath.setStyle({
                textPosition: textPosition,
                textRotation: -rad,
                textOrigin: 'center',
                verticalAlign: 'middle'
            });
        }

D
deqingli 已提交
222 223 224 225 226 227
        if (node.parentNode && node.parentNode !== virtualRoot) {
            var edge = symbolEl.__edge;
            if (!edge) {
                edge = symbolEl.__edge = new graphic.BezierCurve({
                    shape: getEdgeShape(seriesScope, sourceOldLayout, sourceOldLayout),
                    style: zrUtil.defaults({opacity: 0}, seriesScope.lineStyle)
D
deqingli 已提交
228 229 230
                });
            }

D
deqingli 已提交
231
            graphic.updateProps(edge, {
D
deqingli 已提交
232 233 234 235 236 237 238
                shape: getEdgeShape(seriesScope, sourceLayout, targetLayout),
                style: {opacity: 1}
            }, seriesModel);

            group.add(edge);
        }
    }
D
deqingli 已提交
239

D
deqingli 已提交
240 241 242 243 244
    function removeNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) {
        var node = data.tree.getNodeByDataIndex(dataIndex);
        var virtualRoot = data.tree.root;
        var itemModel = node.getModel();
        var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope);
D
deqingli 已提交
245

D
deqingli 已提交
246 247 248 249 250 251 252
        var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
        var sourceLayout;
        while (sourceLayout = source.getLayout(), sourceLayout == null) {
            source = source.parentNode === virtualRoot ? source : source.parentNode || source;
        }

        graphic.updateProps(symbolEl, {
D
deqingli 已提交
253
            position: [sourceLayout.x + 1, sourceLayout.y + 1]
D
deqingli 已提交
254 255 256 257 258
        }, seriesModel, function () {
            group.remove(symbolEl);
            data.setItemGraphicEl(dataIndex, null);
        });

S
sushuang 已提交
259 260
        symbolEl.fadeOut();

D
deqingli 已提交
261 262 263 264 265 266 267 268 269
        var edge = symbolEl.__edge;
        if (edge) {
            graphic.updateProps(edge, {
                shape: getEdgeShape(seriesScope, sourceLayout, sourceLayout),
                style: {
                    opacity: 0
                }
            }, seriesModel, function () {
                group.remove(edge);
D
deqingli 已提交
270
            });
D
deqingli 已提交
271 272
        }
    }
D
deqingli 已提交
273

D
deqingli 已提交
274 275 276 277 278 279 280 281
    function getEdgeShape(seriesScope, sourceLayout, targetLayout) {
        var cpx1;
        var cpy1;
        var cpx2;
        var cpy2;
        var orient = seriesScope.orient;

        if (seriesScope.layout === 'radial') {
D
deqingli 已提交
282 283 284 285
            var x1 = sourceLayout.rawX;
            var y1 = sourceLayout.rawY;
            var x2 = targetLayout.rawX;
            var y2 = targetLayout.rawY;
D
deqingli 已提交
286 287

            var radialCoor1 = radialCoordinate(x1, y1);
D
deqingli 已提交
288 289
            var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * seriesScope.curvature);
            var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * seriesScope.curvature);
D
deqingli 已提交
290 291 292 293 294
            var radialCoor4 = radialCoordinate(x2, y2);

            return {
                x1: radialCoor1.x,
                y1: radialCoor1.y,
D
deqingli 已提交
295 296 297 298 299 300
                x2: radialCoor4.x,
                y2: radialCoor4.y,
                cpx1: radialCoor2.x,
                cpy1: radialCoor2.y,
                cpx2: radialCoor3.x,
                cpy2: radialCoor3.y
D
deqingli 已提交
301 302 303
            };
        }
        else {
D
deqingli 已提交
304 305 306 307
            var x1 = sourceLayout.x;
            var y1 = sourceLayout.y;
            var x2 = targetLayout.x;
            var y2 = targetLayout.y;
D
deqingli 已提交
308 309 310 311 312 313 314 315 316

            if (orient === 'horizontal') {
                cpx1 = x1 + (x2 - x1) * seriesScope.curvature;
                cpy1 = y1;
                cpx2 = x2 + (x1 - x2) * seriesScope.curvature;
                cpy2 = y2;
            }
            if (orient === 'vertical') {
                cpx1 = x1;
D
deqingli 已提交
317
                cpy1 = y1 + (y2 - y1) * seriesScope.curvature;
D
deqingli 已提交
318
                cpx2 = x2;
D
deqingli 已提交
319
                cpy2 = y2 + (y1 - y2) * seriesScope.curvature;
D
deqingli 已提交
320 321 322 323 324 325 326 327 328 329 330 331 332
            }
            return {
                x1: x1,
                y1: y1,
                x2: x2,
                y2: y2,
                cpx1: cpx1,
                cpy1: cpy1,
                cpx2: cpx2,
                cpy2: cpy2
            };
        }
    }
D
deqingli 已提交
333 334

});