vue3+antv x6自定义节点样式

news2025/4/22 0:18:47

先大致定下节点样式,需要展示标题,输入/输出连接桩,

参考样子大概是
https://x6.antv.antgroup.com/examples/showcase/practices#class
这是根据antv x6配置 非自定义节点 图表案例
image-20230811152233914
结果
image-20230811160107525
数据格式大概是

nodes:[{
	title:'鸟',
    id:'node1',
    ports:[{
      title:'羽毛',
      id:'port-1'
    },{
      title:'羽毛',
      id:'port-1'
    }],
}]

接下来开始,新建index,ts存放画布配置等信息

img,目录

1、优化节点数据(index.js)

这个是画布节点关键信息,需要处理成graph需要的格式,下一步渲染到画布

// 画布节点数据
export const NODE_DATA = {
    nodes: [
        {
            id: 'node1', // String,可选,节点的唯一标识。。...
            nodeName: '节点1',
            x: 40,       // Number,必选,节点位置的 x 值
            y: 40,       // Number,必选,节点位置的 y 值。
            ports:[
                {
                    id: 'port-1',
                    name: 'portparams1',
                },
                {
                    id: 'port-2',
                    name: 'portparams2',
                },
            ]
        },
        {
            id: 'node2', // String,可选,节点的唯一标识。。...
            nodeName: '节点2',
            x: 300,       // Number,必选,节点位置的 x 值
            y: 100,       // Number,必选,节点位置的 y 值。
            ports:[
                {
                    id: 'port-1',
                    name: 'portparams1',
                },
                {
                    id: 'port-2',
                    name: 'portparams2',
                },
            ]
        },
    ],
    edges: []
}

2、将节点信息渲染进画布 (index.vue)

增加的代码有注释标注,下一步处理格式


import {NODE_DATA,formatData } from "./index";//节点信息及处理节点格式方法放在index.js内,在下一个步骤

const nodeData = reactive(NODE_DATA)
const refreshData = (data)=>{
    const cells: Cell[] = []
    data.nodes.forEach((item: any) => {
        cells.push(graph.createNode(formatData(item)))//需要将node节点数据处理成createNode接收的格式
    })
    data.edges?.forEach((item: any) => {
        cells.push(graph.createEdge(item))
    })
    graph.resetCells(cells)
    graph.centerContent()
    graph.zoomToFit({ padding: 10, maxScale: 1 })
}
const graphInit = ()=>{
    graph = new Graph({
        container: document.getElementById('container')!,
    });
    refreshData(nodeData)//将取过来的节点信息创建到画布
}

3、将节点数据转化为createNode接收的格式(index.js)

下一步需要配置连接桩的格式

export function formatData(params: any) {
    const portLength = params?.ports?.length || 1
    const portItems = params?.ports?.map((item, index) => ({
        id: item.id,// 连接桩唯一 ID,默认自动生成。
        group: 'port',// 分组名称,指定分组后将继承分组中的连接桩选项。
        name: item.name,
        args: {
            x: 160,
            y: (index + 1) * 25 + 8,
            angle: 45,
        },// 为群组中指定的连接桩布局算法提供参数, 我们不能为单个连接桩指定布局算法,但可以为群组中指定的布局算法提供不同的参数。
    })) || []
    return {
        id: params.id,
        shape: 'node-item',
        x: params.x,//节点x轴位置
        y: params.y,//节点y轴位置
        width: 160,//节点宽度
        height: (portLength + 1) * 25 + 10,//节点高度
        data: params,//用来自定义节点展示节点信息,及节点连接桩信息
        ports: {
            groups: COMMON_GROUP_OPTION,//连接桩样式
            items: [...portItems],
        },
    }
}

4、节点样式(node.vue)

<template>
  <div class="nodeitem">
      <div class="nodetitle">{{ data?.nodeName }}</div>
      <div
        v-for="(item,index) in data?.ports"
        :key="index"
        class="nodeport"
        >
        {{ item.name }}
      </div>
  </div>
</template>
<script setup lang='ts'>
import { inject, onMounted,ref } from "vue";
import { Node } from '@antv/x6'

interface InoutDTO {
  id?: string
  name: string
}
interface NodeDTO {
  id?: string
  nodeName: string
  ports: InoutDTO[]
}

const getNode: Function | undefined = inject<Function>("getNode");
const data =  ref<NodeDTO|undefined>(undefined)
onMounted(() => {
  const node = getNode?.() as Node;
  data.value = node?.getData()
});
</script>
<style scoped>
*{
  font-size: 12px
}
.nodetitle{
  height: 25px;
  line-height: 25px;
  font-weight: 600;
  color: #fff;
  background: #6b94f7;
}
.nodeport{
  padding: 0 6px;
  line-height: 25px;
  background: #f0f4fe;
  border-bottom: 1px solid #fff;
  text-align: center;
}
</style>

5、连接桩配置(index.js)

