GraphView.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. /**
  20. * AUTO-GENERATED FILE. DO NOT MODIFY.
  21. */
  22. /*
  23. * Licensed to the Apache Software Foundation (ASF) under one
  24. * or more contributor license agreements. See the NOTICE file
  25. * distributed with this work for additional information
  26. * regarding copyright ownership. The ASF licenses this file
  27. * to you under the Apache License, Version 2.0 (the
  28. * "License"); you may not use this file except in compliance
  29. * with the License. You may obtain a copy of the License at
  30. *
  31. * http://www.apache.org/licenses/LICENSE-2.0
  32. *
  33. * Unless required by applicable law or agreed to in writing,
  34. * software distributed under the License is distributed on an
  35. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  36. * KIND, either express or implied. See the License for the
  37. * specific language governing permissions and limitations
  38. * under the License.
  39. */
  40. import { __extends } from "tslib";
  41. import SymbolDraw from '../helper/SymbolDraw.js';
  42. import LineDraw from '../helper/LineDraw.js';
  43. import RoamController from '../../component/helper/RoamController.js';
  44. import { isRoamPayloadHasZoom, updateRoamControllerSimply } from '../../component/helper/roamHelper.js';
  45. import * as graphic from '../../util/graphic.js';
  46. import adjustEdge from './adjustEdge.js';
  47. import { getNodeGlobalScale } from './graphHelper.js';
  48. import ChartView from '../../view/Chart.js';
  49. import { SERIES_TYPE_GRAPH } from './GraphSeries.js';
  50. import { applyViewCoordSysTransToElement, getOwnRoamViewCoordSys, VIEW_COORD_SYS_TRANS_OVERALL, viewCoordSysCopyOverallMatrix } from '../../coord/View.js';
  51. import { getECData } from '../../util/innerStore.js';
  52. import { simpleLayoutEdge } from './simpleLayoutHelper.js';
  53. import { circularLayout, rotateNodeLabel } from './circularLayoutHelper.js';
  54. import { clone, extend } from 'zrender/lib/core/util.js';
  55. import ECLinePath from '../helper/LinePath.js';
  56. import { getThumbnailBridge } from '../../component/helper/thumbnailBridge.js';
  57. var GraphView = /** @class */function (_super) {
  58. __extends(GraphView, _super);
  59. function GraphView() {
  60. var _this = _super !== null && _super.apply(this, arguments) || this;
  61. _this.type = SERIES_TYPE_GRAPH;
  62. return _this;
  63. }
  64. GraphView.prototype.init = function (ecModel, api) {
  65. var symbolDraw = new SymbolDraw();
  66. var lineDraw = new LineDraw();
  67. var group = this.group;
  68. var mainGroup = new graphic.Group();
  69. this._controller = new RoamController(api.getZr());
  70. mainGroup.add(symbolDraw.group);
  71. mainGroup.add(lineDraw.group);
  72. group.add(mainGroup);
  73. this._symbolDraw = symbolDraw;
  74. this._lineDraw = lineDraw;
  75. this._mainGroup = mainGroup;
  76. this._firstRender = true;
  77. };
  78. GraphView.prototype.render = function (seriesModel, ecModel, api) {
  79. var _this = this;
  80. var ownCoordSys = getOwnRoamViewCoordSys(seriesModel);
  81. var isForceLayout = false;
  82. this._model = seriesModel;
  83. this._api = api;
  84. this._active = true;
  85. var mainGroup = this._mainGroup;
  86. var thumbnailInfo = this._getThumbnailInfo();
  87. if (thumbnailInfo) {
  88. thumbnailInfo.bridge.reset(api);
  89. }
  90. var symbolDraw = this._symbolDraw;
  91. var lineDraw = this._lineDraw;
  92. if (ownCoordSys) {
  93. applyViewCoordSysTransToElement(mainGroup, VIEW_COORD_SYS_TRANS_OVERALL, ownCoordSys, this._firstRender ? null : seriesModel);
  94. }
  95. // Fix edge contact point with node
  96. adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
  97. var data = seriesModel.getData();
  98. symbolDraw.updateData(data);
  99. var edgeData = seriesModel.getEdgeData();
  100. // TODO: TYPE
  101. lineDraw.updateData(edgeData);
  102. this._updateNodeAndLinkScale();
  103. if (ownCoordSys) {
  104. updateRoamControllerSimply(seriesModel, api, this._controller, function (e, x, y) {
  105. return seriesModel.coordinateSystem.containPoint([x, y]);
  106. }, null);
  107. }
  108. clearTimeout(this._layoutTimeout);
  109. var forceLayout = seriesModel.forceLayout;
  110. var layoutAnimation = seriesModel.get(['force', 'layoutAnimation']);
  111. if (forceLayout) {
  112. isForceLayout = true;
  113. this._startForceLayoutIteration(forceLayout, api, layoutAnimation);
  114. }
  115. var layout = seriesModel.get('layout');
  116. data.graph.eachNode(function (node) {
  117. var idx = node.dataIndex;
  118. var el = node.getGraphicEl();
  119. var itemModel = node.getModel();
  120. if (!el) {
  121. return;
  122. }
  123. // Update draggable
  124. el.off('drag').off('dragend');
  125. var draggable = itemModel.get('draggable');
  126. if (draggable) {
  127. el.on('drag', function (e) {
  128. switch (layout) {
  129. case 'force':
  130. forceLayout.warmUp();
  131. !_this._layouting && _this._startForceLayoutIteration(forceLayout, api, layoutAnimation);
  132. forceLayout.setFixed(idx);
  133. // Write position back to layout
  134. data.setItemLayout(idx, [el.x, el.y]);
  135. break;
  136. case 'circular':
  137. data.setItemLayout(idx, [el.x, el.y]);
  138. // mark node fixed
  139. node.setLayout({
  140. fixed: true
  141. }, true);
  142. // recalculate circular layout
  143. circularLayout(seriesModel, 'symbolSize', node, [e.offsetX, e.offsetY]);
  144. _this.updateLayout(seriesModel);
  145. break;
  146. case 'none':
  147. default:
  148. data.setItemLayout(idx, [el.x, el.y]);
  149. // update edge
  150. simpleLayoutEdge(seriesModel.getGraph(), seriesModel);
  151. _this.updateLayout(seriesModel);
  152. break;
  153. }
  154. }).on('dragend', function () {
  155. if (forceLayout) {
  156. forceLayout.setUnfixed(idx);
  157. }
  158. });
  159. }
  160. el.setDraggable(draggable, !!itemModel.get('cursor'));
  161. var focus = itemModel.get(['emphasis', 'focus']);
  162. if (focus === 'adjacency') {
  163. getECData(el).focus = node.getAdjacentDataIndices();
  164. }
  165. });
  166. data.graph.eachEdge(function (edge) {
  167. var el = edge.getGraphicEl();
  168. var focus = edge.getModel().get(['emphasis', 'focus']);
  169. if (!el) {
  170. return;
  171. }
  172. if (focus === 'adjacency') {
  173. getECData(el).focus = {
  174. edge: [edge.dataIndex],
  175. node: [edge.node1.dataIndex, edge.node2.dataIndex]
  176. };
  177. }
  178. });
  179. var circularRotateLabel = seriesModel.get('layout') === 'circular' && seriesModel.get(['circular', 'rotateLabel']);
  180. var cx = data.getLayout('cx');
  181. var cy = data.getLayout('cy');
  182. data.graph.eachNode(function (node) {
  183. rotateNodeLabel(node, circularRotateLabel, cx, cy);
  184. });
  185. this._firstRender = false;
  186. // Force layout will render thumbnail when layout is finished.
  187. if (!isForceLayout) {
  188. this._renderThumbnail(seriesModel, api, this._symbolDraw, this._lineDraw);
  189. }
  190. };
  191. GraphView.prototype.dispose = function () {
  192. this.remove();
  193. this._controller && this._controller.dispose();
  194. };
  195. GraphView.prototype._startForceLayoutIteration = function (forceLayout, api, layoutAnimation) {
  196. var self = this;
  197. var firstRendered = false;
  198. (function step() {
  199. forceLayout.step(function (stopped) {
  200. self.updateLayout(self._model);
  201. if (stopped || !firstRendered) {
  202. firstRendered = true;
  203. self._renderThumbnail(self._model, api, self._symbolDraw, self._lineDraw);
  204. }
  205. (self._layouting = !stopped) && (layoutAnimation ? self._layoutTimeout = setTimeout(step, 16) : step());
  206. });
  207. })();
  208. };
  209. /**
  210. * @implements RoamHostView['__updateOnOwnRoam']
  211. */
  212. GraphView.prototype.__updateOnOwnRoam = function (payload, seriesModel, api) {
  213. var ownCoordSys = getOwnRoamViewCoordSys(seriesModel);
  214. if (!this._active || !ownCoordSys) {
  215. return;
  216. }
  217. applyViewCoordSysTransToElement(this._mainGroup, VIEW_COORD_SYS_TRANS_OVERALL, ownCoordSys, null);
  218. if (isRoamPayloadHasZoom(payload)) {
  219. this._updateNodeAndLinkScale();
  220. adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
  221. this._lineDraw.updateLayout();
  222. // Only update label layout on zoom
  223. api.updateLabelLayout();
  224. }
  225. this._updateThumbnailWindow();
  226. };
  227. GraphView.prototype._updateNodeAndLinkScale = function () {
  228. var seriesModel = this._model;
  229. var data = seriesModel.getData();
  230. var nodeScale = getNodeGlobalScale(seriesModel);
  231. data.eachItemGraphicEl(function (el, idx) {
  232. el && el.setSymbolScale(nodeScale);
  233. });
  234. };
  235. GraphView.prototype.updateLayout = function (seriesModel) {
  236. if (!this._active) {
  237. return;
  238. }
  239. adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
  240. this._symbolDraw.updateLayout();
  241. this._lineDraw.updateLayout();
  242. };
  243. GraphView.prototype.remove = function () {
  244. this._active = false;
  245. clearTimeout(this._layoutTimeout);
  246. this._layouting = false;
  247. this._layoutTimeout = null;
  248. this._symbolDraw && this._symbolDraw.remove();
  249. this._lineDraw && this._lineDraw.remove();
  250. this._controller && this._controller.disable();
  251. };
  252. /**
  253. * Get thumbnail data structure only if supported.
  254. */
  255. GraphView.prototype._getThumbnailInfo = function () {
  256. var model = this._model;
  257. var coordSys = model.coordinateSystem;
  258. if (coordSys.type !== 'view') {
  259. return;
  260. }
  261. var bridge = getThumbnailBridge(model);
  262. if (!bridge) {
  263. return;
  264. }
  265. return {
  266. bridge: bridge,
  267. coordSys: coordSys
  268. };
  269. };
  270. GraphView.prototype._updateThumbnailWindow = function () {
  271. var info = this._getThumbnailInfo();
  272. if (info) {
  273. info.bridge.updateWindow(viewCoordSysCopyOverallMatrix(null, info.coordSys), this._api);
  274. }
  275. };
  276. GraphView.prototype._renderThumbnail = function (seriesModel, api, symbolDraw, lineDraw) {
  277. var info = this._getThumbnailInfo();
  278. if (!info) {
  279. return;
  280. }
  281. var bridgeGroup = new graphic.Group();
  282. var symbolNodes = symbolDraw.group.children();
  283. var lineNodes = lineDraw.group.children();
  284. var lineGroup = new graphic.Group();
  285. var symbolGroup = new graphic.Group();
  286. bridgeGroup.add(symbolGroup);
  287. bridgeGroup.add(lineGroup);
  288. // TODO: reuse elements for performance in large graph?
  289. for (var i = 0; i < symbolNodes.length; i++) {
  290. var node = symbolNodes[i];
  291. var sub = node.children()[0];
  292. var x = node.x;
  293. var y = node.y;
  294. var subShape = clone(sub.shape);
  295. var shape = extend(subShape, {
  296. width: sub.scaleX,
  297. height: sub.scaleY,
  298. x: x - sub.scaleX / 2,
  299. y: y - sub.scaleY / 2
  300. });
  301. var style = clone(sub.style);
  302. var subThumbnail = new sub.constructor({
  303. shape: shape,
  304. style: style,
  305. z2: 151
  306. });
  307. symbolGroup.add(subThumbnail);
  308. }
  309. for (var i = 0; i < lineNodes.length; i++) {
  310. var node = lineNodes[i];
  311. var line = node.children()[0];
  312. var style = clone(line.style);
  313. var shape = clone(line.shape);
  314. var lineThumbnail = new ECLinePath({
  315. style: style,
  316. shape: shape,
  317. z2: 151
  318. });
  319. lineGroup.add(lineThumbnail);
  320. }
  321. info.bridge.renderContent({
  322. api: api,
  323. roamType: seriesModel.get('roam'),
  324. viewportRect: null,
  325. group: bridgeGroup,
  326. targetTrans: viewCoordSysCopyOverallMatrix(null, info.coordSys)
  327. });
  328. };
  329. GraphView.type = SERIES_TYPE_GRAPH;
  330. return GraphView;
  331. }(ChartView);
  332. export default GraphView;