@xiaomengqiang/charts
Version:
hcharts library for web visualization
336 lines (325 loc) • 12.2 kB
JavaScript
/**
* Copyright (c) 2024 - present OpenTiny HUICharts Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
var VDirection = ['TB', 'BT', 'V'];
// 圆角曲线连线
var LineRound = /*#__PURE__*/function () {
function LineRound(option) {
// 默认圆弧拐角的 radius 为 20
this.radius = 10;
// 连线向前多少开始拐弯
this.dis = 15;
// 直角拐点占水平距离的百分比
this.lineDistance = 0.5;
this.radius = option.radius === undefined ? this.radius : option.radius;
this.lineDistance = option.lineDistance || 0.5;
}
/**
* 以lineRound作为试点,连线有两种对齐方式:
* 1. 默认为向后对齐,即向target节点对齐,优先级低
* 2. 然后再将source节点出来的连线向前对齐,优先级高
*/
var _proto = LineRound.prototype;
_proto.setData = function setData(edge, data, direction) {
if (VDirection.indexOf(direction) !== -1) {
if (edge.alignType == 'target') {
this.setTargetDataV(edge, data);
} else if (edge.alignType == 'source') {
this.setSourceDataV(edge, data);
}
} else {
if (edge.alignType == 'target') {
this.setTargetData(edge, data);
} else if (edge.alignType == 'source') {
this.setSourceData(edge, data);
}
}
}
// 计算出以目标节点为对齐方式的连线数据
;
_proto.setTargetData = function setTargetData(targetEdge, data) {
var end = targetEdge.target;
var start = targetEdge.source;
var nodesObj = data.nodesObj;
var startWidth = nodesObj[start].width || 50;
var startInnerWidth = nodesObj[start].innerWidth || 50;
var startHeight = nodesObj[start].height || 50;
var endWidth = nodesObj[end].width || 50;
var endInnerWidth = nodesObj[end].innerWidth || 50;
var endHeight = nodesObj[end].height || 50;
// 拐角半径
targetEdge.radius = this.radius;
// 起始点
targetEdge.startPoint = {
x: nodesObj[start].x + startWidth + (startInnerWidth - startWidth) / 2 - data.minX,
y: nodesObj[start].y + startHeight / 2 - data.minY
};
// 结束点
targetEdge.endPoint = {
x: nodesObj[end].x - (endInnerWidth - endWidth) / 2 - data.minX,
y: nodesObj[end].y + endHeight / 2 - data.minY
};
var vDis = targetEdge.endPoint.y - targetEdge.startPoint.y;
// endPoint向左距离20点位置开始绘制曲线
var hDis = this.dis;
// radius 根据 vDis 大小而动态调整
if (Math.abs(vDis) <= this.radius * 2) {
targetEdge.radius = Math.abs(vDis) / 2;
}
var revise = targetEdge.radius;
// 当end节点在start节点下方时,个别点的位置需要修正
if (targetEdge.endPoint.y < targetEdge.startPoint.y) {
revise = -targetEdge.radius;
}
// 第一个圆弧起始点
targetEdge.firstRoundStartPoint = {
x: targetEdge.endPoint.x - hDis - targetEdge.radius * 2,
y: targetEdge.startPoint.y
};
// 第一个圆弧控制点
targetEdge.firstRoundControlPoint = {
x: targetEdge.endPoint.x - hDis - targetEdge.radius,
y: targetEdge.startPoint.y
};
// 第一个圆弧结束点
targetEdge.firstRoundEndPoint = {
x: targetEdge.endPoint.x - hDis - targetEdge.radius,
y: targetEdge.startPoint.y + revise
};
// 第二个圆弧起始点
targetEdge.secondRoundStartPoint = {
x: targetEdge.endPoint.x - hDis - targetEdge.radius,
y: targetEdge.endPoint.y - revise
};
// 第二个圆弧控制点
targetEdge.secondRoundControlPoint = {
x: targetEdge.endPoint.x - hDis - targetEdge.radius,
y: targetEdge.endPoint.y
};
// 第二个圆弧结束点
targetEdge.secondRoundEndPoint = {
x: targetEdge.endPoint.x - hDis,
y: targetEdge.endPoint.y
};
}
// 计算出以源头节点为对齐方式的连线数据
;
_proto.setSourceData = function setSourceData(edge, data) {
var end = edge.target;
var start = edge.source;
var nodesObj = data.nodesObj;
var startWidth = nodesObj[start].width || 50;
var startInnerWidth = nodesObj[start].innerWidth || 50;
var startHeight = nodesObj[start].height || 50;
var endWidth = nodesObj[end].width || 50;
var endInnerWidth = nodesObj[end].innerWidth || 50;
var endHeight = nodesObj[end].height || 50;
// 拐角半径
edge.radius = this.radius;
// 起始点
edge.startPoint = {
x: nodesObj[start].x + startWidth + (startInnerWidth - startWidth) / 2 - data.minX,
y: nodesObj[start].y + startHeight / 2 - data.minY
};
// 结束点
edge.endPoint = {
x: nodesObj[end].x - (endInnerWidth - endWidth) / 2 - data.minX,
y: nodesObj[end].y + endHeight / 2 - data.minY
};
var vDis = edge.endPoint.y - edge.startPoint.y;
// endPoint向左距离20点位置开始绘制曲线
var hDis = this.dis;
// radius 根据 vDis 大小而动态调整
if (Math.abs(vDis) <= this.radius * 2) {
edge.radius = Math.abs(vDis) / 2;
}
var revise = edge.radius;
// 当end节点在start节点下方时,个别点的位置需要修正
if (edge.endPoint.y < edge.startPoint.y) {
revise = -edge.radius;
}
// 第一个圆弧起始点
edge.firstRoundStartPoint = {
x: edge.startPoint.x + hDis,
y: edge.startPoint.y
};
// 第一个圆弧控制点
edge.firstRoundControlPoint = {
x: edge.startPoint.x + hDis + edge.radius,
y: edge.startPoint.y
};
// 第一个圆弧结束点
edge.firstRoundEndPoint = {
x: edge.startPoint.x + hDis + edge.radius,
y: edge.startPoint.y + revise
};
// 第二个圆弧起始点
edge.secondRoundStartPoint = {
x: edge.startPoint.x + hDis + edge.radius,
y: edge.endPoint.y - revise
};
// 第二个圆弧控制点
edge.secondRoundControlPoint = {
x: edge.startPoint.x + hDis + edge.radius,
y: edge.endPoint.y
};
// 第二个圆弧结束点
edge.secondRoundEndPoint = {
x: edge.startPoint.x + hDis + edge.radius * 2,
y: edge.endPoint.y
};
}
// 计算出以目标节点为对齐方式的连线数据 --- 纵向
;
_proto.setTargetDataV = function setTargetDataV(targetEdge, data) {
var end = targetEdge.target;
var start = targetEdge.source;
var nodesObj = data.nodesObj;
var startWidth = nodesObj[start].width || 50;
var startInnerHeight = nodesObj[start].innerHeight || 50;
var startHeight = nodesObj[start].height || 50;
var endWidth = nodesObj[end].width || 50;
var endInnerHeight = nodesObj[end].innerHeight || 50;
var endHeight = nodesObj[end].height || 50;
// 拐角半径
targetEdge.radius = this.radius;
// 起始点
targetEdge.startPoint = {
x: nodesObj[start].x + startWidth / 2 - data.minX,
y: nodesObj[start].y + startHeight + (startInnerHeight - startHeight) / 2 - data.minY
};
// 结束点
targetEdge.endPoint = {
x: nodesObj[end].x + endWidth / 2 - data.minX,
y: nodesObj[end].y - (endInnerHeight - endHeight) / 2 - data.minY
};
var hDis = targetEdge.endPoint.x - targetEdge.startPoint.x;
// endPoint向上距离20点位置开始绘制曲线
var vDis = this.dis;
// radius 根据 vDis 大小而动态调整
if (Math.abs(hDis) <= this.radius * 2) {
targetEdge.radius = Math.abs(hDis) / 2;
}
var revise = targetEdge.radius;
// 当end节点在start节点左方时,个别点的位置需要修正
if (targetEdge.endPoint.x < targetEdge.startPoint.x) {
revise = -targetEdge.radius;
}
// 第一个圆弧起始点
targetEdge.firstRoundStartPoint = {
x: targetEdge.startPoint.x,
y: targetEdge.endPoint.y - vDis - targetEdge.radius * 2
};
// 第一个圆弧控制点
targetEdge.firstRoundControlPoint = {
x: targetEdge.startPoint.x,
y: targetEdge.endPoint.y - vDis - targetEdge.radius
};
// 第一个圆弧结束点
targetEdge.firstRoundEndPoint = {
x: targetEdge.startPoint.x + revise,
y: targetEdge.endPoint.y - vDis - targetEdge.radius
};
// 第二个圆弧起始点
targetEdge.secondRoundStartPoint = {
x: targetEdge.endPoint.x - revise,
y: targetEdge.endPoint.y - vDis - targetEdge.radius
};
// 第二个圆弧控制点
targetEdge.secondRoundControlPoint = {
x: targetEdge.endPoint.x,
y: targetEdge.endPoint.y - vDis - targetEdge.radius
};
// 第二个圆弧结束点
targetEdge.secondRoundEndPoint = {
x: targetEdge.endPoint.x,
y: targetEdge.endPoint.y - vDis
};
}
// 计算出以源头节点为对齐方式的连线数据 --- 纵向
;
_proto.setSourceDataV = function setSourceDataV(edge, data) {
var end = edge.target;
var start = edge.source;
var nodesObj = data.nodesObj;
var startWidth = nodesObj[start].width || 50;
var startInnerHeight = nodesObj[start].innerHeight || 50;
var startHeight = nodesObj[start].height || 50;
var endWidth = nodesObj[end].width || 50;
var endInnerHeight = nodesObj[end].innerHeight || 50;
var endHeight = nodesObj[end].height || 50;
// 拐角半径
edge.radius = this.radius;
// 起始点
edge.startPoint = {
x: nodesObj[start].x + startWidth / 2 - data.minX,
y: nodesObj[start].y + startHeight + (startInnerHeight - startHeight) / 2 - data.minY
};
// 结束点
edge.endPoint = {
x: nodesObj[end].x + endWidth / 2 - data.minX,
y: nodesObj[end].y - (endInnerHeight - endHeight) / 2 - data.minY
};
var hDis = edge.endPoint.x - edge.startPoint.x;
// endPoint向上距离20点位置开始绘制曲线
var vDis = this.dis;
// radius 根据 vDis 大小而动态调整
if (Math.abs(hDis) <= this.radius * 2) {
edge.radius = Math.abs(hDis) / 2;
}
var revise = edge.radius;
// 当end节点在start节点左方时,个别点的位置需要修正
if (edge.endPoint.x < edge.startPoint.x) {
revise = -edge.radius;
}
// 第一个圆弧起始点
edge.firstRoundStartPoint = {
x: edge.startPoint.x,
y: edge.startPoint.y + vDis
};
// 第一个圆弧控制点
edge.firstRoundControlPoint = {
x: edge.startPoint.x,
y: edge.startPoint.y + vDis + edge.radius
};
// 第一个圆弧结束点
edge.firstRoundEndPoint = {
x: edge.startPoint.x + revise,
y: edge.startPoint.y + vDis + edge.radius
};
// 第二个圆弧起始点
edge.secondRoundStartPoint = {
x: edge.endPoint.x - revise,
y: edge.startPoint.y + vDis + edge.radius
};
// 第二个圆弧控制点
edge.secondRoundControlPoint = {
x: edge.endPoint.x,
y: edge.startPoint.y + vDis + edge.radius
};
// 第二个圆弧结束点
edge.secondRoundEndPoint = {
x: edge.endPoint.x,
y: edge.startPoint.y + vDis + edge.radius * 2
};
};
_proto.setPath = function setPath(edge) {
var m = "M" + edge.startPoint.x + " " + edge.startPoint.y;
var l1 = "L" + edge.firstRoundStartPoint.x + " " + edge.firstRoundStartPoint.y;
var q1 = "Q" + edge.firstRoundControlPoint.x + " " + edge.firstRoundControlPoint.y + " " + edge.firstRoundEndPoint.x + " " + edge.firstRoundEndPoint.y;
var l2 = "L" + edge.secondRoundStartPoint.x + " " + edge.secondRoundStartPoint.y;
var q2 = "Q" + edge.secondRoundControlPoint.x + " " + edge.secondRoundControlPoint.y + " " + edge.secondRoundEndPoint.x + " " + edge.secondRoundEndPoint.y;
var l3 = "L" + edge.endPoint.x + " " + edge.endPoint.y;
return m + " " + l1 + " " + q1 + " " + l2 + " " + q2 + " " + l3;
};
return LineRound;
}();
export { LineRound as default };