export const COMMON_GROUP_OPTION = {
    port:{
        markup: [
            {
                tagName: 'rect',//矩形
                selector: 'portBody',
            },
        ],
        position: {
            name: 'absolute',
            args: { x: 0, y: 0 },//相对节点绝对定位,在formatData有重置位置
        },
        attrs: {//样式
            portBody: {
                width: 6,
                height: 6,
                strokeWidth: 2,
                stroke: '#6A93FF',
                fill: '#fff',
                magnet: true,
            },
        },
        zIndex: 3,
    },
}

6、最后配置一下画布连接规则(index.js)

// 画布配置
export const GRAPH_CONFIG = {
    autoResize: true,
    panning: {
        enabled: true,
        // 没有导出类型 EventType
        eventTypes: ['leftMouseDown'] as any,
        // rightMouseDown
    },
    highlighting: {
        // 高亮
        magnetAvailable: {
            name: 'stroke',
            args: {
                attrs: {
                    portBody: {
                        stroke: '#ccc',
                    },
                },
            },
        },
        magnetAdsorbed: {
            // port自动吸附,跟snap一起用
            name: 'stroke',
            args: {
                attrs: {
                    stroke: '#31d0c6',
                },
            },
        },
    },
}
// 连线配置
export const CONNECTING_CONFIG = {
    snap: {
        radius: 30,
    },
    allowBlank: false,
    allowLoop: false,
    allowNode: false,
    allowEdge: false,
    allowMulti: true,
    highlight: true,
    anchor: 'orth',
    connector: 'rounded',
    connectionPoint: 'boundary',
    router: {
        name: 'er',
        args: {
            offset: 25,
            direction: 'H',
        },
    },
}

index.vue内

import { GRAPH_CONFIG, CONNECTING_CONFIG, NODE_DATA,formatData } from "./index";
const graphInit = ()=>{
    graph = new Graph({
        container: document.getElementById('container')!,
        ...GRAPH_CONFIG,
        connecting: { // 连线规则
          ...CONNECTING_CONFIG,
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: '#E3EEFF',
                  strokeWidth: 2,
                },
              },
            })
          },
        }
    });
    refreshData(nodeData)
}

7、最后呈现样式

image-20230811160107525

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/864449.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

逐步分解,一文教会你如何用 jenkins+docker 实现主从模式

♥ 前 言 jenkins 主从模式想必大家都不陌生&#xff0c;大家在学习过程中为了学习方便都在自己本地搭建了 jenkins 环境&#xff0c;然后通过 javaweb 方式实现&#xff0c;对于 docker 下实现主从模式大家好像兴趣挺大。今天就通过这篇文章给大家讲讲怎么玩&#xff0c;希…

【JavaEE进阶】Bean 作用域和生命周期

文章目录 一. 关于Bean作用域的实例1. lombok2. 实例代码 二. 作用域定义1. Bean的六种作用域2. 设置作用域 三. Spring 执行流程和 Bean 的生命周期1. Spring 执行流程2. Bean生命周期 一. 关于Bean作用域的实例 注意在此例子中需要用到lombok 1. lombok lombok是什么? Lo…

android ndk clang交叉编译ffmpeg动态库踩坑

1.ffmpeg默认使用gcc编译&#xff0c;在android上无法使用&#xff0c;否则各种报错&#xff0c;所以要用ndk的clang编译 2.下载ffmpeg源码 修改configure文件&#xff0c;增加命令 cross_prefix_clang 修改以下命令 cc_default"${cross_prefix}${cc_default}" cxx…

Jmeter请求接口返回值乱码解决

乱码示例 解决步骤&#xff1a; 1.打开Jmeter安装目录下的bin目录&#xff0c;找到jmeter.properties 2.使用记事本或其他编译工具打开jmeter.properties文件&#xff0c;然后全局搜索sampleresult.default.encoding 3.在文件中添加sampleresult.default.encodingutf-8,保存…

C++入门篇7---string类

所谓的string类&#xff0c;其实就是我们所说的字符串&#xff0c;本质和c语言中的字符串数组一样&#xff0c;但是为了更符合C面向对象的特性&#xff0c;特地将它写成了一个单独的类&#xff0c;方便我们的使用 对其定义有兴趣的可以去看string类的文档介绍&#xff0c;这里…

【在树莓派上安装cpolar内网穿透实战】

文章目录 前言1.在树莓派上安装cpolar2.查询cpolar版本号3.激活本地cpolar客户端4.cpolar记入配置文件 前言 树莓派作为一个超小型的电脑系统&#xff0c;虽然因其自身性能所限&#xff0c;无法如台式机或笔记本等准系统一样&#xff0c;运行大型软件或程序&#xff08;指望用…

ecology-自定义浏览按钮实现多处引用可定制不同查询条件。

1.新建ecode代码&#xff0c;前置加载&#xff0c;代码内容&#xff1a; ecodeSDK.overwritePropsFnQueueMapSet(WeaBrowser,{ //组件名fn:(newProps)>{ //newProps代表组件参数 if(newProps.type162 || newProps.type161){//console.log("自定义浏览框");if(!ne…

