antv/x6_2.0学习使用(三、内置节点和自定义节点)

内置节点和自定义节点

一、节点渲染方式

X6 是基于 SVG 的渲染引擎,可以使用不同的 SVG 元素渲染节点和边,非常适合节点内容比较简单的场景。面对复杂的节点, SVG 中有一个特殊的 foreignObject 元素,在该元素中可以内嵌任何 XHTML 元素,可以借助该元素来渲染 HTML、React/Vue/Angular 组件到需要位置,这会给项目开发带来非常大的便利。

  • 在选择渲染方式时推荐:
    • 如果节点内容比较简单,而且需求比较固定,使用 SVG 节点
    • 其他场景,都推荐使用当前项目所使用的框架来渲染节点

注意:

  1. React/Vue/Angular/HTML 渲染方式也存在一些限制,因为浏览器的兼容性问题,有时会出现一些异常的渲染行为。主要表现形式为节点内容展示不全或者节点内容闪烁。可以通过一些方法规避,比如在节点内部元素的 css 样式中不要使用 position:absolute、position:relative、tranform、opacity。
  2. 使用 React/Vue/Angular 渲染时,x6 的版本要和 x6-react-shape/x6-vue-shape/x6-angular-shape 的版本匹配,也就是两个包需要用同一个大版本。比如如果 X6 使用的是 2.x 版本,那么 x6-react-shape/x6-vue-shape/x6-angular-shape 也需要使用 2.x 版本。
  3. x6-react-shape 从 2.0.8 版本以后只支持 react18,如果项目是低于 react18 的版本,就要把 x6-react-shape 的版本锁定在 2.0.8。
  • 节点和边都有共同的基类 Cell,除了从 Cell 继承属性外,还支持以下选项。
属性名类型默认值描述
xnumber0节点位置 x 坐标,单位为 px
ynumber0节点位置 y 坐标,单位为 px
widthnumber1节点宽度,单位为 px
heightnumber1节点高度,单位为 px
anglenumber0节点旋转角度
graph.addNode({
  shape: 'rect',
  x: 100,
  y: 40,
  width: 100,
  height: 40,
})
二、内置节点

使用 shape 指定节点的图形,shape 的默认值为 rect。X6 内置节点与 shape 名称对应关系如下表

shape 名称描述
rect矩形
circle圆形
ellipse椭圆
polygon多边形
polyline折线
path路径
image图片
htmlHTML 节点,使用 foreignObject 渲染 HTML 片段。
// rect
graph.addNode({
    shape: "rect",
    x: 40,
    y: 40,
    width: 80,
    height: 40,
    label: "rect",
});

// circle
graph.addNode({
    shape: "circle",
    x: 180,
    y: 40,
    width: 40,
    height: 40,
    label: "circle",
});

// ellipse
graph.addNode({
    shape: "ellipse",
    x: 280,
    y: 40,
    width: 80,
    height: 40,
    label: "ellipse",
});

// path
graph.addNode({
    shape: "path",
    x: 420,
    y: 40,
    width: 40,
    height: 40,
    // https://www.svgrepo.com/svg/13653/like
    path: "M24.85,10.126c2.018-4.783,6.628-8.125,11.99-8.125c7.223,0,12.425,6.179,13.079,13.543c0,0,0.353,1.828-0.424,5.119c-1.058,4.482-3.545,8.464-6.898,11.503L24.85,48L7.402,32.165c-3.353-3.038-5.84-7.021-6.898-11.503c-0.777-3.291-0.424-5.119-0.424-5.119C0.734,8.179,5.936,2,13.159,2C18.522,2,22.832,5.343,24.85,10.126z",
    label: "path",
});

