Antv X6-自定义拖拽方法

在上一篇文章中介绍了了Antv X6的安装&引入和一些简单配置,今天结合项目需求以及这几天搜到的一些资料,关于Antv X6想实现拖拽功能,可以自定义一个拖拽方法。方便自己后期查阅也希望可以帮助到其他小伙伴。

1.布局

不赘述,后面会附上详细代码。(ui库用的elementui)

如图所示:

 2.下载Dnd插件

 附上官网使用插件地址:https://x6.antv.antgroup.com/tutorial/plugins/dnd

通过 npm 或 yarn 命令安装 Dnd插件。命令如下:

# npm
$ npm install @antv/x6-plugin-dnd --save

# yarn
$ yarn add @antv/x6-plugin-dnd

安装成功,如图所示:

3.使用(Vue2中)

重点会标注出来,如图所示:

官网的案例是在React 中的使用,这里我用的是Vue2框架,基于这一专栏的上一篇文章代码。

4.实现效果:

5.附上完整代码
<template>
  <div>
    <div class="flex">
      <div class="left">
        <el-collapse v-model="activeNames">
          <el-collapse-item title="可拖拽元素库" name="1">
            <div
              class="btn"
              v-for="(item, index) in List"
              :key="index"
              :title="item"
              @mousedown="startDragToGraph(item, $event)"
            >
              <el-link :underline="false" :disabled="item.disabled">
                {{ item.name }}
              </el-link>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
      <div class="right" id="container"></div>
    </div>
  </div>
</template>
<script>
import { Graph } from '@antv/x6'
import { Snapline } from '@antv/x6-plugin-snapline'
import { Dnd } from '@antv/x6-plugin-dnd'
export default {
  data() {
    return {
      graph: null,
      // 节点
      nodes: [
        {
          id: 'node1',
          shape: 'rect',
          x: 40,
          y: 40,
          width: 100,
          height: 40,
          label: 'hello',
          attrs: {
            body: {
              stroke: '#8f8f8f',
              strokeWidth: 1,
              fill: '#fff',
              rx: 6,
              ry: 6,
            },
          },
        },
        {
          id: 'node2',
          shape: 'rect',
          x: 160,
          y: 180,
          width: 100,
          height: 40,
          label: 'world',
          attrs: {
            body: {
              stroke: '#8f8f8f',
              strokeWidth: 1,
              fill: '#fff',
              rx: 6,
              ry: 6,
            },
          },
        },
      ],
      // 边
      edges: [
        {
          shape: 'edge',
          source: 'node1',
          target: 'node2',
          label: 'x6',
          attrs: {
            line: {
              stroke: '#8f8f8f',
              strokeWidth: 1,
            },
          },
        },
      ],
      // 拖拽
      activeNames: ['1'],
      // 此处提前定义好的假数据,也可利用接口请求从后端获取,相关参数可以自己定义
      List: [
        {
          id: 1,
          name: '目录监听',
          disabled: true,
        },
        {
          id: 2,
          name: '数据组织',
          disabled: false,
        },
        {
          id: 3,
          name: '影像发布',
          disabled: true,
        },
        {
          id: 4,
          name: '目标检测',
          disabled: false,
        },
        {
          id: 5,
          name: '变化检测',
          disabled: true,
        },
        {
          id: 6,
          name: '地物分类',
          disabled: true,
        },
        {
          id: 7,
          name: '专家候审',
          disabled: false,
        },
        {
          id: 8,
          name: '样本入库',
          disabled: true,
        },
        {
          id: 9,
          name: '影像入库',
          disabled: false,
        },
        {
          id: 10,
          name: '目标入库',
          disabled: true,
        },
        {
          id: 11,
          name: '图幅整饰',
          disabled: false,
        },
        {
          id: 12,
          name: '打包下载',
          disabled: true,
        },
      ],
    }
  },
  mounted() {
    this.graph = new Graph({
      container: document.getElementById('container'),
      width: 800,
      height: 600,
      background: {
        color: '#F2F7FA',
      },
      // 网格线设置
      grid: {
        visible: true,
        type: 'doubleMesh',
        args: [
          {
            color: '#eee', // 主网格线颜色
            thickness: 1, // 主网格线宽度
          },
          {
            color: '#ddd', // 次网格线颜色
            thickness: 1, // 次网格线宽度
            factor: 4, // 主次网格线间隔
          },
        ],
      },
      // 缩放与平移
      mousewheel: true, //使用滚轮控制缩放
      panning: {
        enabled: true,
        //触发键盘事件进行平移:'alt' | 'ctrl' | 'meta' | 'shift'
        modifiers: [],
        //触发鼠标事件进行平移:'leftMouseDown' | 'rightMouseDown' | 'mouseWheel'
        eventTypes: ['leftMouseDown'],
      },
    })
    // 渲染节点和边
    this.graph.fromJSON({
      nodes: this.nodes,
      edges: this.edges,
    })
    // 实现画布内容居中
    this.graph.centerContent()
    //增加对齐线
    this.graph.use(
      new Snapline({
        enabled: true,
      })
    )
  },
  methods: {
    // 自定义一个拖拽方法,也可以单独封装成一个js文件(方便调用)
    // 这里直接写到vue文件的methods方法里了
    // 需求:未置灰的可以拖拽,置灰的无法拖拽即禁用状态
    startDragToGraph(item, e) {
      if (item.disabled == false) {
        const node = this.graph.createNode({
          // 自己设置拖拽元素的具体属性,此处不赘述
          width: 40, //节点的宽度
          height: 180, //节点的高度
          attrs: {
            body: {
              fill: '#fff',
              stoke: '#000',
            },
            text: {
              text: item.name,
              textWrap: {
                width: '50%', // 宽度减少 10px
                height: '100%', // 高度为参照元素高度的一半
                ellipsis: true, // 文本超出显示范围时,自动添加省略号
              },
            },
          },
        })
        const dnd = new Dnd({
          target: this.graph,
          // ☆拖拽结束时,验证节点是否可以放置到目标画布中。
          validateNode: () => {
            console.log('成功拖拽至目标画布')
          },
        })
        dnd.start(node, e)
      } else {
        return
      }
    },
  },
}
</script>
<style scoped>
.flex {
  display: flex;
}
.left {
  width: 150px;
  padding: 10px;
  border: 1px solid blue;
}
.right {
  margin-left: 10px;
  border: 1px solid blue;
}
.btn {
  cursor: move;
}
</style>

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值