日常BUG——使用Long类型作id,后端返回给前段后精度丢失问题

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 数据库long类型Id: 前端返回的Id实体类: Data ApiModel("xxx") public class …

数据结构顺序表

今天主要讲解顺序表&#xff0c;实现顺序表的尾插&#xff0c;头插&#xff0c;头删&#xff0c;还有尾删等操作&#xff0c;和我们之前写的通讯录的增删查改有类似的功能。接下来让我们开始我们的学习吧。 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特…

保证接口数据安全的10种方式

我们日常开发中&#xff0c;如何保证接口数据的安全性呢&#xff1f;个人觉得&#xff0c;接口数据安全的保证过程&#xff0c;主要体现在这几个方面&#xff1a;一个就是数据传输过程中的安全&#xff0c;还有就是数据到达服务端&#xff0c;如何识别数据&#xff0c;最后一点…

安达发|企业如何提高生产实现精细化管理

随着市场竞争的加剧&#xff0c;企业如何提高生产效率和降低成本成为了关键。本文将探讨生产计划排程表的制定方法&#xff0c;帮助企业实现精细化管理&#xff0c;提升竞争力。 在传统的生产管理中&#xff0c;企业往往依赖于人工经验和直觉来制定生产计划&#xff0c;导致生产…

docker复现Nginx配置漏洞

目录 1.docker环境搭建 2.复现过程 2.1CRLF(carriage return/line feed)注入漏洞 2.2.目录穿越 2.3.add_header覆盖 1.docker环境搭建 1.安装docker apt-get update apt-get install docker.ioyum install docker.io 2.下载并解压docker环境Nginx配置漏洞安装包 链接&am…

最强的表格组件—AG Grid使用以及License Key Crack

PS: 想要官方 License Key翻到最后面 Ag Grid简介 Ag-Grid 是一个高级数据网格&#xff0c;适用于JavaScript/TypeScript应用程序&#xff0c;可以使用React、Angular和Vue等流行框架进行集成。它是一种功能强大、灵活且具有高度可定制性的表格解决方案&#xff0c;提供了丰富…

23款奔驰AMG GT50升级原厂HUD抬头显示系统,增加您的行车安全性

HUD是平视显示器的简称&#xff0c;它原先是运用在航空器上的飞行辅助仪器。指飞行员不需要低头&#xff0c;就能够看到他需要的重要资讯。由于HUD的方便性以及能够提高飞行安全&#xff0c;这项技术后来也发展到汽车行业。汽车搭载的HUD抬头数字显示功能&#xff0c;是利用光学…

类的默认成员函数(C++)

类的默认成员函数 1.构造函数特性 2.析构函数特性 3.拷贝构造函数特性 4.赋值重载函数运算符重载赋值运算符重载 const成员函数取地址运算符重载 1.构造函数 构造函数是一个特殊的成员函数&#xff0c;名字与类名相同&#xff0c;创建类类型对象时由编译器自动调用&#xff0c…

怎么制作gif动态图?gif图片在线制作攻略分享

现在许多品牌和营销活动也使用gif动态图来吸引用户注意力、提升品牌形象或传递特定的信息&#xff0c;那么gif制作的过程到底难不难呢&#xff1f;其实只需要使用gif图片在线制作工具就非常简单了&#xff0c;下面以图片制作gif&#xff08;https://www.gif.cn&#xff09;为例…

一个事务插入,另外一个事务更新操作,是否会更新成功?

1.前言 同样另外一个非常有意思的题目&#xff0c;值得我们思考。大概背景是这个样子的。如果有一个事务A进行插入 id > 100, 同时另外一个事务B进行更新update id > 100。那么事务B是否会更新成功。我们来画一个时序图&#xff1a; time事务A事务B备注T1insert id >…

MPAS-A原理及陆面模式的基本概念

跨尺度预测模式&#xff08;The Model for Prediction Across Scales - MPAS&#xff09;是由洛斯阿拉莫斯实验室和美国国家大气研究中心(NCAR)共同开发&#xff0c;其由3个部分组成&#xff0c;分别称为 MPAS-A&#xff08;大气模型&#xff09;、MPAS-O&#xff08;海洋模型&…

Nginx+Tomcat负载均衡、动静分离实例详细部署

一、反向代理两种模式 四层反向代理 基于四层的iptcp/upd端口的代理 他是http块同一级&#xff0c;一般配置在http块上面。 他是需要用到stream模块的&#xff0c;一般四层里面没有自带&#xff0c;需要编译安装一下。并在stream模块里面添加upstream 服务器名称&#xff0c;…

uni-app日期选择器

写个简单的日期选择器&#xff0c;还没搞样式&#xff0c;所以有点丑 大概长这样吧 首先是这个picker选择器&#xff0c;mode选择日期&#xff0c;end是写一个范围前日期&#xff0c;:end就是这个日期是动态变化的&#xff0c;还有change函数 <template><view>&l…