GraphView.js 7.1 KB
Newer Older
L
lang 已提交
1

L
lang 已提交
2 3
define(function (require) {

L
lang 已提交
4 5
    var SymbolDraw = require('../helper/SymbolDraw');
    var LineDraw = require('../helper/LineDraw');
L
lang 已提交
6
    var RoamController = require('../../component/helper/RoamController');
L
lang 已提交
7

L
lang 已提交
8
    var graphic = require('../../util/graphic');
L
lang 已提交
9
    var adjustEdge = require('./adjustEdge');
L
lang 已提交
10

L
lang 已提交
11 12 13 14
    require('../../echarts').extendChartView({

        type: 'graph',

L
lang 已提交
15
        init: function (ecModel, api) {
L
lang 已提交
16
            var symbolDraw = new SymbolDraw();
L
lang 已提交
17
            var lineDraw = new LineDraw();
L
lang 已提交
18
            var group = this.group;
L
lang 已提交
19

L
lang 已提交
20 21
            var controller = new RoamController(api.getZr(), group);

L
lang 已提交
22 23
            group.add(symbolDraw.group);
            group.add(lineDraw.group);
L
lang 已提交
24

L
lang 已提交
25
            this._symbolDraw = symbolDraw;
L
lang 已提交
26
            this._lineDraw = lineDraw;
L
lang 已提交
27
            this._controller = controller;
L
lang 已提交
28 29

            this._firstRender = true;
L
lang 已提交
30 31 32
        },

        render: function (seriesModel, ecModel, api) {
L
lang 已提交
33 34
            var coordSys = seriesModel.coordinateSystem;
            // Only support view and geo coordinate system
35 36 37
            // if (coordSys.type !== 'geo' && coordSys.type !== 'view') {
            //     return;
            // }
L
lang 已提交
38 39

            this._model = seriesModel;
40
            this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');
L
lang 已提交
41

L
lang 已提交
42 43 44
            var symbolDraw = this._symbolDraw;
            var lineDraw = this._lineDraw;

L
lang 已提交
45
            var group = this.group;
46 47 48 49 50 51 52 53 54 55 56 57

            if (coordSys.type === 'view') {
                var groupNewProp = {
                    position: coordSys.position,
                    scale: coordSys.scale
                };
                if (this._firstRender) {
                    group.attr(groupNewProp);
                }
                else {
                    graphic.updateProps(group, groupNewProp, seriesModel);
                }
L
lang 已提交
58
            }
59 60
            // Fix edge contact point with node
            adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
L
lang 已提交
61

62 63 64 65 66 67

            var data = seriesModel.getData();
            symbolDraw.updateData(data);

            var edgeData = seriesModel.getEdgeData();
            lineDraw.updateData(edgeData);
L
lang 已提交
68 69 70

            this._updateNodeAndLinkScale();

71
            this._updateController(seriesModel, api);
L
lang 已提交
72

L
lang 已提交
73
            clearTimeout(this._layoutTimeout);
L
lang 已提交
74
            var forceLayout = seriesModel.forceLayout;
L
lang 已提交
75
            var layoutAnimation = seriesModel.get('force.layoutAnimation');
L
lang 已提交
76
            if (forceLayout) {
L
lang 已提交
77
                this._startForceLayoutIteration(forceLayout, layoutAnimation);
L
lang 已提交
78
            }
L
lang 已提交
79 80 81
            // Update draggable
            data.eachItemGraphicEl(function (el, idx) {
                var draggable = data.getItemModel(idx).get('draggable');
82
                if (draggable) {
L
lang 已提交
83
                    el.on('drag', function () {
84 85 86 87 88 89 90 91
                        if (forceLayout) {
                            forceLayout.warmUp();
                            !this._layouting
                                && this._startForceLayoutIteration(forceLayout, layoutAnimation);
                            forceLayout.setFixed(idx);
                            // Write position back to layout
                            data.setItemLayout(idx, el.position);
                        }
L
lang 已提交
92
                    }, this).on('dragend', function () {
93 94 95
                        if (forceLayout) {
                            forceLayout.setUnfixed(idx);
                        }
L
lang 已提交
96
                    }, this);
L
lang 已提交
97 98 99 100
                }
                else {
                    el.off('drag');
                }
101
                el.setDraggable(draggable && forceLayout);
L
lang 已提交
102
            }, this);
L
lang 已提交
103 104

            this._firstRender = false;
L
lang 已提交
105 106
        },

L
lang 已提交
107
        _startForceLayoutIteration: function (forceLayout, layoutAnimation) {
L
lang 已提交
108 109 110
            var self = this;
            (function step() {
                forceLayout.step(function (stopped) {
111
                    self.updateLayout(self._model);
L
lang 已提交
112
                    (self._layouting = !stopped) && (
L
lang 已提交
113 114 115 116
                        layoutAnimation
                            ? (self._layoutTimeout = setTimeout(step, 16))
                            : step()
                    );
L
lang 已提交
117 118
                });
            })();
L
lang 已提交
119 120
        },

121
        _updateController: function (seriesModel, api) {
L
lang 已提交
122
            var controller = this._controller;
123 124 125 126 127 128
            var group = this.group;
            controller.rectProvider = function () {
                var rect = group.getBoundingRect();
                rect.applyTransform(group.transform);
                return rect;
            };
129 130 131 132
            if (seriesModel.coordinateSystem.type !== 'view') {
                controller.disable();
                return;
            }
L
lang 已提交
133
            controller.enable(seriesModel.get('roam'));
L
lang 已提交
134 135
            controller.zoomLimit = seriesModel.get('scaleLimit');
            // Update zoom from model
136
            controller.zoom = seriesModel.coordinateSystem.getZoom();
L
lang 已提交
137 138 139 140 141

            controller
                .off('pan')
                .off('zoom')
                .on('pan', function (dx, dy) {
L
lang 已提交
142
                    api.dispatchAction({
P
pah100 已提交
143
                        seriesId: seriesModel.id,
L
lang 已提交
144 145 146 147 148 149
                        type: 'graphRoam',
                        dx: dx,
                        dy: dy
                    });
                })
                .on('zoom', function (zoom, mouseX, mouseY) {
L
lang 已提交
150
                    api.dispatchAction({
P
pah100 已提交
151
                        seriesId: seriesModel.id,
L
lang 已提交
152 153 154 155 156
                        type: 'graphRoam',
                        zoom:  zoom,
                        originX: mouseX,
                        originY: mouseY
                    });
157 158 159 160
                    this._updateNodeAndLinkScale();
                    adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
                    this._lineDraw.updateLayout();
                }, this);
L
lang 已提交
161 162 163 164 165
        },

        _updateNodeAndLinkScale: function () {
            var seriesModel = this._model;
            var data = seriesModel.getData();
166 167 168 169 170 171 172 173 174 175

            var nodeScale = this._getNodeGlobalScale(seriesModel);
            var invScale = [nodeScale, nodeScale];

            data.eachItemGraphicEl(function (el, idx) {
                el.attr('scale', invScale);
            });
        },

        _getNodeGlobalScale: function (seriesModel) {
176
            var coordSys = seriesModel.coordinateSystem;
177 178 179
            if (coordSys.type !== 'view') {
                return 1;
            }
L
lang 已提交
180 181 182

            var nodeScaleRatio = this._nodeScaleRatio;

183 184 185 186 187
            var groupScale = this.group.scale;
            var groupZoom = (groupScale && groupScale[0]) || 1;
            // Scale node when zoom changes
            var roamZoom = coordSys.getZoom();
            var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
L
lang 已提交
188

189
            return nodeScale / groupZoom;
L
lang 已提交
190 191
        },

192
        updateLayout: function (seriesModel) {
L
lang 已提交
193 194
            this._symbolDraw.updateLayout();
            this._lineDraw.updateLayout();
195 196

            adjustEdge(seriesModel.getGraph(), this._getNodeGlobalScale(seriesModel));
L
lang 已提交
197
        },
L
lang 已提交
198

L
lang 已提交
199
        remove: function (ecModel, api) {
L
lang 已提交
200 201
            this._symbolDraw && this._symbolDraw.remove();
            this._lineDraw && this._lineDraw.remove();
L
lang 已提交
202 203 204
        }
    });
});