TreeView.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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 * as zrUtil from 'zrender/lib/core/util.js';
  42. import * as graphic from '../../util/graphic.js';
  43. import { getECData } from '../../util/innerStore.js';
  44. import SymbolClz from '../helper/Symbol.js';
  45. import { radialCoordinate } from './layoutHelper.js';
  46. import * as bbox from 'zrender/lib/core/bbox.js';
  47. import View from '../../coord/View.js';
  48. import * as roamHelper from '../../component/helper/roamHelper.js';
  49. import RoamController from '../../component/helper/RoamController.js';
  50. import { onIrrelevantElement } from '../../component/helper/cursorHelper.js';
  51. import { parsePercent } from '../../util/number.js';
  52. import ChartView from '../../view/Chart.js';
  53. import Path from 'zrender/lib/graphic/Path.js';
  54. import { setStatesStylesFromModel, setStatesFlag, setDefaultStateProxy, HOVER_STATE_BLUR } from '../../util/states.js';
  55. var TreeEdgeShape =
  56. /** @class */
  57. function () {
  58. function TreeEdgeShape() {
  59. this.parentPoint = [];
  60. this.childPoints = [];
  61. }
  62. return TreeEdgeShape;
  63. }();
  64. var TreePath =
  65. /** @class */
  66. function (_super) {
  67. __extends(TreePath, _super);
  68. function TreePath(opts) {
  69. return _super.call(this, opts) || this;
  70. }
  71. TreePath.prototype.getDefaultStyle = function () {
  72. return {
  73. stroke: '#000',
  74. fill: null
  75. };
  76. };
  77. TreePath.prototype.getDefaultShape = function () {
  78. return new TreeEdgeShape();
  79. };
  80. TreePath.prototype.buildPath = function (ctx, shape) {
  81. var childPoints = shape.childPoints;
  82. var childLen = childPoints.length;
  83. var parentPoint = shape.parentPoint;
  84. var firstChildPos = childPoints[0];
  85. var lastChildPos = childPoints[childLen - 1];
  86. if (childLen === 1) {
  87. ctx.moveTo(parentPoint[0], parentPoint[1]);
  88. ctx.lineTo(firstChildPos[0], firstChildPos[1]);
  89. return;
  90. }
  91. var orient = shape.orient;
  92. var forkDim = orient === 'TB' || orient === 'BT' ? 0 : 1;
  93. var otherDim = 1 - forkDim;
  94. var forkPosition = parsePercent(shape.forkPosition, 1);
  95. var tmpPoint = [];
  96. tmpPoint[forkDim] = parentPoint[forkDim];
  97. tmpPoint[otherDim] = parentPoint[otherDim] + (lastChildPos[otherDim] - parentPoint[otherDim]) * forkPosition;
  98. ctx.moveTo(parentPoint[0], parentPoint[1]);
  99. ctx.lineTo(tmpPoint[0], tmpPoint[1]);
  100. ctx.moveTo(firstChildPos[0], firstChildPos[1]);
  101. tmpPoint[forkDim] = firstChildPos[forkDim];
  102. ctx.lineTo(tmpPoint[0], tmpPoint[1]);
  103. tmpPoint[forkDim] = lastChildPos[forkDim];
  104. ctx.lineTo(tmpPoint[0], tmpPoint[1]);
  105. ctx.lineTo(lastChildPos[0], lastChildPos[1]);
  106. for (var i = 1; i < childLen - 1; i++) {
  107. var point = childPoints[i];
  108. ctx.moveTo(point[0], point[1]);
  109. tmpPoint[forkDim] = point[forkDim];
  110. ctx.lineTo(tmpPoint[0], tmpPoint[1]);
  111. }
  112. };
  113. return TreePath;
  114. }(Path);
  115. var TreeView =
  116. /** @class */
  117. function (_super) {
  118. __extends(TreeView, _super);
  119. function TreeView() {
  120. var _this = _super !== null && _super.apply(this, arguments) || this;
  121. _this.type = TreeView.type;
  122. _this._mainGroup = new graphic.Group();
  123. return _this;
  124. }
  125. TreeView.prototype.init = function (ecModel, api) {
  126. this._controller = new RoamController(api.getZr());
  127. this._controllerHost = {
  128. target: this.group
  129. };
  130. this.group.add(this._mainGroup);
  131. };
  132. TreeView.prototype.render = function (seriesModel, ecModel, api) {
  133. var data = seriesModel.getData();
  134. var layoutInfo = seriesModel.layoutInfo;
  135. var group = this._mainGroup;
  136. var layout = seriesModel.get('layout');
  137. if (layout === 'radial') {
  138. group.x = layoutInfo.x + layoutInfo.width / 2;
  139. group.y = layoutInfo.y + layoutInfo.height / 2;
  140. } else {
  141. group.x = layoutInfo.x;
  142. group.y = layoutInfo.y;
  143. }
  144. this._updateViewCoordSys(seriesModel, api);
  145. this._updateController(seriesModel, ecModel, api);
  146. var oldData = this._data;
  147. data.diff(oldData).add(function (newIdx) {
  148. if (symbolNeedsDraw(data, newIdx)) {
  149. // Create node and edge
  150. updateNode(data, newIdx, null, group, seriesModel);
  151. }
  152. }).update(function (newIdx, oldIdx) {
  153. var symbolEl = oldData.getItemGraphicEl(oldIdx);
  154. if (!symbolNeedsDraw(data, newIdx)) {
  155. symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
  156. return;
  157. } // Update node and edge
  158. updateNode(data, newIdx, symbolEl, group, seriesModel);
  159. }).remove(function (oldIdx) {
  160. var symbolEl = oldData.getItemGraphicEl(oldIdx); // When remove a collapsed node of subtree, since the collapsed
  161. // node haven't been initialized with a symbol element,
  162. // you can't found it's symbol element through index.
  163. // so if we want to remove the symbol element we should insure
  164. // that the symbol element is not null.
  165. if (symbolEl) {
  166. removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
  167. }
  168. }).execute();
  169. this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');
  170. this._updateNodeAndLinkScale(seriesModel);
  171. if (seriesModel.get('expandAndCollapse') === true) {
  172. data.eachItemGraphicEl(function (el, dataIndex) {
  173. el.off('click').on('click', function () {
  174. api.dispatchAction({
  175. type: 'treeExpandAndCollapse',
  176. seriesId: seriesModel.id,
  177. dataIndex: dataIndex
  178. });
  179. });
  180. });
  181. }
  182. this._data = data;
  183. };
  184. TreeView.prototype._updateViewCoordSys = function (seriesModel, api) {
  185. var data = seriesModel.getData();
  186. var points = [];
  187. data.each(function (idx) {
  188. var layout = data.getItemLayout(idx);
  189. if (layout && !isNaN(layout.x) && !isNaN(layout.y)) {
  190. points.push([+layout.x, +layout.y]);
  191. }
  192. });
  193. var min = [];
  194. var max = [];
  195. bbox.fromPoints(points, min, max); // If don't Store min max when collapse the root node after roam,
  196. // the root node will disappear.
  197. var oldMin = this._min;
  198. var oldMax = this._max; // If width or height is 0
  199. if (max[0] - min[0] === 0) {
  200. min[0] = oldMin ? oldMin[0] : min[0] - 1;
  201. max[0] = oldMax ? oldMax[0] : max[0] + 1;
  202. }
  203. if (max[1] - min[1] === 0) {
  204. min[1] = oldMin ? oldMin[1] : min[1] - 1;
  205. max[1] = oldMax ? oldMax[1] : max[1] + 1;
  206. }
  207. var viewCoordSys = seriesModel.coordinateSystem = new View();
  208. viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');
  209. viewCoordSys.setBoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
  210. viewCoordSys.setCenter(seriesModel.get('center'), api);
  211. viewCoordSys.setZoom(seriesModel.get('zoom')); // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group
  212. this.group.attr({
  213. x: viewCoordSys.x,
  214. y: viewCoordSys.y,
  215. scaleX: viewCoordSys.scaleX,
  216. scaleY: viewCoordSys.scaleY
  217. });
  218. this._min = min;
  219. this._max = max;
  220. };
  221. TreeView.prototype._updateController = function (seriesModel, ecModel, api) {
  222. var _this = this;
  223. var controller = this._controller;
  224. var controllerHost = this._controllerHost;
  225. var group = this.group;
  226. controller.setPointerChecker(function (e, x, y) {
  227. var rect = group.getBoundingRect();
  228. rect.applyTransform(group.transform);
  229. return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel);
  230. });
  231. controller.enable(seriesModel.get('roam'));
  232. controllerHost.zoomLimit = seriesModel.get('scaleLimit');
  233. controllerHost.zoom = seriesModel.coordinateSystem.getZoom();
  234. controller.off('pan').off('zoom').on('pan', function (e) {
  235. roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
  236. api.dispatchAction({
  237. seriesId: seriesModel.id,
  238. type: 'treeRoam',
  239. dx: e.dx,
  240. dy: e.dy
  241. });
  242. }).on('zoom', function (e) {
  243. roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
  244. api.dispatchAction({
  245. seriesId: seriesModel.id,
  246. type: 'treeRoam',
  247. zoom: e.scale,
  248. originX: e.originX,
  249. originY: e.originY
  250. });
  251. _this._updateNodeAndLinkScale(seriesModel); // Only update label layout on zoom
  252. api.updateLabelLayout();
  253. });
  254. };
  255. TreeView.prototype._updateNodeAndLinkScale = function (seriesModel) {
  256. var data = seriesModel.getData();
  257. var nodeScale = this._getNodeGlobalScale(seriesModel);
  258. data.eachItemGraphicEl(function (el, idx) {
  259. el.setSymbolScale(nodeScale);
  260. });
  261. };
  262. TreeView.prototype._getNodeGlobalScale = function (seriesModel) {
  263. var coordSys = seriesModel.coordinateSystem;
  264. if (coordSys.type !== 'view') {
  265. return 1;
  266. }
  267. var nodeScaleRatio = this._nodeScaleRatio;
  268. var groupZoom = coordSys.scaleX || 1; // Scale node when zoom changes
  269. var roamZoom = coordSys.getZoom();
  270. var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
  271. return nodeScale / groupZoom;
  272. };
  273. TreeView.prototype.dispose = function () {
  274. this._controller && this._controller.dispose();
  275. this._controllerHost = null;
  276. };
  277. TreeView.prototype.remove = function () {
  278. this._mainGroup.removeAll();
  279. this._data = null;
  280. };
  281. TreeView.type = 'tree';
  282. return TreeView;
  283. }(ChartView);
  284. function symbolNeedsDraw(data, dataIndex) {
  285. var layout = data.getItemLayout(dataIndex);
  286. return layout && !isNaN(layout.x) && !isNaN(layout.y);
  287. }
  288. function updateNode(data, dataIndex, symbolEl, group, seriesModel) {
  289. var isInit = !symbolEl;
  290. var node = data.tree.getNodeByDataIndex(dataIndex);
  291. var itemModel = node.getModel();
  292. var visualColor = node.getVisual('style').fill;
  293. var symbolInnerColor = node.isExpand === false && node.children.length !== 0 ? visualColor : '#fff';
  294. var virtualRoot = data.tree.root;
  295. var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
  296. var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
  297. var sourceLayout = source.getLayout();
  298. var sourceOldLayout = sourceSymbolEl ? {
  299. x: sourceSymbolEl.__oldX,
  300. y: sourceSymbolEl.__oldY,
  301. rawX: sourceSymbolEl.__radialOldRawX,
  302. rawY: sourceSymbolEl.__radialOldRawY
  303. } : sourceLayout;
  304. var targetLayout = node.getLayout();
  305. if (isInit) {
  306. symbolEl = new SymbolClz(data, dataIndex, null, {
  307. symbolInnerColor: symbolInnerColor,
  308. useNameLabel: true
  309. });
  310. symbolEl.x = sourceOldLayout.x;
  311. symbolEl.y = sourceOldLayout.y;
  312. } else {
  313. symbolEl.updateData(data, dataIndex, null, {
  314. symbolInnerColor: symbolInnerColor,
  315. useNameLabel: true
  316. });
  317. }
  318. symbolEl.__radialOldRawX = symbolEl.__radialRawX;
  319. symbolEl.__radialOldRawY = symbolEl.__radialRawY;
  320. symbolEl.__radialRawX = targetLayout.rawX;
  321. symbolEl.__radialRawY = targetLayout.rawY;
  322. group.add(symbolEl);
  323. data.setItemGraphicEl(dataIndex, symbolEl);
  324. symbolEl.__oldX = symbolEl.x;
  325. symbolEl.__oldY = symbolEl.y;
  326. graphic.updateProps(symbolEl, {
  327. x: targetLayout.x,
  328. y: targetLayout.y
  329. }, seriesModel);
  330. var symbolPath = symbolEl.getSymbolPath();
  331. if (seriesModel.get('layout') === 'radial') {
  332. var realRoot = virtualRoot.children[0];
  333. var rootLayout = realRoot.getLayout();
  334. var length_1 = realRoot.children.length;
  335. var rad = void 0;
  336. var isLeft = void 0;
  337. if (targetLayout.x === rootLayout.x && node.isExpand === true && realRoot.children.length) {
  338. var center = {
  339. x: (realRoot.children[0].getLayout().x + realRoot.children[length_1 - 1].getLayout().x) / 2,
  340. y: (realRoot.children[0].getLayout().y + realRoot.children[length_1 - 1].getLayout().y) / 2
  341. };
  342. rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x);
  343. if (rad < 0) {
  344. rad = Math.PI * 2 + rad;
  345. }
  346. isLeft = center.x < rootLayout.x;
  347. if (isLeft) {
  348. rad = rad - Math.PI;
  349. }
  350. } else {
  351. rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x);
  352. if (rad < 0) {
  353. rad = Math.PI * 2 + rad;
  354. }
  355. if (node.children.length === 0 || node.children.length !== 0 && node.isExpand === false) {
  356. isLeft = targetLayout.x < rootLayout.x;
  357. if (isLeft) {
  358. rad = rad - Math.PI;
  359. }
  360. } else {
  361. isLeft = targetLayout.x > rootLayout.x;
  362. if (!isLeft) {
  363. rad = rad - Math.PI;
  364. }
  365. }
  366. }
  367. var textPosition = isLeft ? 'left' : 'right';
  368. var normalLabelModel = itemModel.getModel('label');
  369. var rotate = normalLabelModel.get('rotate');
  370. var labelRotateRadian = rotate * (Math.PI / 180);
  371. var textContent = symbolPath.getTextContent();
  372. if (textContent) {
  373. symbolPath.setTextConfig({
  374. position: normalLabelModel.get('position') || textPosition,
  375. rotation: rotate == null ? -rad : labelRotateRadian,
  376. origin: 'center'
  377. });
  378. textContent.setStyle('verticalAlign', 'middle');
  379. }
  380. } // Handle status
  381. var focus = itemModel.get(['emphasis', 'focus']);
  382. var focusDataIndices = focus === 'relative' ? zrUtil.concatArray(node.getAncestorsIndices(), node.getDescendantIndices()) : focus === 'ancestor' ? node.getAncestorsIndices() : focus === 'descendant' ? node.getDescendantIndices() : null;
  383. if (focusDataIndices) {
  384. // Modify the focus to data indices.
  385. getECData(symbolEl).focus = focusDataIndices;
  386. }
  387. drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group);
  388. if (symbolEl.__edge) {
  389. symbolEl.onHoverStateChange = function (toState) {
  390. if (toState !== 'blur') {
  391. // NOTE: Ensure the parent elements will been blurred firstly.
  392. // According to the return of getAncestorsIndices and getDescendantIndices
  393. // TODO: A bit tricky.
  394. var parentEl = node.parentNode && data.getItemGraphicEl(node.parentNode.dataIndex);
  395. if (!(parentEl && parentEl.hoverState === HOVER_STATE_BLUR)) {
  396. setStatesFlag(symbolEl.__edge, toState);
  397. }
  398. }
  399. };
  400. }
  401. }
  402. function drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group) {
  403. var itemModel = node.getModel();
  404. var edgeShape = seriesModel.get('edgeShape');
  405. var layout = seriesModel.get('layout');
  406. var orient = seriesModel.getOrient();
  407. var curvature = seriesModel.get(['lineStyle', 'curveness']);
  408. var edgeForkPosition = seriesModel.get('edgeForkPosition');
  409. var lineStyle = itemModel.getModel('lineStyle').getLineStyle();
  410. var edge = symbolEl.__edge; // curve edge from node -> parent
  411. // polyline edge from node -> children
  412. if (edgeShape === 'curve') {
  413. if (node.parentNode && node.parentNode !== virtualRoot) {
  414. if (!edge) {
  415. edge = symbolEl.__edge = new graphic.BezierCurve({
  416. shape: getEdgeShape(layout, orient, curvature, sourceOldLayout, sourceOldLayout)
  417. });
  418. }
  419. graphic.updateProps(edge, {
  420. shape: getEdgeShape(layout, orient, curvature, sourceLayout, targetLayout)
  421. }, seriesModel);
  422. }
  423. } else if (edgeShape === 'polyline') {
  424. if (layout === 'orthogonal') {
  425. if (node !== virtualRoot && node.children && node.children.length !== 0 && node.isExpand === true) {
  426. var children = node.children;
  427. var childPoints = [];
  428. for (var i = 0; i < children.length; i++) {
  429. var childLayout = children[i].getLayout();
  430. childPoints.push([childLayout.x, childLayout.y]);
  431. }
  432. if (!edge) {
  433. edge = symbolEl.__edge = new TreePath({
  434. shape: {
  435. parentPoint: [targetLayout.x, targetLayout.y],
  436. childPoints: [[targetLayout.x, targetLayout.y]],
  437. orient: orient,
  438. forkPosition: edgeForkPosition
  439. }
  440. });
  441. }
  442. graphic.updateProps(edge, {
  443. shape: {
  444. parentPoint: [targetLayout.x, targetLayout.y],
  445. childPoints: childPoints
  446. }
  447. }, seriesModel);
  448. }
  449. } else {
  450. if (process.env.NODE_ENV !== 'production') {
  451. throw new Error('The polyline edgeShape can only be used in orthogonal layout');
  452. }
  453. }
  454. } // show all edge when edgeShape is 'curve', filter node `isExpand` is false when edgeShape is 'polyline'
  455. if (edge && !(edgeShape === 'polyline' && !node.isExpand)) {
  456. edge.useStyle(zrUtil.defaults({
  457. strokeNoScale: true,
  458. fill: null
  459. }, lineStyle));
  460. setStatesStylesFromModel(edge, itemModel, 'lineStyle');
  461. setDefaultStateProxy(edge);
  462. group.add(edge);
  463. }
  464. }
  465. function removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt) {
  466. var virtualRoot = data.tree.root;
  467. var _a = getSourceNode(virtualRoot, node),
  468. source = _a.source,
  469. sourceLayout = _a.sourceLayout;
  470. var symbolEl = data.getItemGraphicEl(node.dataIndex);
  471. if (!symbolEl) {
  472. return;
  473. }
  474. var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
  475. var sourceEdge = sourceSymbolEl.__edge; // 1. when expand the sub tree, delete the children node should delete the edge of
  476. // the source at the same time. because the polyline edge shape is only owned by the source.
  477. // 2.when the node is the only children of the source, delete the node should delete the edge of
  478. // the source at the same time. the same reason as above.
  479. var edge = symbolEl.__edge || (source.isExpand === false || source.children.length === 1 ? sourceEdge : undefined);
  480. var edgeShape = seriesModel.get('edgeShape');
  481. var layoutOpt = seriesModel.get('layout');
  482. var orient = seriesModel.get('orient');
  483. var curvature = seriesModel.get(['lineStyle', 'curveness']);
  484. if (edge) {
  485. if (edgeShape === 'curve') {
  486. graphic.removeElement(edge, {
  487. shape: getEdgeShape(layoutOpt, orient, curvature, sourceLayout, sourceLayout),
  488. style: {
  489. opacity: 0
  490. }
  491. }, seriesModel, {
  492. cb: function () {
  493. group.remove(edge);
  494. },
  495. removeOpt: removeAnimationOpt
  496. });
  497. } else if (edgeShape === 'polyline' && seriesModel.get('layout') === 'orthogonal') {
  498. graphic.removeElement(edge, {
  499. shape: {
  500. parentPoint: [sourceLayout.x, sourceLayout.y],
  501. childPoints: [[sourceLayout.x, sourceLayout.y]]
  502. },
  503. style: {
  504. opacity: 0
  505. }
  506. }, seriesModel, {
  507. cb: function () {
  508. group.remove(edge);
  509. },
  510. removeOpt: removeAnimationOpt
  511. });
  512. }
  513. }
  514. }
  515. function getSourceNode(virtualRoot, node) {
  516. var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
  517. var sourceLayout;
  518. while (sourceLayout = source.getLayout(), sourceLayout == null) {
  519. source = source.parentNode === virtualRoot ? source : source.parentNode || source;
  520. }
  521. return {
  522. source: source,
  523. sourceLayout: sourceLayout
  524. };
  525. }
  526. function removeNode(data, dataIndex, symbolEl, group, seriesModel) {
  527. var node = data.tree.getNodeByDataIndex(dataIndex);
  528. var virtualRoot = data.tree.root;
  529. var sourceLayout = getSourceNode(virtualRoot, node).sourceLayout; // Use same duration and easing with update to have more consistent animation.
  530. var removeAnimationOpt = {
  531. duration: seriesModel.get('animationDurationUpdate'),
  532. easing: seriesModel.get('animationEasingUpdate')
  533. };
  534. graphic.removeElement(symbolEl, {
  535. x: sourceLayout.x + 1,
  536. y: sourceLayout.y + 1
  537. }, seriesModel, {
  538. cb: function () {
  539. group.remove(symbolEl);
  540. data.setItemGraphicEl(dataIndex, null);
  541. },
  542. removeOpt: removeAnimationOpt
  543. });
  544. symbolEl.fadeOut(null, data.hostModel, {
  545. fadeLabel: true,
  546. animation: removeAnimationOpt
  547. }); // remove edge as parent node
  548. node.children.forEach(function (childNode) {
  549. removeNodeEdge(childNode, data, group, seriesModel, removeAnimationOpt);
  550. }); // remove edge as child node
  551. removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt);
  552. }
  553. function getEdgeShape(layoutOpt, orient, curvature, sourceLayout, targetLayout) {
  554. var cpx1;
  555. var cpy1;
  556. var cpx2;
  557. var cpy2;
  558. var x1;
  559. var x2;
  560. var y1;
  561. var y2;
  562. if (layoutOpt === 'radial') {
  563. x1 = sourceLayout.rawX;
  564. y1 = sourceLayout.rawY;
  565. x2 = targetLayout.rawX;
  566. y2 = targetLayout.rawY;
  567. var radialCoor1 = radialCoordinate(x1, y1);
  568. var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * curvature);
  569. var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * curvature);
  570. var radialCoor4 = radialCoordinate(x2, y2);
  571. return {
  572. x1: radialCoor1.x || 0,
  573. y1: radialCoor1.y || 0,
  574. x2: radialCoor4.x || 0,
  575. y2: radialCoor4.y || 0,
  576. cpx1: radialCoor2.x || 0,
  577. cpy1: radialCoor2.y || 0,
  578. cpx2: radialCoor3.x || 0,
  579. cpy2: radialCoor3.y || 0
  580. };
  581. } else {
  582. x1 = sourceLayout.x;
  583. y1 = sourceLayout.y;
  584. x2 = targetLayout.x;
  585. y2 = targetLayout.y;
  586. if (orient === 'LR' || orient === 'RL') {
  587. cpx1 = x1 + (x2 - x1) * curvature;
  588. cpy1 = y1;
  589. cpx2 = x2 + (x1 - x2) * curvature;
  590. cpy2 = y2;
  591. }
  592. if (orient === 'TB' || orient === 'BT') {
  593. cpx1 = x1;
  594. cpy1 = y1 + (y2 - y1) * curvature;
  595. cpx2 = x2;
  596. cpy2 = y2 + (y1 - y2) * curvature;
  597. }
  598. }
  599. return {
  600. x1: x1,
  601. y1: y1,
  602. x2: x2,
  603. y2: y2,
  604. cpx1: cpx1,
  605. cpy1: cpy1,
  606. cpx2: cpx2,
  607. cpy2: cpy2
  608. };
  609. }
  610. export default TreeView;