forked from zhurui/management
637 lines
20 KiB
JavaScript
637 lines
20 KiB
JavaScript
|
|
||
|
/*
|
||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||
|
* or more contributor license agreements. See the NOTICE file
|
||
|
* distributed with this work for additional information
|
||
|
* regarding copyright ownership. The ASF licenses this file
|
||
|
* to you under the Apache License, Version 2.0 (the
|
||
|
* "License"); you may not use this file except in compliance
|
||
|
* with the License. You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing,
|
||
|
* software distributed under the License is distributed on an
|
||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
* KIND, either express or implied. See the License for the
|
||
|
* specific language governing permissions and limitations
|
||
|
* under the License.
|
||
|
*/
|
||
|
|
||
|
var zrUtil = require("zrender/lib/core/util");
|
||
|
|
||
|
var graphic = require("../../util/graphic");
|
||
|
|
||
|
var SymbolClz = require("../helper/Symbol");
|
||
|
|
||
|
var _layoutHelper = require("./layoutHelper");
|
||
|
|
||
|
var radialCoordinate = _layoutHelper.radialCoordinate;
|
||
|
|
||
|
var echarts = require("../../echarts");
|
||
|
|
||
|
var bbox = require("zrender/lib/core/bbox");
|
||
|
|
||
|
var View = require("../../coord/View");
|
||
|
|
||
|
var roamHelper = require("../../component/helper/roamHelper");
|
||
|
|
||
|
var RoamController = require("../../component/helper/RoamController");
|
||
|
|
||
|
var _cursorHelper = require("../../component/helper/cursorHelper");
|
||
|
|
||
|
var onIrrelevantElement = _cursorHelper.onIrrelevantElement;
|
||
|
|
||
|
var _config = require("../../config");
|
||
|
|
||
|
var __DEV__ = _config.__DEV__;
|
||
|
|
||
|
var _number = require("../../util/number");
|
||
|
|
||
|
var parsePercent = _number.parsePercent;
|
||
|
|
||
|
/*
|
||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||
|
* or more contributor license agreements. See the NOTICE file
|
||
|
* distributed with this work for additional information
|
||
|
* regarding copyright ownership. The ASF licenses this file
|
||
|
* to you under the Apache License, Version 2.0 (the
|
||
|
* "License"); you may not use this file except in compliance
|
||
|
* with the License. You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing,
|
||
|
* software distributed under the License is distributed on an
|
||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
* KIND, either express or implied. See the License for the
|
||
|
* specific language governing permissions and limitations
|
||
|
* under the License.
|
||
|
*/
|
||
|
var TreeShape = graphic.extendShape({
|
||
|
shape: {
|
||
|
parentPoint: [],
|
||
|
childPoints: [],
|
||
|
orient: '',
|
||
|
forkPosition: ''
|
||
|
},
|
||
|
style: {
|
||
|
stroke: '#000',
|
||
|
fill: null
|
||
|
},
|
||
|
buildPath: function (ctx, shape) {
|
||
|
var childPoints = shape.childPoints;
|
||
|
var childLen = childPoints.length;
|
||
|
var parentPoint = shape.parentPoint;
|
||
|
var firstChildPos = childPoints[0];
|
||
|
var lastChildPos = childPoints[childLen - 1];
|
||
|
|
||
|
if (childLen === 1) {
|
||
|
ctx.moveTo(parentPoint[0], parentPoint[1]);
|
||
|
ctx.lineTo(firstChildPos[0], firstChildPos[1]);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var orient = shape.orient;
|
||
|
var forkDim = orient === 'TB' || orient === 'BT' ? 0 : 1;
|
||
|
var otherDim = 1 - forkDim;
|
||
|
var forkPosition = parsePercent(shape.forkPosition, 1);
|
||
|
var tmpPoint = [];
|
||
|
tmpPoint[forkDim] = parentPoint[forkDim];
|
||
|
tmpPoint[otherDim] = parentPoint[otherDim] + (lastChildPos[otherDim] - parentPoint[otherDim]) * forkPosition;
|
||
|
ctx.moveTo(parentPoint[0], parentPoint[1]);
|
||
|
ctx.lineTo(tmpPoint[0], tmpPoint[1]);
|
||
|
ctx.moveTo(firstChildPos[0], firstChildPos[1]);
|
||
|
tmpPoint[forkDim] = firstChildPos[forkDim];
|
||
|
ctx.lineTo(tmpPoint[0], tmpPoint[1]);
|
||
|
tmpPoint[forkDim] = lastChildPos[forkDim];
|
||
|
ctx.lineTo(tmpPoint[0], tmpPoint[1]);
|
||
|
ctx.lineTo(lastChildPos[0], lastChildPos[1]);
|
||
|
|
||
|
for (var i = 1; i < childLen - 1; i++) {
|
||
|
var point = childPoints[i];
|
||
|
ctx.moveTo(point[0], point[1]);
|
||
|
tmpPoint[forkDim] = point[forkDim];
|
||
|
ctx.lineTo(tmpPoint[0], tmpPoint[1]);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var _default = echarts.extendChartView({
|
||
|
type: 'tree',
|
||
|
|
||
|
/**
|
||
|
* 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();
|
||
|
/**
|
||
|
* @private
|
||
|
* @type {module:echarts/componet/helper/RoamController}
|
||
|
*/
|
||
|
|
||
|
this._controller = new RoamController(api.getZr());
|
||
|
this._controllerHost = {
|
||
|
target: this.group
|
||
|
};
|
||
|
this.group.add(this._mainGroup);
|
||
|
},
|
||
|
render: function (seriesModel, ecModel, api, payload) {
|
||
|
var data = seriesModel.getData();
|
||
|
var layoutInfo = seriesModel.layoutInfo;
|
||
|
var group = this._mainGroup;
|
||
|
var layout = seriesModel.get('layout');
|
||
|
|
||
|
if (layout === 'radial') {
|
||
|
group.attr('position', [layoutInfo.x + layoutInfo.width / 2, layoutInfo.y + layoutInfo.height / 2]);
|
||
|
} else {
|
||
|
group.attr('position', [layoutInfo.x, layoutInfo.y]);
|
||
|
}
|
||
|
|
||
|
this._updateViewCoordSys(seriesModel, layoutInfo, layout);
|
||
|
|
||
|
this._updateController(seriesModel, ecModel, api);
|
||
|
|
||
|
var oldData = this._data;
|
||
|
var seriesScope = {
|
||
|
expandAndCollapse: seriesModel.get('expandAndCollapse'),
|
||
|
layout: layout,
|
||
|
edgeShape: seriesModel.get('edgeShape'),
|
||
|
edgeForkPosition: seriesModel.get('edgeForkPosition'),
|
||
|
orient: seriesModel.getOrient(),
|
||
|
curvature: seriesModel.get('lineStyle.curveness'),
|
||
|
symbolRotate: seriesModel.get('symbolRotate'),
|
||
|
symbolOffset: seriesModel.get('symbolOffset'),
|
||
|
hoverAnimation: seriesModel.get('hoverAnimation'),
|
||
|
useNameLabel: true,
|
||
|
fadeIn: true
|
||
|
};
|
||
|
data.diff(oldData).add(function (newIdx) {
|
||
|
if (symbolNeedsDraw(data, newIdx)) {
|
||
|
// Create node and edge
|
||
|
updateNode(data, newIdx, null, group, seriesModel, seriesScope);
|
||
|
}
|
||
|
}).update(function (newIdx, oldIdx) {
|
||
|
var symbolEl = oldData.getItemGraphicEl(oldIdx);
|
||
|
|
||
|
if (!symbolNeedsDraw(data, newIdx)) {
|
||
|
symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel, seriesScope);
|
||
|
return;
|
||
|
} // Update node and edge
|
||
|
|
||
|
|
||
|
updateNode(data, newIdx, symbolEl, group, seriesModel, seriesScope);
|
||
|
}).remove(function (oldIdx) {
|
||
|
var symbolEl = oldData.getItemGraphicEl(oldIdx); // When remove a collapsed node of subtree, since the collapsed
|
||
|
// node haven't been initialized with a symbol element,
|
||
|
// you can't found it's symbol element through index.
|
||
|
// so if we want to remove the symbol element we should insure
|
||
|
// that the symbol element is not null.
|
||
|
|
||
|
if (symbolEl) {
|
||
|
removeNode(oldData, oldIdx, symbolEl, group, seriesModel, seriesScope);
|
||
|
}
|
||
|
}).execute();
|
||
|
this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');
|
||
|
|
||
|
this._updateNodeAndLinkScale(seriesModel);
|
||
|
|
||
|
if (seriesScope.expandAndCollapse === true) {
|
||
|
data.eachItemGraphicEl(function (el, dataIndex) {
|
||
|
el.off('click').on('click', function () {
|
||
|
api.dispatchAction({
|
||
|
type: 'treeExpandAndCollapse',
|
||
|
seriesId: seriesModel.id,
|
||
|
dataIndex: dataIndex
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
this._data = data;
|
||
|
},
|
||
|
_updateViewCoordSys: function (seriesModel) {
|
||
|
var data = seriesModel.getData();
|
||
|
var points = [];
|
||
|
data.each(function (idx) {
|
||
|
var layout = data.getItemLayout(idx);
|
||
|
|
||
|
if (layout && !isNaN(layout.x) && !isNaN(layout.y)) {
|
||
|
points.push([+layout.x, +layout.y]);
|
||
|
}
|
||
|
});
|
||
|
var min = [];
|
||
|
var max = [];
|
||
|
bbox.fromPoints(points, min, max); // If don't Store min max when collapse the root node after roam,
|
||
|
// the root node will disappear.
|
||
|
|
||
|
var oldMin = this._min;
|
||
|
var oldMax = this._max; // If width or height is 0
|
||
|
|
||
|
if (max[0] - min[0] === 0) {
|
||
|
min[0] = oldMin ? oldMin[0] : min[0] - 1;
|
||
|
max[0] = oldMax ? oldMax[0] : max[0] + 1;
|
||
|
}
|
||
|
|
||
|
if (max[1] - min[1] === 0) {
|
||
|
min[1] = oldMin ? oldMin[1] : min[1] - 1;
|
||
|
max[1] = oldMax ? oldMax[1] : max[1] + 1;
|
||
|
}
|
||
|
|
||
|
var viewCoordSys = seriesModel.coordinateSystem = new View();
|
||
|
viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');
|
||
|
viewCoordSys.setBoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
|
||
|
viewCoordSys.setCenter(seriesModel.get('center'));
|
||
|
viewCoordSys.setZoom(seriesModel.get('zoom')); // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group
|
||
|
|
||
|
this.group.attr({
|
||
|
position: viewCoordSys.position,
|
||
|
scale: viewCoordSys.scale
|
||
|
});
|
||
|
this._viewCoordSys = viewCoordSys;
|
||
|
this._min = min;
|
||
|
this._max = max;
|
||
|
},
|
||
|
_updateController: function (seriesModel, ecModel, api) {
|
||
|
var controller = this._controller;
|
||
|
var controllerHost = this._controllerHost;
|
||
|
var group = this.group;
|
||
|
controller.setPointerChecker(function (e, x, y) {
|
||
|
var rect = group.getBoundingRect();
|
||
|
rect.applyTransform(group.transform);
|
||
|
return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel);
|
||
|
});
|
||
|
controller.enable(seriesModel.get('roam'));
|
||
|
controllerHost.zoomLimit = seriesModel.get('scaleLimit');
|
||
|
controllerHost.zoom = seriesModel.coordinateSystem.getZoom();
|
||
|
controller.off('pan').off('zoom').on('pan', function (e) {
|
||
|
roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
|
||
|
api.dispatchAction({
|
||
|
seriesId: seriesModel.id,
|
||
|
type: 'treeRoam',
|
||
|
dx: e.dx,
|
||
|
dy: e.dy
|
||
|
});
|
||
|
}, this).on('zoom', function (e) {
|
||
|
roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
|
||
|
api.dispatchAction({
|
||
|
seriesId: seriesModel.id,
|
||
|
type: 'treeRoam',
|
||
|
zoom: e.scale,
|
||
|
originX: e.originX,
|
||
|
originY: e.originY
|
||
|
});
|
||
|
|
||
|
this._updateNodeAndLinkScale(seriesModel);
|
||
|
}, this);
|
||
|
},
|
||
|
_updateNodeAndLinkScale: function (seriesModel) {
|
||
|
var data = seriesModel.getData();
|
||
|
|
||
|
var nodeScale = this._getNodeGlobalScale(seriesModel);
|
||
|
|
||
|
var invScale = [nodeScale, nodeScale];
|
||
|
data.eachItemGraphicEl(function (el, idx) {
|
||
|
el.attr('scale', invScale);
|
||
|
});
|
||
|
},
|
||
|
_getNodeGlobalScale: function (seriesModel) {
|
||
|
var coordSys = seriesModel.coordinateSystem;
|
||
|
|
||
|
if (coordSys.type !== 'view') {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
var nodeScaleRatio = this._nodeScaleRatio;
|
||
|
var groupScale = coordSys.scale;
|
||
|
var groupZoom = groupScale && groupScale[0] || 1; // Scale node when zoom changes
|
||
|
|
||
|
var roamZoom = coordSys.getZoom();
|
||
|
var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
|
||
|
return nodeScale / groupZoom;
|
||
|
},
|
||
|
dispose: function () {
|
||
|
this._controller && this._controller.dispose();
|
||
|
this._controllerHost = {};
|
||
|
},
|
||
|
remove: function () {
|
||
|
this._mainGroup.removeAll();
|
||
|
|
||
|
this._data = null;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
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').getItemStyle();
|
||
|
seriesScope.hoverItemStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();
|
||
|
seriesScope.lineStyle = itemModel.getModel('lineStyle').getLineStyle();
|
||
|
seriesScope.labelModel = itemModel.getModel('label');
|
||
|
seriesScope.hoverLabelModel = itemModel.getModel('emphasis.label');
|
||
|
|
||
|
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) {
|
||
|
var isInit = !symbolEl;
|
||
|
var node = data.tree.getNodeByDataIndex(dataIndex);
|
||
|
var itemModel = node.getModel();
|
||
|
var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope);
|
||
|
var virtualRoot = data.tree.root;
|
||
|
var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
|
||
|
var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
|
||
|
var sourceLayout = source.getLayout();
|
||
|
var sourceOldLayout = sourceSymbolEl ? {
|
||
|
x: sourceSymbolEl.position[0],
|
||
|
y: sourceSymbolEl.position[1],
|
||
|
rawX: sourceSymbolEl.__radialOldRawX,
|
||
|
rawY: sourceSymbolEl.__radialOldRawY
|
||
|
} : sourceLayout;
|
||
|
var targetLayout = node.getLayout();
|
||
|
|
||
|
if (isInit) {
|
||
|
symbolEl = new SymbolClz(data, dataIndex, seriesScope);
|
||
|
symbolEl.attr('position', [sourceOldLayout.x, sourceOldLayout.y]);
|
||
|
} else {
|
||
|
symbolEl.updateData(data, dataIndex, seriesScope);
|
||
|
}
|
||
|
|
||
|
symbolEl.__radialOldRawX = symbolEl.__radialRawX;
|
||
|
symbolEl.__radialOldRawY = symbolEl.__radialRawY;
|
||
|
symbolEl.__radialRawX = targetLayout.rawX;
|
||
|
symbolEl.__radialRawY = targetLayout.rawY;
|
||
|
group.add(symbolEl);
|
||
|
data.setItemGraphicEl(dataIndex, symbolEl);
|
||
|
graphic.updateProps(symbolEl, {
|
||
|
position: [targetLayout.x, targetLayout.y]
|
||
|
}, seriesModel);
|
||
|
var symbolPath = symbolEl.getSymbolPath();
|
||
|
|
||
|
if (seriesScope.layout === 'radial') {
|
||
|
var realRoot = virtualRoot.children[0];
|
||
|
var rootLayout = realRoot.getLayout();
|
||
|
var length = realRoot.children.length;
|
||
|
var rad;
|
||
|
var isLeft;
|
||
|
|
||
|
if (targetLayout.x === rootLayout.x && node.isExpand === true) {
|
||
|
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;
|
||
|
|
||
|
if (isLeft) {
|
||
|
rad = rad - Math.PI;
|
||
|
}
|
||
|
} else {
|
||
|
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;
|
||
|
}
|
||
|
} else {
|
||
|
isLeft = targetLayout.x > rootLayout.x;
|
||
|
|
||
|
if (!isLeft) {
|
||
|
rad = rad - Math.PI;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var textPosition = isLeft ? 'left' : 'right';
|
||
|
var rotate = seriesScope.labelModel.get('rotate');
|
||
|
var labelRotateRadian = rotate * (Math.PI / 180);
|
||
|
symbolPath.setStyle({
|
||
|
textPosition: seriesScope.labelModel.get('position') || textPosition,
|
||
|
textRotation: rotate == null ? -rad : labelRotateRadian,
|
||
|
textOrigin: 'center',
|
||
|
verticalAlign: 'middle'
|
||
|
});
|
||
|
}
|
||
|
|
||
|
drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group, seriesScope);
|
||
|
}
|
||
|
|
||
|
function drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group, seriesScope) {
|
||
|
var edgeShape = seriesScope.edgeShape;
|
||
|
var edge = symbolEl.__edge;
|
||
|
|
||
|
if (edgeShape === 'curve') {
|
||
|
if (node.parentNode && node.parentNode !== virtualRoot) {
|
||
|
if (!edge) {
|
||
|
edge = symbolEl.__edge = new graphic.BezierCurve({
|
||
|
shape: getEdgeShape(seriesScope, sourceOldLayout, sourceOldLayout),
|
||
|
style: zrUtil.defaults({
|
||
|
opacity: 0,
|
||
|
strokeNoScale: true
|
||
|
}, seriesScope.lineStyle)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
graphic.updateProps(edge, {
|
||
|
shape: getEdgeShape(seriesScope, sourceLayout, targetLayout),
|
||
|
style: zrUtil.defaults({
|
||
|
opacity: 1
|
||
|
}, seriesScope.lineStyle)
|
||
|
}, seriesModel);
|
||
|
}
|
||
|
} else if (edgeShape === 'polyline') {
|
||
|
if (seriesScope.layout === 'orthogonal') {
|
||
|
if (node !== virtualRoot && node.children && node.children.length !== 0 && node.isExpand === true) {
|
||
|
var children = node.children;
|
||
|
var childPoints = [];
|
||
|
|
||
|
for (var i = 0; i < children.length; i++) {
|
||
|
var childLayout = children[i].getLayout();
|
||
|
childPoints.push([childLayout.x, childLayout.y]);
|
||
|
}
|
||
|
|
||
|
if (!edge) {
|
||
|
edge = symbolEl.__edge = new TreeShape({
|
||
|
shape: {
|
||
|
parentPoint: [targetLayout.x, targetLayout.y],
|
||
|
childPoints: [[targetLayout.x, targetLayout.y]],
|
||
|
orient: seriesScope.orient,
|
||
|
forkPosition: seriesScope.edgeForkPosition
|
||
|
},
|
||
|
style: zrUtil.defaults({
|
||
|
opacity: 0,
|
||
|
strokeNoScale: true
|
||
|
}, seriesScope.lineStyle)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
graphic.updateProps(edge, {
|
||
|
shape: {
|
||
|
parentPoint: [targetLayout.x, targetLayout.y],
|
||
|
childPoints: childPoints
|
||
|
},
|
||
|
style: zrUtil.defaults({
|
||
|
opacity: 1
|
||
|
}, seriesScope.lineStyle)
|
||
|
}, seriesModel);
|
||
|
}
|
||
|
} else {}
|
||
|
}
|
||
|
|
||
|
group.add(edge);
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
|
||
|
var edgeShape = seriesScope.edgeShape;
|
||
|
var sourceLayout;
|
||
|
|
||
|
while (sourceLayout = source.getLayout(), sourceLayout == null) {
|
||
|
source = source.parentNode === virtualRoot ? source : source.parentNode || source;
|
||
|
}
|
||
|
|
||
|
graphic.updateProps(symbolEl, {
|
||
|
position: [sourceLayout.x + 1, sourceLayout.y + 1]
|
||
|
}, seriesModel, function () {
|
||
|
group.remove(symbolEl);
|
||
|
data.setItemGraphicEl(dataIndex, null);
|
||
|
});
|
||
|
symbolEl.fadeOut(null, {
|
||
|
keepLabel: true
|
||
|
});
|
||
|
var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
|
||
|
var sourceEdge = sourceSymbolEl.__edge; // 1. when expand the sub tree, delete the children node should delete the edge of
|
||
|
// the source at the same time. because the polyline edge shape is only owned by the source.
|
||
|
// 2.when the node is the only children of the source, delete the node should delete the edge of
|
||
|
// the source at the same time. the same reason as above.
|
||
|
|
||
|
var edge = symbolEl.__edge || (source.isExpand === false || source.children.length === 1 ? sourceEdge : undefined);
|
||
|
var edgeShape = seriesScope.edgeShape;
|
||
|
|
||
|
if (edge) {
|
||
|
if (edgeShape === 'curve') {
|
||
|
graphic.updateProps(edge, {
|
||
|
shape: getEdgeShape(seriesScope, sourceLayout, sourceLayout),
|
||
|
style: {
|
||
|
opacity: 0
|
||
|
}
|
||
|
}, seriesModel, function () {
|
||
|
group.remove(edge);
|
||
|
});
|
||
|
} else if (edgeShape === 'polyline' && seriesScope.layout === 'orthogonal') {
|
||
|
graphic.updateProps(edge, {
|
||
|
shape: {
|
||
|
parentPoint: [sourceLayout.x, sourceLayout.y],
|
||
|
childPoints: [[sourceLayout.x, sourceLayout.y]]
|
||
|
},
|
||
|
style: {
|
||
|
opacity: 0
|
||
|
}
|
||
|
}, seriesModel, function () {
|
||
|
group.remove(edge);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getEdgeShape(seriesScope, sourceLayout, targetLayout) {
|
||
|
var cpx1;
|
||
|
var cpy1;
|
||
|
var cpx2;
|
||
|
var cpy2;
|
||
|
var orient = seriesScope.orient;
|
||
|
var x1;
|
||
|
var x2;
|
||
|
var y1;
|
||
|
var y2;
|
||
|
|
||
|
if (seriesScope.layout === 'radial') {
|
||
|
x1 = sourceLayout.rawX;
|
||
|
y1 = sourceLayout.rawY;
|
||
|
x2 = targetLayout.rawX;
|
||
|
y2 = targetLayout.rawY;
|
||
|
var radialCoor1 = radialCoordinate(x1, y1);
|
||
|
var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * seriesScope.curvature);
|
||
|
var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * seriesScope.curvature);
|
||
|
var radialCoor4 = radialCoordinate(x2, y2);
|
||
|
return {
|
||
|
x1: radialCoor1.x,
|
||
|
y1: radialCoor1.y,
|
||
|
x2: radialCoor4.x,
|
||
|
y2: radialCoor4.y,
|
||
|
cpx1: radialCoor2.x,
|
||
|
cpy1: radialCoor2.y,
|
||
|
cpx2: radialCoor3.x,
|
||
|
cpy2: radialCoor3.y
|
||
|
};
|
||
|
} else {
|
||
|
x1 = sourceLayout.x;
|
||
|
y1 = sourceLayout.y;
|
||
|
x2 = targetLayout.x;
|
||
|
y2 = targetLayout.y;
|
||
|
|
||
|
if (orient === 'LR' || orient === 'RL') {
|
||
|
cpx1 = x1 + (x2 - x1) * seriesScope.curvature;
|
||
|
cpy1 = y1;
|
||
|
cpx2 = x2 + (x1 - x2) * seriesScope.curvature;
|
||
|
cpy2 = y2;
|
||
|
}
|
||
|
|
||
|
if (orient === 'TB' || orient === 'BT') {
|
||
|
cpx1 = x1;
|
||
|
cpy1 = y1 + (y2 - y1) * seriesScope.curvature;
|
||
|
cpx2 = x2;
|
||
|
cpy2 = y2 + (y1 - y2) * seriesScope.curvature;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
x1: x1,
|
||
|
y1: y1,
|
||
|
x2: x2,
|
||
|
y2: y2,
|
||
|
cpx1: cpx1,
|
||
|
cpy1: cpy1,
|
||
|
cpx2: cpx2,
|
||
|
cpy2: cpy2
|
||
|
};
|
||
|
}
|
||
|
|
||
|
module.exports = _default;
|