Antd G6实现自定义工具栏

在使用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自行实现。这里只简述思路和原理。

相关推荐
天下无贼!9 分钟前
2024年最新版Vue3学习笔记
前端·vue.js·笔记·学习·vue
Jiaberrr9 分钟前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
赵啸林12 分钟前
npm发布插件超级简单版
前端·npm·node.js
罔闻_spider1 小时前
爬虫----webpack
前端·爬虫·webpack
吱吱鼠叔1 小时前
MATLAB数据文件读写:1.格式化读写文件
前端·数据库·matlab
爱喝水的小鼠1 小时前
Vue3(一) Vite创建Vue3工程,选项式API与组合式API;setup的使用;Vue中的响应式ref,reactive
前端·javascript·vue.js
WeiShuai1 小时前
vue-cli3使用DllPlugin优化webpack打包性能
前端·javascript
Wandra1 小时前
很全但是超级易懂的border-radius讲解,让你快速回忆和上手
前端
ice___Cpu1 小时前
Linux 基本使用和 web 程序部署 ( 8000 字 Linux 入门 )
linux·运维·前端
JYbill1 小时前
nestjs使用ESM模块化
前端