// polygon
graph.addNode({
    shape: "polygon",
    x: 60,
    y: 150,
    width: 40,
    height: 40,
    points: "100,10 40,198 190,78 10,78 160,198",
    label: "polygon",
    attrs: {
        body: {
            fill: "#fff",
            stroke: "#8f8f8f",
            strokeWidth: 1,
        },
        label: {
            refX: 0.5,
            refY: "100%",
            refY2: 4,
            textAnchor: "middle",
            textVerticalAnchor: "top",
        },
    },
});

// polyline
graph.addNode({
    shape: "polyline",
    x: 180,
    y: 150,
    width: 40,
    height: 40,
    label: "polyline",
    attrs: {
        body: {
            refPoints: "0,0 0,10 10,10 10,0",
        },
        label: {
            refX: 0.5,
            refY: "100%",
            refY2: 4,
            textAnchor: "middle",
            textVerticalAnchor: "top",
        },
    },
});

// image
graph.addNode({
    shape: "image",
    x: 290,
    y: 150,
    width: 60,
    height: 40,
    imageUrl:
        "https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg",
    label: "image",
    attrs: {
        label: {
            refX: 0.5,
            refY: "100%",
            refY2: 4,
            textAnchor: "middle",
            textVerticalAnchor: "top",
        },
    }
});

以下是效果图
在这里插入图片描述

三、定制节点

实际上是从基础节点派生(继承)出我们自己的节点,并覆盖基类的某些选项和方法。
可以通过 markup 和 attrs 来定制节点的形状和样式,markup 可以类比 HTML,attrs 类比 CSS。具体可以仔细阅读 markup 和 attrs 文档。

以 Rect 为例:

  1. 继承
import { Node } from '@antv/x6'

class Rect extends Node {
  ......
}
  1. 配置

    调用继承的静态方法 config(options) 来配置节点选项的默认值、自定义选项和自定义属性,最常用选项的是通过 markup 来指定节点默认的 SVG/HTML 结构,通过 attrs 来指定节点的默认属性样式

    名称类型是否必选默认值说明
    propHooksFunctionundefined自定义选项钩子
    attrHooksObjectundefined自定义属性钩子
    …othersObject节点选项
Rect.config({
  width: 100,
  height: 40,
  markup: [  //  定义了节点由 <rect> 和 <text> 两个 SVG 元素构成,并分别指定了 body 和 label 两个选择器,接着就可以在 attrs 中通过这两个选择器来指定节点的默认样式。
    {
      tagName: 'rect',
      selector: 'body',
    },
    {
      tagName: 'text',
      selector: 'label',
    },
  ],
  attrs: {
    body: {
      fill: '#ffffff',
      stroke: '#333333',
      strokeWidth: 2,
    },
    label: {
      fontSize: 14,
      fill: '#333333',
      refX: '50%',
      refY: '50%',
      textAnchor: 'middle',
      textVerticalAnchor: 'middle',
    },
  },
  // 通过钩子将自定义选项 label 应用到 'attrs/text/text' 属性上
  propHooks(metadata) {
    const { label, ...others } = metadata
    if (label) {
      ObjectExt.setByPath(others, 'attrs/text/text', label)
    }
    return others
  },
})
  1. 注册

    调用 Graph 的静态方法 registerNode 来注册节点,注册以后就可以像使用内置节点那样来使用节点。

Graph.registerNode(name: string, cls: typeof Node, overwrite?: boolean)
参数名类型是否必选默认值说明
nameString注册的节点名
clstypeof Node节点类,直接或间接继承 Node 的类
overwriteBooleanfalse重名时是否覆盖,默认为 false 不覆盖(重名时报错)

例如,注册名为 ‘rect’ 的节点。

Graph.registerNode('rect', Rect)

注册以后,可以像下面这样来使用。

graph.addNode({
  shape: 'rect',
  x: 30,
  y: 40,
})
  • 便捷方法:

同时实现定义和注册节点。

Graph.registerNode(name: string, options: Object, overwrite?: boolean)
参数名类型是否必选默认值说明
nameString注册的节点名
optionsObject选项
overwriteBooleanfalse重名时是否覆盖,默认为 false 不覆盖(重名时报错)

