索引
HT for Web
提供了默认的直线和多点的连线类型能满足大部分基本拓扑图形应用,但对于绘制流程图、组织结构图和思维导图等应用来说还需要更多类型的连线,
为此HT for Web
提供了能满足更多应用需求的连线类型扩展库。
使用本章节介绍的连线类型需要在引入ht.js
核心库之后,再引入一个ht-edgetype.js
的连线类型插件库。
ht.Default.setEdgeType(type, func, mutual)
函数可用于自定义新连线类型:
type
:字符串类型的连线类型,对应style
的edge.type
属性func
:函数类型,根据传入参数(edge, gap, graphView, sameSourceWithFirstEdge)
返回连线走向信息edge
:当前连线对象gap
:多条连线成捆时,本连线对象对应中心连线的间距 graphView
:当前对应拓扑组件对象 sameSourceWithFirstEdge
:boolean
类型,该连线是否与同组的第一条连线同源{points: new ht.List(...), segments: new ht.List(...)}
结构的连线走向信息,segments
可取值如下:moveTo
,占用1
个点信息lineTo
,占用1
个点信息quadraticCurveTo
,占用2
个点信息bezierCurveTo
,占用3
个点信息closePath
,不占用点信息mutual
:该参数决定连线是否影响起始或结束节点上的所有连线,默认为false
代表只影响同source
和target
的EdgeGroup
中的连线,
HT
预定义的连线类型中,后缀为2
的类型都是mutual
为true
的复杂连线类型,参见复杂连线章节ht.Default.setEdgeType('custom', function(edge, gap, graphView, sameSourceWithFirstEdge){
var sourcePoint = edge.getSourceAgent().getPosition(),
targetPoint = edge.getTargetAgent().getPosition(),
points = new ht.List();
points.add(sourcePoint);
points.add({
x: (sourcePoint.x + targetPoint.x)/2,
y: (sourcePoint.y + targetPoint.y)/2 + 300
});
points.add(targetPoint);
return {
points: points,
segments: new ht.List([1, 3])
};
});
以上自定义连线例子中,对连线在sourcePoint和targetPoint之间,插入一个中心控制点作为曲线的拐点。
该例子运用了graphView.setLayers(['nodeLayer', 'edgeLayer']);
的分层功能,
通过node.setLayer('nodeLayer');
和edge.setLayer('edgeLayer');
分别将Node
和Edge
归入不同的图层,
因为默认节点会显示在连线之上,通过这样的分层后节点会呈现在连线之下。
鼠标移动到连线之上是会动态改变连线颜色,该功能是通过直接对GraphView.getView()
添加mousemove
事件做的特殊处理,
ht.Default.isDragging()
的判断是为了避免在移动节点时进行处理,通过graphView.getDataAt(e);
可获取当前鼠标所在位置下图元。
var lastFocus = null;
graphView.getView().addEventListener('mousemove', function(e){
if(!ht.Default.isDragging()){
if(lastFocus){
lastFocus.s('edge.color', 'lightgray');
}
var data = graphView.getDataAt(e);
if(data instanceof ht.Edge){
data.s('edge.color', 'red');
lastFocus = data;
}else{
lastFocus = null;
}
}
});
连线类型扩展包预定义了如下可选择类型:
boundary
:该类型的连线仅连接到图元矩形边缘ripple
:该类型呈现波浪效果连线edge.offset
:指定制连线距离图元中心位置edge.ripple.size
:指定波浪的起伏次数,默认为1
edge.ripple.length
:指定波浪的长度,该属性优先级高于edge.ripple.size
edge.ripple.both
:指定是否双边起伏,默认为false
edge.center
:指定起始和结束点是否聚合,默认为false
edge.ripple.elevation
:指定波浪起伏的高度,默认为-20
edge.ripple.straight
:指定波浪是否为直线,默认为false
h.v
:该类型从起始点先水平再垂直到结束点的走向edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心v.h
:该类型从起始点先垂直再水平到结束点的走向edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心 ortho
:该类型在连接起始和结束点之间会拐弯出一条中间折线edge.ortho
:该参考指定中间折线的拐弯位置,默认值为0.5
代表从中间拐弯edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心flex
:该类型在连接起始和结束的刚开始位置会有一次拐弯edge.flex
:该参数指定拐弯的位置,默认值为20
edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心extend.east
:该类型连线往东边延伸进行连接edge.extend
:控制延伸的距离edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心extend.west
:该类型连线往西边延伸进行连接edge.extend
:控制延伸的距离edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心extend.north
:该类型连线往北边延伸进行连接edge.extend
:控制延伸的距离edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心extend.south
:该类型连线往南边延伸进行连接edge.extend
:控制延伸的距离edge.corner.radius
:控制拐角曲线弧度edge.center
:默认值为false
代表从矩形边缘开始走向,true
则起始和结束于中心以下例子和上面类型模型一致,但对所有连线增加了起始和结束箭头功能,HT
未预定义连线箭头功能,用户可通过自定义矢量的方式任意扩展自己所需箭头样式。
以下代码先定义了toArrow
的矢量箭头,然后通过旋转rotation: Math.PI
实现fromArrow
,
最后通过edge.addStyleIcon
的函数分别在15
和19
的左右中心位置设置了两个箭头图标,
其中keepOrien: true
需要设置,因为需要让箭头和连线的平行方向保持一致,无需像label
的情况那样动态调节。
ht.Default.setImage('toArrow', {
width: 100,
height: 50,
comps: [
{
type: 'shape',
points: [2, 25, 30, 25],
borderWidth: 4,
borderColor: 'rgba(255, 0, 0, 0.9)'
},
{
type: 'shape',
points: [30, 10, 30, 40, 50, 25, 30, 10],
background: 'rgba(255, 0, 0, 0.9)',
borderWidth: 1,
borderColor: 'red',
gradient: 'spread.vertical',
gradientColor: 'rgba(255, 255, 255, 0.9)'
}
]
});
ht.Default.setImage('fromArrow', {
width: 100,
height: 50,
comps: [
{
type: 'image',
name: 'toArrow',
rect: [0, 0, 100, 50],
rotation: Math.PI
}
]
});
function createEdge(sourceNode, targetNode, count, typeOrStyle){
var edge;
for(var i=0; i<count; i++){
edge = new ht.Edge(sourceNode, targetNode);
if(typeof typeOrStyle === 'object'){
edge.s(typeOrStyle);
}else{
edge.s('edge.type', typeOrStyle);
}
edge.addStyleIcon("fromArrow", {
position: 15,
keepOrien: true,
width: 40,
height: 20,
names: ['fromArrow']
});
edge.addStyleIcon("toArrow", {
position: 19,
keepOrien: true,
width: 40,
height: 20,
names: ['toArrow']
});
dataModel.add(edge);
}
return edge;
}
前面介绍的连线类型能实现同起始和结束节点将连线的成捆布局功能,但这些连线类型布局时并不考虑起始和结束节点不同的连线存在,
因此对于复杂的拓扑图会存在连线互相重叠的问题,为此HT
增加了对应的后缀为2
的连线类型:ortho2
,flex2
,extend.north2
、
extend.south2
、extend.west2
,extend.east2
,v.h2
和h.v2
。