在使用g6实现知识图谱可视化中,产品经理提出了有关图谱操作的不少功能,需要放置在工具栏中,其中有些功能不在g6自带的功能里,且工具栏样式、交互效果也和官方自定义工具栏不同。那我们怎么去实现呢?
g6官方的工具栏案例是这样:G6,提供了"重做","撤销","放大","缩小","适应屏幕","实际大小"的操作,配置项中也提供了有关样式及操作的回调功能,但是,远不能满足我们产品需要的样式及功能。
产品的需求中,工具栏各操作需要有激活和未激活的效果,悬浮的效果等等。操作除了官方工具栏自带的操作,还需"高亮","鱼眼放大镜","布局","下载","关系标签显隐"的功能。
那我们就给工具栏换个新包装吧!话不多说,看效果,上代码。
html
<div v-if="graphState.showTool" class="toolbar">
<a-tooltip title="展开/收起" color="geekblue" placement="right">
<div class="inactiveTool">
<MenuUnfoldOutlined
v-if="graphState.collapse"
style="font-size: 20px"
@click="
() => {
graphState.collapse = !graphState.collapse;
}
"
/>
<MenuFoldOutlined
v-else
style="font-size: 20px"
@click="
() => {
graphState.collapse = !graphState.collapse;
}
"
/>
</div>
</a-tooltip>
<a-space v-show="!graphState.collapse" direction="horizontal">
<a-tooltip title="放大" color="geekblue" placement="right">
<div
code="zoomOut"
:class="graphState.activeTool == 'zoomOut' ? 'activeTool' : 'inactiveTool'"
>
<ZoomInOutlined @click="handleClickTool('zoomOut')" style="font-size: 20px" />
</div>
</a-tooltip>
<a-tooltip title="缩小" color="geekblue" placement="right">
<div
code="realZoom"
:class="graphState.activeTool == 'zoomIn' ? 'activeTool' : 'inactiveTool'"
>
<ZoomOutOutlined @click="handleClickTool('zoomIn')" style="font-size: 20px" />
</div>
</a-tooltip>
<a-tooltip title="自适应" color="geekblue" placement="right">
<div :class="graphState.activeTool == 'realZoom' ? 'activeTool' : 'inactiveTool'">
<OneToOneOutlined @click="handleClickTool('realZoom')" style="font-size: 20px" />
</div>
</a-tooltip>
<a-tooltip title="视图居中" color="geekblue" placement="right">
<div
:class="graphState.activeTool == 'autoZoom' ? 'activeTool' : 'inactiveTool'"
style="font-size: 20px"
>
<PicCenterOutlined @click="handleClickTool('autoZoom')" style="font-size: 20px" />
</div>
</a-tooltip>
<a-tooltip title="高亮相邻节点" color="geekblue" placement="right">
<div :class="graphState.activeTool == 'relation' ? 'activeTool' : 'inactiveTool'">
<DeploymentUnitOutlined
@click="handleClickTool('relation')"
style="font-size: 20px"
/>
</div>
</a-tooltip>
<a-tooltip title="鱼眼放大镜" color="geekblue" placement="right">
<div :class="graphState.activeTool == 'fishEye' ? 'activeTool' : 'inactiveTool'">
<EyeOutlined @click="handleClickTool('fishEye')" style="font-size: 20px" />
</div>
</a-tooltip>
<a-popover
title="布局方案"
placement="right"
@visibleChange="handleChangeVisibleLayout"
>
<template #content>
<a-radio-group
v-model:value="graphState.layout.type"
@change="handleChangeLayout"
>
<div>
<a-radio value="AI" :disabled="graphState.nodes.length >= 100">
多边散列排布(少量数据推荐)
</a-radio>
</div>
<div>
<a-radio value="gForce">gForce力导向布局</a-radio>
</div>
<div>
<a-radio value="force2">基础力导向布局</a-radio>
</div>
<div v-show="false">
<a-radio value="fruchterman">Fruchterman布局</a-radio>
</div>
</a-radio-group>
</template>
<div :class="graphState.activeTool == 'layout' ? 'activeTool' : 'inactiveTool'">
<LayoutOutlined style="font-size: 20px" />
</div>
</a-popover>
<a-tooltip title="导出图片" color="geekblue" placement="right">
<div :class="graphState.activeTool == 'download' ? 'activeTool' : 'inactiveTool'">
<DownloadOutlined @click="handleClickTool('download')" style="font-size: 20px" />
</div>
</a-tooltip>
<a-tooltip title="关系标签显隐" color="geekblue" placement="right">
<div
:class="
graphState.activeTool == 'relationVisible' ? 'activeTool' : 'inactiveTool'
"
>
<ArrowRightOutlined
@click="handleClickTool('relationVisible')"
style="font-size: 20px"
/>
</div>
</a-tooltip>
</a-space>
</div>
上述代码中,我们根据业务需求做了工具栏整体的显示隐藏,展开收起,关系显隐,图片下载等功能。工具栏面板我们可以根据自己系统使用的组件库,ant design 、element ui或者其他。添加图标,提示框,选中等效果。这里不多赘述。
那么,怎么将g6的功能添加到我们工具栏上面使用呢?
我们定义了一组响应式对象,用来存储当前激活的工具或效果。
javascript
const graphState = reactive({
layout: {
type: 'force2',
advanceWeight: false,
damping: 0.8,
kr: 1000,
preset: {
minNodeSpacing: 10,
nodeSize: 10,
type: 'concentric',
},
clustering: true,
animate: false,
preventOverlap: true,
clusterNodeStrength: 35,
distanceThresholdMode: 'max',
minMovement: 10,
maxSpeed: 1000,
linkDistance: 50,
edgeStrength: 200,
nodeStrength: 1000,
nodeWeightFieldScale: 1,
nodeWeightFromType: 'node',
fitCenter: true,
},
showTool: false,
activeTool: '', //当前激活的工具
enableFishEye: false, //是否启用鱼眼放大镜
relation: false, //是否开启高亮相邻节点
enableLegend: false, //是否开启图例
relationVisible: true, //关系标签显示隐藏
collapse: false, //展开或折叠工具栏
});
引入G6,定义graph,用来初始化G6实例,再初始化G6的工具栏
javascript
import G6 from '@antv/g6';
javascript
let graph;
let toolbar = new G6.ToolBar({
className: 'g6-component-toolbar',
});
通过动态的给graph 实例添加插件、添加行为动作,达到调用工具栏功能的目的。
javascript
const handleClickTool = code => {
if (toolbar.destroyed) {
toolbar = new G6.ToolBar({
className: 'g6-component-toolbar',
});
graph.addPlugin(toolbar);
}
if (code === 'zoomOut') {
toolbar.zoomOut();
//...
} else if (code === 'zoomIn') {
toolbar.zoomIn();
//...
}
//...
graph.fitCenter();
graphState.activeTool = code;
};
其他功能实现读者可查询G6官网API自行实现。这里只简述思路和原理。