通过 options.inherit 来指定继承的基类,默认值为 Node 类,支持字符串或节点类,当 options.inherit 为字符串时将自动从已注册的节点中找到对应的节点作为基类,options 的其他选项与 define 方法一致。当 options.constructorName 类名缺省时,第一个参数 name 的大驼峰形式(CamelCase)也将作为自定义节点的类名。

const ports = {
  groups: {
    top: {
      position: "top",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
    right: {
      position: "right",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
    bottom: {
      position: "bottom",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
    left: {
      position: "left",
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: "#5F95FF",
          strokeWidth: 1,
          fill: "#fff",
          style: {
            visibility: "hidden",
          },
        },
      },
    },
  },
  items: [
    {
      group: "top",
    },
    {
      group: "right",
    },
    {
      group: "bottom",
    },
    {
      group: "left",
    },
  ],
};

Graph.registerNode(
  "custom-rect",
  {
    inherit: "rect",
    width: 66,
    height: 36,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: "#5F95FF",
        fill: "#EFF4FF",
      },
      text: {
        fontSize: 12,
        fill: "#262626",
      },
    },
    ports: { ...ports },
  },
  true
);

Graph.registerNode(
  "custom-polygon",
  {
    inherit: "polygon",
    width: 66,
    height: 36,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: "#5F95FF",
        fill: "#EFF4FF",
      },
      text: {
        fontSize: 12,
        fill: "#262626",
      },
    },
    ports: {
      ...ports,
      items: [
        {
          group: "top",
        },
        {
          group: "bottom",
        },
      ],
    },
  },
  true
);

Graph.registerNode(
  "custom-circle",
  {
    inherit: "circle",
    width: 45,
    height: 45,
    attrs: {
      body: {
        strokeWidth: 1,
        stroke: "#5F95FF",
        fill: "#EFF4FF",
      },
      text: {
        fontSize: 12,
        fill: "#262626",
      },
    },
    ports: { ...ports },
  },
  true
);

Graph.registerNode(
  "custom-image",
  {
    inherit: "rect",
    width: 52,
    height: 52,
    markup: [
      {
        tagName: "rect",
        selector: "body",
      },
      {
        tagName: "image",
      },
      {
        tagName: "text",
        selector: "label",
      },
    ],
    attrs: {
      body: {
        stroke: "#5F95FF",
        fill: "#5F95FF",
      },
      image: {
        width: 26,
        height: 26,
        refX: 13,
        refY: 16,
      },
      label: {
        refX: 3,
        refY: 2,
        textAnchor: "left",
        textVerticalAnchor: "top",
        fontSize: 12,
        fill: "#fff",
      },
    },
    ports: { ...ports },
  },
  true
);

除此方法外还可以使用另外一种静态方法 define 来自定义节点,具体可查看自定义节点

四、自定义HTML节点
  1. 渲染节点

X6 默认内置 HTML 渲染能力

import {  Shape } from '@antv/x6'

Shape.HTML.register({
  shape: 'custom-html',
  width: 160,
  height: 80,
  html() {
    const div = document.createElement('div')
    div.className = 'custom-html'
    return div
  },
})

graph.addNode({
  shape: 'custom-html',
  x: 60,
  y: 100,
})
  1. 节点更新

在注册节点的时候,提供一个 effect,字段,是当前节点的 prop 数组,当 effect 包含的 prop 有变动时,会重新执行 html 方法,返回新的 dom,更新节点内容。

Shape.HTML.register({
  shape: 'custom-html',
  width: 160,
  height: 80,
  effect: ['data'],
  html(cell) {
    const { color } = cell.getData()
    const div = document.createElement('div')
    div.className = 'custom-html'
    div.style.background = color
    return div
  },
})
五、 自定义React/Vue/Angular节点

