antv-X6-Vue3总结03-Vue节点配置

部分源代码:https://gitee.com/eadela/x6-example.git

channelReferral.vue 节点组件

<template>
  <!-- 多波次 -->
  <div class="node-box">
    <Icon type="cancel-questionnaire" class="icon" />
    <p> 渠道转介 </p>

    <div class="child">
      <Button type="text" @click="edit">
        编辑
      </Button>
      <Button type="text" @click="del" class="m-l-1">
        删除
      </Button>
    </div>
  </div>
</template>

<script lang="ts" setup>
/*eslint-disable */
import { Icon, Button } from '@bairong/uxd-ui'
import { defineProps } from 'vue'

const props = defineProps({
  icon: {
    type: String
    // required: true
  },
  text: {
    type: String
    // required: true
  }
})

defineExpose({
  ...props
})

const edit = () => {
  console.log(123123)
}
const del = () => {
  console.log(456456)
}

/*eslint-disable */
</script>

<style scoped lang="less">
.child {
  width: 150px;
  min-height: 100px;
  background: #fff;
  position: absolute;
  left: 60px;
  top: 0;
  display: none;
}
.node-box {
  width: 64px;
  height: 64px;
  border: 1px solid #136fff;
  border-radius: 5px;
  background: #fff;
  text-align: center;
  padding-top: 6px;
  position: relative;
  &:hover {
    background: #136fff;
    color: #fff;
    .child {
      // display: block;
      color: #000;
    }
    .icon {
      color: #fff;
    }
  }
  .icon {
    font-size: 22px;
    color: #136fff;
  }
}
</style>

常量

// 所有节点组
export const ShapeComs = {
  HEEL_NODE: 'HeelNode', // 客群筛选
  SEC_SCREENING: 'SecScreening', // 二次筛选
  SEC_CREATE: 'SecCreate', // 二次筛选裂变产生 -- 特殊节点
  AB_TEST: 'AbTest', // AB测试
  AB_CREATE: 'AbCreate', // AB测试裂变产生  -- 特殊节点
  EXTERNAL_DATA: 'ExternalData', // 外部数据
  FINANCIAL_MANAGER: 'FinancialManager', // 理财经理
  MANUAL_OUTBOUND_CALL: 'ManualOutboundCall', // 人工外呼
  SHORT_MESSAGE: 'ShortMessage', // 短信
  PHONE_APP: 'PhoneApp', // 手机APP
  OFFICIAL_ACCOUNT: 'OfficialAccount', // 公众号
  BRAIN_POWER: 'BrainPower', // 智能外呼
  CHANNEL_REFERRAL: 'ChannelReferral', // 渠道转介
  DELAY_NODE: 'DelayNode', // 延时节点
  EQUITY_RESOURCES: 'EquityResources', // 权益资源
  END_NODE: 'EndNode', // 结束
  PARENT_NODE: 'ParentNode' // 父节点
}

注册组件,注册节点


import { Graph, Edge } from '@antv/x6'
import { VueShape } from '@antv/x6-vue-shape'
import HeelNode from '../shape/heelNode.vue'
import SecScreening from '../shape/secScreening.vue'
import AbTest from '../shape/abTest.vue'
import ExternalData from '../shape/externalData.vue'
import FinancialManager from '../shape/financialManager.vue'
import ManualOutboundCall from '../shape/manualOutboundCall.vue'
import ShortMessage from '../shape/shortMessage.vue'
import PhoneApp from '../shape/phoneApp.vue'
import OfficialAccount from '../shape/officialAccount.vue'
import BrainPower from '../shape/brainPower.vue'
import ChannelReferral from '../shape/channelReferral.vue'
import DelayNode from '../shape/delayNode.vue'
import EndNode from '../shape/endNode.vue'

// 所有vue组件名称
import { ShapeComs } from './shapeConst'

// 注册vue组件到x6中
const registerVueComponent = (comNm: string) => {
  Graph.registerVueComponent(
    comNm,
    {
      template: `<${comNm} />`,
      components: {
        HeelNode,
        SecScreening,
        AbTest,
        ExternalData,
        FinancialManager,
        ManualOutboundCall,
        ShortMessage,
        PhoneApp,
        OfficialAccount,
        BrainPower,
        ChannelReferral,
        DelayNode,
        EndNode,
      },
    },
    true,
  )
}

// 注册vue组件到x6中
Object.values(ShapeComs).map(comNm => registerVueComponent(comNm))

// 定义节点
// 第一步继承VueShape
export class MyShape extends VueShape {
  getInPorts() {
    return this.getPortsByGroup('in')
  }

  getOutPorts() {
    return this.getPortsByGroup('out')
  }

  getUsedInPorts(graph: Graph) {
    console.log(graph)
    // const incomingEdges = graph.getIncomingEdges(this) || []
    return [].map((edge: Edge) => {
      const portId = edge.getTargetPortId()
      return this.getPort(portId!)
    })
  }

  // eslint-disable-next-line class-methods-use-this
  getNewInPorts(length: number) {
    return Array.from(
      {
        length,
      },
      () => ({
        group: 'in' // , id: `${this.data.comType}-out-${Date.now()}`
      }),
    )
  }

  // eslint-disable-next-line class-methods-use-this
  getNewOutPorts(length: number) {
    return Array.from(
      {
        length,
      },
      () => ({
        group: 'out', // , id: `${this.data.comType}-out-${Date.now()}`
      }),
    )
  }

