-
Notifications
You must be signed in to change notification settings - Fork 19.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add polyline edge layout for the tree series #7090 #11808
Changes from 1 commit
ba002d2
3b63439
9b8f59a
bf61955
7e6ada8
66119d3
ecfda9a
6e570cc
185b880
07f2d70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,81 @@ import * as roamHelper from '../../component/helper/roamHelper'; | |
import RoamController from '../../component/helper/RoamController'; | ||
import {onIrrelevantElement} from '../../component/helper/cursorHelper'; | ||
|
||
var TreeShape = graphic.extendShape({ | ||
shape: { | ||
parentPoint: [], | ||
childPoints: [], | ||
orient: '' | ||
}, | ||
|
||
buildPath: function (ctx, shape) { | ||
var ptMin = [Infinity, Infinity]; | ||
var ptMax = [-Infinity, -Infinity]; | ||
var points = shape.childPoints; | ||
for (var i = 0; i < points.length; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think buildPath: function (ctx, shape) {
var childPoints = shape.childPoints;
var parentPoint = shape.parentPoint;
var childLen = childPoints.length;
var firstChildPos = childPoints[1];
var lastChildPos = childPoints[childLen - 1];
if (!childLen || !parentPoint) {
return;
}
if (childLen === 1) {
ctx.moveTo(firstChildPos[0], firstChildPos[1]);
ctx.lineTo(parentPoint[0], parentPoint[1]);
return;
}
var forkDim = (orient === 'TB' || orient === 'BT') ? 1 : 0;
var otherDim = 1 - forkDim;
var forkPosition = parsePercent(shape.forkPosition, 1);
var tmpPt = [];
ctx.moveTo(parentPoint[0], parentPoint[1]);
tmpPt[forkDim] = parentPoint[forkDim] + (firstChildPos[forkDim] - parentPoint[forkDim]) * forkPosition;
tmpPt[otherDim] = parentPoint[otherDim];
ctx.lineTo(tmpPt[0], tmpPt[1]);
ctx.moveTo(firstChildPos[0], firstChildPos[1]);
tmpPt[otherDim] = firstChildPos[otherDim];
ctx.lineTo(tmpPt[0], tmpPt[1]);
tmpPt[otherDim] = lastChildPos[otherDim];
ctx.lineTo(tmpPt[0], tmpPt[1]);
ctx.lineTo(lastChildPos[0], lastChildPos[1]);
for (var i = 1; i < childLen - 1; i++) {
var childPos = childPoints[i];
ctx.moveTo(childPos[0], childPos[1]);
tmpPt[otherDim] = childPos[otherDim];
ctx.lineTo(tmpPt[0], tmpPt[1]);
}
} |
||
var pt = points[i]; | ||
if (pt[0] < ptMin[0]) { | ||
ptMin[0] = pt[0]; | ||
} | ||
if (pt[0] > ptMax[0]) { | ||
ptMax[0] = pt[0]; | ||
} | ||
if (pt[1] < ptMin[1]) { | ||
ptMin[1] = pt[1]; | ||
} | ||
if (pt[1] > ptMax[1]) { | ||
ptMax[1] = pt[1]; | ||
} | ||
} | ||
var parentPoint = shape.parentPoint; | ||
var orient = shape.orient; | ||
var midPoint = computeMidPoints(parentPoint, orient, ptMax); | ||
|
||
ctx.moveTo(parentPoint[0], parentPoint[1]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrong indent |
||
ctx.lineTo(midPoint[0], midPoint[1]); | ||
if (orient === 'TB' || orient === 'BT') { | ||
ctx.moveTo(ptMin[0], midPoint[1]); | ||
ctx.lineTo(ptMax[0], midPoint[1]); | ||
} | ||
else if (orient === 'LR' || orient === 'RL') { | ||
ctx.moveTo(midPoint[0], ptMin[1]); | ||
ctx.lineTo(midPoint[0], ptMax[1]); | ||
} | ||
for (var i = 0; i < points.length; i++) { | ||
var point = points[i]; | ||
ctx.moveTo(point[0], point[1]); | ||
if (orient === 'TB' || orient === 'BT') { | ||
ctx.lineTo(point[0], midPoint[1]); | ||
} | ||
else if (orient === 'LR' || orient === 'RL') { | ||
ctx.lineTo(midPoint[0], point[1]); | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Top and bottom horizontal lines are better to be connected with the vertical line. ctx.moveTo(); // top line end point
ctx.lineTo(); // top line connect point
ctx.lineTo(); // bottom line connect point
ctx.lineTo(); // bottom line end point It will have a nicer corner than current if the line is thicker. |
||
}); | ||
|
||
function computeMidPoints(parentPoint, orient, ptMax) { | ||
var midPoint = []; | ||
switch (orient) { | ||
case 'TB': | ||
midPoint[0] = parentPoint[0]; | ||
midPoint[1] = parentPoint[1] + (ptMax[1] - parentPoint[1]) / 2; | ||
break; | ||
case 'BT': | ||
midPoint[0] = parentPoint[0]; | ||
midPoint[1] = ptMax[1] + (parentPoint[1] - ptMax[1]) / 2; | ||
break; | ||
case 'LR': | ||
midPoint[0] = parentPoint[0] + (ptMax[0] - parentPoint[0]) / 2; | ||
midPoint[1] = parentPoint[1]; | ||
break; | ||
case 'RL': | ||
midPoint[0] = ptMax[0] + (parentPoint[0] - ptMax[0]) / 2; | ||
midPoint[1] = parentPoint[1]; | ||
} | ||
return midPoint; | ||
} | ||
|
||
export default echarts.extendChartView({ | ||
|
||
type: 'tree', | ||
|
@@ -87,6 +162,7 @@ export default echarts.extendChartView({ | |
var seriesScope = { | ||
expandAndCollapse: seriesModel.get('expandAndCollapse'), | ||
layout: layout, | ||
edgeLayout: seriesModel.get('edgeLayout'), | ||
orient: seriesModel.getOrient(), | ||
curvature: seriesModel.get('lineStyle.curveness'), | ||
symbolRotate: seriesModel.get('symbolRotate'), | ||
|
@@ -388,22 +464,64 @@ function updateNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) | |
}); | ||
} | ||
|
||
if (node.parentNode && node.parentNode !== virtualRoot) { | ||
drawEdge( | ||
seriesModel, node, virtualRoot, symbolEl, | ||
sourceOldLayout, sourceLayout, targetLayout, group, seriesScope | ||
); | ||
|
||
} | ||
|
||
function drawEdge( | ||
seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, | ||
targetLayout, group, seriesScope | ||
) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The indent is not good. The back brace should better align with the start of the sentence |
||
var edgeLayout = seriesScope.edgeLayout; | ||
var edge = symbolEl.__edge; | ||
if (!edge) { | ||
edge = symbolEl.__edge = new graphic.BezierCurve({ | ||
shape: getEdgeShape(seriesScope, sourceOldLayout, sourceOldLayout), | ||
style: zrUtil.defaults({opacity: 0, strokeNoScale: true}, seriesScope.lineStyle) | ||
}); | ||
} | ||
if (edgeLayout === '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: {opacity: 1} | ||
}, seriesModel); | ||
graphic.updateProps(edge, { | ||
shape: getEdgeShape(seriesScope, sourceLayout, targetLayout), | ||
style: {opacity: 1} | ||
}, seriesModel); | ||
} | ||
} | ||
else if (edgeLayout === 'polyline' && 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 layout = children[i].getLayout(); | ||
childPoints.push([layout.x, layout.y]); | ||
} | ||
|
||
if (!edge) { | ||
edge = symbolEl.__edge = new TreeShape({ | ||
shape: { | ||
parentPoint: [targetLayout.x, targetLayout.y], | ||
childPoints: [[targetLayout.x, targetLayout.y]], | ||
orient: seriesScope.orient | ||
}, | ||
style: zrUtil.defaults({opacity: 0, strokeNoScale: true}, seriesScope.lineStyle) | ||
}); | ||
} | ||
graphic.updateProps(edge, { | ||
shape: { | ||
parentPoint: [targetLayout.x, targetLayout.y], | ||
childPoints: childPoints, | ||
orient: seriesScope.orient | ||
}, | ||
style: {opacity: 1} | ||
}, seriesModel); | ||
} | ||
} | ||
group.add(edge); | ||
} | ||
} | ||
|
||
function removeNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) { | ||
|
@@ -413,6 +531,7 @@ function removeNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) | |
var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope); | ||
|
||
var source = node.parentNode === virtualRoot ? node : node.parentNode || node; | ||
var edgeLayout = seriesScope.edgeLayout; | ||
var sourceLayout; | ||
while (sourceLayout = source.getLayout(), sourceLayout == null) { | ||
source = source.parentNode === virtualRoot ? source : source.parentNode || source; | ||
|
@@ -427,16 +546,60 @@ function removeNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) | |
|
||
symbolEl.fadeOut(null, {keepLabel: true}); | ||
|
||
var edge = symbolEl.__edge; | ||
var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex); | ||
var sourceEdge = sourceSymbolEl.__edge; | ||
var edge = symbolEl.__edge || (source.isExpand === false ? sourceEdge : undefined); | ||
var edgeLayout = seriesScope.edgeLayout; | ||
|
||
if (edge) { | ||
graphic.updateProps(edge, { | ||
shape: getEdgeShape(seriesScope, sourceLayout, sourceLayout), | ||
if (edgeLayout === 'curve') { | ||
graphic.updateProps(edge, { | ||
shape: getEdgeShape(seriesScope, sourceLayout, sourceLayout), | ||
style: { | ||
opacity: 0 | ||
} | ||
}, seriesModel, function () { | ||
group.remove(edge); | ||
}); | ||
} | ||
else if (edgeLayout === 'polyline' && seriesScope.layout === 'orthogonal') { | ||
graphic.updateProps(edge, { | ||
shape: { | ||
parentPoint: [sourceLayout.x, sourceLayout.y], | ||
childPoints: [[sourceLayout.x, sourceLayout.y]], | ||
orient: seriesScope.orient | ||
}, | ||
style: { | ||
opacity: 0 | ||
} | ||
}, seriesModel, function () { | ||
group.remove(edge); | ||
}); | ||
} | ||
} | ||
else if (sourceEdge) { | ||
var filterChilPoints = []; | ||
var children = source.children; | ||
for (var i = 0; i < children.length; i++) { | ||
if (children[i] !== node) { | ||
var nodeLayout = children[i].getLayout(); | ||
filterChilPoints.push([nodeLayout.x, nodeLayout.y]); | ||
} | ||
} | ||
graphic.updateProps(sourceEdge, { | ||
shape: { | ||
parentPoint: [sourceLayout.x, sourceLayout.y], | ||
childPoints: filterChilPoints, | ||
orient: seriesScope.orient | ||
}, | ||
style: { | ||
opacity: 0 | ||
opacity: 1 | ||
} | ||
}, seriesModel, function () { | ||
group.remove(edge); | ||
}); | ||
}, seriesModel); | ||
|
||
graphic.updateProps(sourceSymbolEl, { | ||
position: [sourceLayout.x, sourceLayout.y] | ||
}, seriesModel); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think
edgeShape
is better.edgeLayout
is more like theposition
of edgeThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, good suggestion!