可阅读官方文档 自定义React节点、自定义Vue节点、自定义Angular节点

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法笔记

数据结构&#xff1a; 就是指一组数据的存储结构 算法&#xff1a; 就是操作数据的一组方法 数据结构和算法 两者关系 数据结构和算法是相辅相成的。数据结构是为算法服务的&#xff0c;算法要作用在特定的数据结构之上。 数据结构是静态的&#xff0c;它只是组织数据的一…

Windows窗口程序详解

今天来给大家详细剖析一下Windows的消息机制 一、什么是消息机制 首先消息机制是Windows上面进程之间通信的一种方式&#xff0c;除此之外还包括共享内存&#xff0c;管道&#xff0c;socket等等进程之间的通信方式&#xff0c;当然socket还可以实现远程进程之间的通信&#…

JS变量和函数提升

JS变量和函数提升 JS变量提升编译阶段执行阶段相同变量或函数 变量提升带来的问题变量容易不被察觉的遭覆盖本应销毁的变量未被销毁 如何解决变量提升带来的问题 JS变量提升 sayHi()console.log(myname)var myname yyfunction sayHi() {console.log(Hi) }// 执行结果: // Hi …

我的2023年,平淡中寻找乐趣

文章目录 两个满意我学会了自由泳。学习英语 一个较满意写博客 2024的期望 2023年&#xff0c;我有两个满意&#xff0c;一个较满意。 两个满意 我学会了自由泳。 开始练习自由泳是从2023年3月份&#xff0c;我并没有请教练&#xff0c;而是自己摸索。在抖音上看自由泳的视频…

【一分钟】ThinkPHP v6.0 (poc-yaml-thinkphp-v6-file-write)环境复现及poc解析

写在前面 一分钟表示是非常短的文章&#xff0c;只会做简单的描述。旨在用较短的时间获取有用的信息 环境下载 官方环境下载器&#xff1a;https://getcomposer.org/Composer-Setup.exe 下载文档时可以设置代理&#xff0c;不然下载不上&#xff0c;你懂的 下载成功 cmd cd…

JavaWeb——前端之HTMLCSS

学习视频链接&#xff1a;https://www.bilibili.com/video/BV1m84y1w7Tb/?spm_id_from333.999.0.0 一、Web开发 1. 概述 能通过浏览器访问的网站 2. Web网站的开发模式——主流是前后端分离 二、前端Web开发 1. 初识 前端编写的代码通过浏览器进行解析和渲染得到我们看到…

Java多线程常见的成员方法(线程优先级,守护线程,礼让/插入线程)

目录 1.多线程常见的成员方法2.优先级相关的方法3.守护线程&#xff08;备胎线程&#xff09;4.其他线程 1.多线程常见的成员方法 ①如果没有给线程设置名字&#xff0c;线程是有默认名字 的&#xff1a;Thread-X(X序号&#xff0c;从0开始) ②如果要给线程设置名字&#xff0c…

【SAM系列】Auto-Prompting SAM for Mobile Friendly 3D Medical Image Segmentation

论文链接&#xff1a;https://arxiv.org/pdf/2308.14936.pdf 核心&#xff1a; finetune SAM,为了不依赖外部prompt&#xff0c;通过将深层的特征经过一个编-解码器来得到prompt embedding&#xff1b;finetune完之后做蒸馏

苯酚,市场预计将以5%左右的复合年增长率

苯酚是一种重要的化合物&#xff0c;用于广泛的工业应用&#xff0c;包括塑料、树脂和合成纤维的生产。在建筑、汽车和电子行业不断增长的需求推动下&#xff0c;苯酚市场在过去十年中经历了稳步增长。全球苯酚市场分析&#xff1a; 在 2021-2026 年的预测期内&#xff0c;全球…

Java并发编程(三)