  updateInPorts(graph: Graph) {
    const minNumberOfPorts = 2
    // const ports = this.getInPorts()
    // const usedPorts = this.getUsedInPorts(graph)
    const newInPorts = this.getNewInPorts(1)
    const newOutPorts = this.getNewOutPorts(1)
    // debugger
    if (this.id.includes('HeelNode')) { // 起始节点
      this.addPorts(newOutPorts)
    } else if (this.id.includes('EndNode')) { // 结束节点
      this.addPorts(newInPorts)
    } else { // 其他节点
      this.addPorts(newOutPorts)
      this.addPorts(newInPorts)
    }
    // if (ports.length === minNumberOfPorts && ports.length - usedPorts.length > 0) {
    //   // noop
    // } else if (ports.length === usedPorts.length) {
    //   this.addPorts(newPorts)
    // } else if (ports.length + 1 > usedPorts.length) {
    //   this.prop(
    //     ['ports', 'items'],
    //     this.getOutPorts()
    //       .concat(usedPorts)
    //       .concat(newPorts),
    //     {
    //       rewrite: true,
    //     },
    //   )
    // }

    return this
  }
}
// 第二步:配置
MyShape.config({
  attrs: {
    // root: {
    //   magnet: false,
    // },
    body: {
      fill: '#f5f5f5',
      stroke: '#d9d9d9',
      strokeWidth: 1,
    },
  },
  ports: {
    // items: [
    //   {
    //     group: 'out',
    //   },
    // ],
    groups: {
      in: {
        position: {
          name: 'top',
        },
        attrs: {
          portBody: {
            magnet: 'passive',
            r: 6,
            stroke: '#ffa940',
            fill: '#fff',
            strokeWidth: 2,
          },
        },
      },
      out: {
        position: {
          name: 'bottom',
        },
        attrs: {
          portBody: {
            magnet: true,
            r: 8,
            fill: '#fff',
            stroke: '#3199FF',
            strokeWidth: 2,
          },
        },
      },
    },
  },
  portMarkup: [
    {
      tagName: 'circle',
      selector: 'portBody',
    },
  ],
  // component: {
  //   template: `<Abtext2 />`,
  //   components: {
  //     Abtext2,
  //   },
  // },
})
// 第三步:注册
Graph.registerNode('my-shape', MyShape)

// Graph.registerEdge('my-edge', {
//   inherit: 'edge',
//   attrs: {
//     line: {
//       stroke: '#a0a0a0',
//       strokeWidth: 1,
//       targetMarker: {
//         name: 'classic',
//         size: 7,
//       },
//     },
//   },
// })

画布添加vue节点

在这里插入代码片
<!--
 * VUE节点
-->
<template>
  <div id="containered" ref="containered" />
</template>

<script lang="ts" setup>
/*eslint-disable */
import { ref, computed, onMounted } from 'vue'
import { Graph, Shape } from '@antv/x6';
import './ts/register';
import ChannelReferral from "./shape/channelReferral.vue";

const graph = ref<any>({}) // 流程图
const containered = ref<HTMLElement>() // 流程图挂载dom节点

const init = () => {
  graph.value = new Graph({
    container: containered.value,
    width: 800,
    height: 600,
    background: {
      color: '#fffbe6', // 设置画布背景颜色
    },
    grid: {
      size: 10,      // 网格大小 10px
      visible: true, // 渲染网格背景
    },
    snapline: { // 对齐线
    enabled: true,
    sharp: true, // 是否显示截断的对齐线-对齐线变短
    },
    selecting: { // 点选/框选,默认禁用。
      enabled: true,
      // rubberband: true, // 框选
      // 是否显示节点的选择框,默认为 false,建议使用下面的样式定制方法去定制自己的选择框样式。
      // showNodeSelectionBox: true // 节点的选择框
    },
    keyboard: { // 键盘事件可用于绑定快捷键
      enabled: true
    },
    // 开启撤销/重做
    history: {
      enabled: true,
      ignoreChange: true
    },
    // 剪切板用于复制/粘贴节点和边,并支持跨画布的复制/粘贴,创建画布时通过以下配置启用。
    clipboard: {
      enabled: true
      // useLocalStorage: true // 保存到 localStorage
    },
    // panning: true, // 普通画布(未开启 scroller 模式)通过开启 panning 选项来支持拖拽平移。
    // 使画布具备滚动、平移、居中、缩放等能力
    scroller: {
      enabled: true,
      pageVisible: false, // 是否分页,默认为 false。
      pageBreak: false, // 是否显示分页符,默认为 false。
      pannable: true // 启用画布平移
    },
    mousewheel: { // 鼠标滚轮缩放
      enabled: true,
      // 是否为全局事件,设置为 true 时滚轮事件绑定在 document 上,否则绑定在画布容器上。默认为 false。
      global: true,
      modifiers: ['ctrl', 'meta']
    },
    highlighting: {
      // 连线过程中,节点可以被链接时被使用
      // nodeAvailable: {},
      // 拖动节点进行嵌入操作过程中,节点可以被嵌入时被使用
      embedding: {
        name: 'stroke',
        args: {
          attrs: {
            fill: '#fff',
            stroke: '#47C769',
          },
        },
      },
      // 连线过程中,链接桩可以被链接时被使用
      magnetAvailable: { // 高亮
        name: 'stroke',
        args: {
          attrs: {
            fill: '#fff',
            stroke: '#47C769',
          },
        },
      },
      // 连线过程中,自动吸附到链接桩时被使用
      magnetAdsorbed: {
        name: 'stroke',
        args: {
          attrs: {
            fill: '#fff',
            stroke: '#31d0c6',
          },
        },
      },
    },
  });
  graph.value.addNode({
    shape: 'my-shape',
    width: 64,
    height: 64,
    x: 40,
    y: 40,
    component: {
      template: `<channel-referral :text="text" />`,
      data() {
        return {
          text:'AB测试',
        }
      },
      components: {
        ChannelReferral,
      },
    },
  })
}

onMounted(() => {
  init()
})


</script>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eadela

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值