relation-graph官网地址
在官网中能看到一些基本的配置和方法,但是并不全面,有些东西可以去github上面的问题解答查看
安装图谱库
npm install --dev relation-graph
vue 中引入relation-graph
import RelationGraph from 'relation-graph';
Vue use(RelationGraph);
常用配置
{
defaultJunctionPoint: 'border', // 连线与节点接触的方式
defaultLineShape: 1, // 连线样式 1直线,2,3,4折线,5,6曲线, 默认1
allowShowMiniToolBar: false,
layouts: [
{
label: '自动布局',
layoutName: 'force',
layoutClassName: 'seeks-layout-force'
}
],
// layouts: [
// {
// label: '中心布局',
// layoutName: 'center',
// layoutClassName: 'seeks-layout-center'
// }
// ],
defaultNodeShape: 0, // 1矩形,0圆形
defaultLineColor: '#00ced1', // 默认连线颜色
defaultNodeColor: '#1884ff', // 默认节点颜色
isMoveByParentNode: true,
// hideNodeContentByZoom: true, // 根据缩放比例隐藏节点内容
// moveToCenterWhenRefresh: true, // 刷新自动居中
// zoomToFitWhenRefresh: true, // 图谱刷新后,是否让图谱缩放到适合可见区域大小
// useAnimationWhenRefresh: true, // 图谱刷新后,使用动画让图居中、缩放
}
常用方法
getInstance()
获取图谱实例,实例中会包含一些实用方法,可以通过this.$refs.seeksRelationGraph.getInstance()
来获取,此实例支持的方法见:实例方法api,(更多复杂操作,后续可以通过实例方法api来实现)setOptions(options, callback)
设置/重新设置图谱的选项,options:图谱选项,不能为空;callback:当设置完成后的回调函数,可以为空;options选项设置方法示例:<SeeksRelationGraph ref="seeksRelationGraph" :options="userGraphSetting" />
更改设置this.$refs.seeksRelationGraph.setOptions(newOptions, callback);
setJsonData(jsonData, callback)
设置/重新设置图谱中的数据,jsonData:图谱数据,不能为空,jsonData中需要包含三要素(rootId、nodes、links)数据格式示例;callback:当设置完成后的回调函数,可以为空;appendJsonData(jsonData, callback)
向图谱中追加数据,jsonData:图谱数据,不能为空,数据格式示例;callback:当设置完成后的回调函数,可以为空;refresh()
刷新布局,你可以通过getNodes()获取当前图谱中的节点,并通过节点的isHide属性隐藏一些节点,再调用refresh()方法可以根据依然显示的节点重新布局图谱;或者在动态向图谱中添加数据候刷新布局;当你的图片默认默认状态是不可见的时,在切换到可见状态下后可能会显示不正常,这时你调用一下refresh()方法可以让图片正确显示。总之一句话:当图谱中的节点看起来不正常时,你都可以调用refresh方法来让布局器重新为节点分配位置。onGraphResize()
当用于展示图谱的div容器大小发生变化时,可以调用此方法来让图谱各个部件展示到正确位置;使用示例focusRootNode()
选中图谱的根节点居中并选中;focusNodeById(nodeId)
根据节点id在图谱中选中该节点并居中;getNodeById(nodeId)
根据节点id获取节点对象;removeNodeById(nodeId)
移除指定id对应的节点,彻底移除,移除element和数据对象;downloadAsImage(format, fileName)
下载图片,将当前图谱导出为图片,format可以为:png/jpg,默认为png;fileName为下载图片的文件名,此方法需要通过getInstance()获取实例调用:this.$refs.seeksRelationGraph.getInstance().downloadAsImage(a,b)getNodes()
获取图谱中所有的节点对象,可以直接修改该对象的属性,这些对象不能用于JSON序列化;getLines()
获取图谱中所有的连线对象,可以直接修改该对象的属性,这些对象不能用于JSON序列化;getGraphJsonData()
获取当前图谱的节点、关系数据的json数据;getGraphJsonOptions()
获取当前图谱的完整的配置信息;dataUpdated()
有时候在更改数据后视图并没有同步(比如通过更改了线条color属性值后,但图谱上的线条颜色没有变化),可以调用此方法;
删除某个节点后的所有子节点
removeNode(node){
if (node.lot.childs.length) {
node.lot.childs.forEach(thisNode => {
this.$refs.seeksRelationGraph.removeNodeById(thisNode.id)
return this.removeNode(thisNode)
})
}
},
连线选中状态
onNodeClick(nodeObject, $event) {
const nodeData = nodeObject.data
console.log('onNodeClick:', nodeObject)
if (nodeObject.nodeShape === 2) {
const targetFromNodeIds = nodeObject.targetFrom.map(node => {
return (node.id).toString()
})
const targetToNodeIds = nodeObject.targetTo.map(node => {
return (node.id).toString()
})
const currentNodeId = (nodeObject.id).toString()
const _all_links = this.$refs.seeksRelationGraph.getInstance().getLinks();
// console.log(_all_links)
// 点击关系节点连线处理
_all_links.forEach(thisLink => {
thisLink.relations.forEach(thisLine => {
if (
(targetFromNodeIds.includes(thisLine.from) && thisLine.to === currentNodeId)
||
(targetToNodeIds.includes(thisLine.to) && thisLine.from === currentNodeId)
) {
if (thisLine.color === 'rgba(0, 186, 189, 1)') {
thisLine.color = undefined
this.activeRelationNodeIds = this.activeRelationNodeIds.filter(it => it.batchId !== nodeData.batchId)
} else {
thisLine.color = 'rgba(0, 186, 189, 1)';
if (this.activeRelationNodeIds.every(it => it.batchId !== nodeData.batchId)) {
const obj = {
entityLeftId: nodeData.entityLeftId,
batchId: nodeData.batchId,
entityRightId: nodeData.entityRightId
}
this.activeRelationNodeIds.push(obj)
}
}
}
})
});
} else {
if (this.activeEntityNodeIds.includes(nodeData.id)) {
this.activeEntityNodeIds = this.activeEntityNodeIds.filter(it => it !== nodeData.id);
} else {
this.activeEntityNodeIds.push(nodeData.id);
}
}
this.$refs.seeksRelationGraph.getInstance().dataUpdated();
},
自定义节点
<div
slot="node"
slot-scope="{node}"
@mouseover="showNodeTips(node, $event)"
@mouseout="hideNodeTips(node, $event)"
v-if="node.nodeShape === 2"
>
<div class='diamond' :class="activeRelationNodeIds.some(it => it.batchId === node.data.batchId) ? 'node-select' : ''"></div>
<span class="diamond-name">{{ node.text }}</span>
</div>
<div
v-else
slot="node"
slot-scope="{node}"
@mouseover="showNodeTips(node, $event)"
@mouseout="hideNodeTips(node, $event)"
:class="activeEntityNodeIds.some(it => it === node.data.id) ? 'node-select' : ''"
>
<div class="common-node">{{ node.text }}</div>
</div>
比较坑的地方
- 动态加载节点,数量超过5个之后,会变得异常卡顿,暂没有解决方案,我这边是通过
setJSONData
处理,但是这样会导致页面重绘,图重新加载,对视觉不友好 - 节点类型比较少,目前默认的仅有圆形和矩形,要想额外设置其他形状,要么加载图片,要么就是通过自定义slot去改写样式来实现
- 必须要有一个根节点
rootId
,不然页面的图形一旦属于并行节点,就会导致节点不会自定展开,会堆积在一起