并发编程的三个特性 并发编程的三个重要特性是原子性、可见性和有序性。 原子性&#xff1a;原子性指的是一个操作是不可中断的&#xff0c;要么全部执行成功&#xff0c;要么全部不执行&#xff0c;是不可再分割的最小操作单位。保证原子性可以避免多个线程同时对共享数据进行…

《深入理解计算机系统》学习笔记 - 第七课 - 机器级别的程序三

Lecture 07 Machine Level Programming III Procedures 机器级别的程序三 文章目录 Lecture 07 Machine Level Programming III Procedures 机器级别的程序三概述程序机制 栈结构栈说明栈定义推入数据弹出数据 调用控制代码示例程序控制流程%rip 传递数据ABI 标准示例 管理局部…

WPF Button使用漂亮 控件模板ControlTemplate 按钮使用控制模板实例及源代码 设计一个具有圆角边框、鼠标悬停时颜色变化的按钮模板

续前两篇模板文章 模板介绍1 模板介绍2 WPF中的Button控件默认样式简洁&#xff0c;但可以通过设置模板来实现更丰富的视觉效果和交互体验。按钮模板主要包括背景、边框、内容&#xff08;通常为文本或图像&#xff09;等元素。通过自定义模板&#xff0c;我们可以改…

JVM篇:JVM的简介

JVM简介 JVM全称为Java Virtual Machine&#xff0c;翻译过来就是java虚拟机&#xff0c;Java程序&#xff08;Java二进制字节码&#xff09;的运行环境 JVM的优点&#xff1a; Java最大的一个优点是&#xff0c;一次编写&#xff0c;到处运行。之所以能够实现这个功能就是依…

Docker自建私人云盘系统

Docker自建私人云盘系统。 有个人云盘需求的人&#xff0c;主要需求有这几类&#xff1a; 文件同步、分享需要。 照片、视频同步需要&#xff0c;尤其是全家人都是用的同步。 影视观看需要&#xff08;分为家庭内部、家庭外部&#xff09; 搭建个人网站/博客 云端OFFICE需…

TiDB在WMS物流系统的应用与实践 (转)

业务背景 北京科捷物流有限公司于2003年在北京正式成立,是ISO质量管理体系认证企业、国家AAAAA级物流企业、海关AEO高级认证企业,注册资金1亿元,是中国领先的大数据科技公司——神州控股的全资子公司。科捷物流融合B2B和B2C的客户需求,基于遍布全国的物流网络与自主知识产…

电话号码的字母组合[中等]

一、题目 给定一个仅包含数字2-9的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意1不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digits "23" 输出&am…

【MySQL学习笔记008】多表查询及案例实战

1、多表关系 概述&#xff1a;项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种联系&#xff0c;基本上可分为三种&a…

什么是 NLP (自然语言处理)

NLP&#xff08;自然语言处理&#xff09;到底是做什么&#xff1f; NLP 的全称是 Natural Language Processing&#xff0c;翻译成中文称作&#xff1a;自然语言处理。它是计算机和人工智能的一个重要领域。顾名思义&#xff0c;该领域研究如何处理自然语言。 自然语言就是我…

小狐狸ChatGPT付费创作系统小程序端开发工具提示打开显示无法打开页面解决办法

最新版2.6.7版下载&#xff1a;https://download.csdn.net/download/mo3408/88656497 很多会员在上传小程序前端时经常出现首页无法打开的情况&#xff0c;错误提示无法打开该页面&#xff0c;不支持打开&#xff0c;这种问题其实就是权限问题&#xff0c;页面是通过调用web-v…

实习知识整理13:在购物车界面点击提交订单进入订单信息界面

在这块主要就是对前端传到后端的数据的处理&#xff0c;然后由后端再返还到新的前端界面 首先点击下单按钮后&#xff0c; 提交购物车中所选中的信息 因为前端是将name定义为 cartList[0].cartId &#xff0c;cartList[1].cartId 形式的 所以后端需要重新定义一个类来进行封装…