4-节点

简介

1 .除了支持基类的属性,还有这些自定义属性

1 .x:节点的x坐标
2 .y:节点的y坐标
3 .width:节点的宽度
4 .height:节点的高度
5 .angle:节点的角度
6 .zIndex:节点的层级,这个感觉应该不算.这个是cell就有的
7 .label:''

2 .创建节点的新方式,html

graph.createNode({
            width: 60,
            height: 60,
            shape: 'html',
            html: () => {
              const wrap = document.createElement('div')
              wrap.style.width = '100%'
              wrap.style.height = '100%'
              wrap.style.display = 'flex'
              wrap.style.alignItems = 'center'
              wrap.style.justifyContent = 'center'
              wrap.style.border = '2px solid rgb(49, 208, 198)'
              wrap.style.background = '#fff'
              wrap.style.borderRadius = '100%'
              wrap.innerText = 'Circle'
              return wrap
            },
          })

基础选项

id

1 .节点边的唯一标识,默认使用自动生成的UUID

markup

1 .节点.边的SVG/HTML片段,指定了渲染节点/边时使用的SVG,html片段.使用json格式描述.


image.png
1 .以上是一个矩形里面有文字的节点的markup结构,渲染出来是这样的
<g data-cell-id="c2e1dd06-15c6-43a4-987a-712a664b8f85" class="x6-cell x6-node" transform="translate(40,40)">
  <rect fill="#fff" stroke="#000" stroke-width="2" fill-opacity="0.5" width="100" height="40"></rect>
  <text font-size="14" xml:space="preserve" fill="#333" text-anchor="middle" font-family="Arial, helvetica, sans-serif" transform="matrix(1,0,0,1,50,20)">
    <tspan dy="0.3em" class="v-line">rect</tspan>
  </text>
</g>
//感觉有点像react的意思了
2 .tagName:svg,html元素标签名
3 .ns与tagName对应的元素命名空间.默认使用svg元素命名空间'http://www.w3.org/2000/svg',如果tagName指定的是标签是HTML标签的话,需要使用html元素的命名空间'http://www.w3.org/1999/xhtml"
4 .selector:SVG,HTML元素的唯一标识,通过这个唯一标识为该元素执行属性样式https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Fills_and_Strokes.这里的body就是attr里面的body的样式
5 .attrs:注意,这个和外面的attrs还不一样.定义SVG,HTML元素的默认属性值对,通常用于定义那些不变的通用属性,这些默认样式可以在实例化的时候被覆盖.
5.1 .markup的attrs属性只支持原生的SVG属性,X6的自定义属性这李是不行的
6 .style:SVG,html元素的行内样式键值对
7 .className:svg,html元素的css样式名
8 .textContent:svg,html元素的文本内容
9 .children:嵌套的子元素

attrs

1 .节点/边属性样式.创建节点或者准备节点数据时,可以通过attrs对象来配置节点样式,该对象的key时节点SVG元素的选择器,这里和上面对上了
2 .选择器(Selector)通过节点的 markup 确定,如 Shape.Rect 节点定义了 'body'(代表 <rect> 元素) 和 'label'(代表 <text> 元素) 两个选择器

//x6代码
const rect = new Shape.Rect({
  x: 40,
  y: 40,
  width: 100,
  height: 40,
  attrs: { 
    body: {
//body是markup里面的选择器selector
      fill: '#2ECC71',
      stroke: '#000',
    },
//这个也是
    label: {
      text: 'rect',
      fill: '#333',
      fontSize: 13,
    },
  },
})

//渲染出来的结果
<g data-cell-id="3ee1452c-6d75-478d-af22-88e03c6d513b" class="x6-cell x6-node" transform="translate(40,40)">
  <rect fill="#2ECC71" stroke="#000" stroke-width="2" width="100" height="40"></rect>
  <text font-size="13" xml:space="preserve" fill="#333" text-anchor="middle" font-family="Arial, helvetica, sans-serif" transform="matrix(1,0,0,1,50,20)">
    <tspan dy="0.3em" class="v-line">
      rect
    </tspan>
  </text>
</g>

shape

1 .渲染节点/边的图形,将要渲染的图形的模式
2 .在 X6 内部实现中,我们通过 shape 指定的图形找到对应的构造函数来初始化节点/边,并将其添加到画布,rect,edge都是之前写好的.如果我们要自定义节点,这里就用自定义好的节点的名字来初始化
3 .内置节点如下

1 .Shape.Rect:rect(shape名称,到时候里面就填这个) 矩形
2 .Shape.Circle:circle
3 .Shape.Ellipse:ellipse:椭圆
4 .Shape.Polygon:polygon:多边形
5 .Shape.Polyline:polyline:折线
6 .Shape.Path:path:路径
7 .Shape.Image:image:图片
8 .Shape.HTML:html:html节点,使用foreignObject渲染html片段
9 .Shape.TextBlock:text-block:文本节点,使用foreignObject渲染文本
10 .Shape.BorderedImage:image-bordered:带边框的图片
11 .Shape.EmbeddedImage:image-embedded:内嵌入矩形的图片
12 .Shape.InscribedImage:image=inscribed:内嵌入椭圆的图片
13 .Shape.Cylinder:cylinder:圆柱

4 .但是好像还不知道这些内置的元素怎么使用,应该是不同的模式需要传入不同的参数,比如图片这种要传图片的地址

5 .内置边

1 .Shape.Edge:edge:边
2 .Shape.DoubleEdge:'doublle-edge'双线边
3 .Shape.ShadowEdge:'shadow-edge'阴影边

view

渲染节点/边的视图
1 .指定渲染节点/边使用的视图.

zIndex

节点/边在画布中的层级,默认根据节点/边添加的顺序自动确定
1 .边,节点可以通过cell.getIndex(),cell.setIndex来获取或设置zIndex的值,可以调用cell.toForont(),cell.toBack()来将其移动到最顶层或最底层
2 .

visible

节点是否可见

parent父节点

1 .

children:子节点

2 .

data:节点边关联的业务数据

const rect = new Shape.Rect({
  x: 40,
  y: 40,
  width: 100,
  height: 40,
  data: { 
    bizID: 125,
    date: '20200630',
    price: 89.00,
  }
})

修改attr样式

1 .方法1

rect.attr('label/text', 'hello')

2 .方法2

rect.attr('label', {
  text: 'hello'
})

3 .方法3

rect.attr({
  label: {
    text: 'hello'
  }
})

attr属性置空

1 .rect.attr('label/text'.null)

设置默认值

1 .cell.config()可以来配置默认值,

Shape.Rect.config({
  width: 80,
  height: 40,
  markup: [
    {
      tagName: 'rect',
      selector: 'body',
    }, 
    {
      tagName: 'text',
      selector: 'label',
    },
  ],
  attrs: {
    body: {
      fill: '#fff',
      stroke: '#000',
      strokeWidth: 2,
    },
    label: {
      fontSize: 14,
      fill: '#333',
      fontFamily: 'Arial, helvetica, sans-serif',
      textAnchor: 'middle',
      textVerticalAnchor: 'middle',
    }
  },
})

2 .每次调用config(options)都是与当前预设值进行深度merge

自定义选项

1 .定义的时候我们可以随便传,但是这也不对啊,传的这些值也是原来就有的,这里感觉是讲的实现机制

Shape.Rect.config({
  propHooks: {
    rx(metadata) { 
      const { rx, ...others } = metadata
      if (rx != null) {
        ObjectExt.setByPath(others, 'attrs/body/rx', rx)
      }
      return others
    },
    ry(metadata) { 
      const { ry, ...others } = metadata
      if (ry != null) {
        ObjectExt.setByPath(others, 'attrs/body/ry', ry)
      }
      return others
    },
  },
})

问题1 如何自定义节点样式

1 .要用attrs来对已经生成的样式进行重定义.'rect' 图形中定义了 'body'(代表 <rect> 元素) 和 'label'(代表 <text> 元素) 两个选择器(Selector),每种图形都有属于自己的选择器定义,别的图形的定义没找到api文档啊

attrs:{
                body:{
                    fill:"red",
                    stroke:"yellow"
                },
                label:{
                    text:'hello',
                    fill:"#333",
                    fontSize:20
                }
            },

2 .这里的body,label都属于选择器,这些都是原来定义在markUp里面的.
3 .markUp:代表了这个svg节点有两个结构,一个circle和一个text,tagName决定了他们渲染的基类.selector定义了选择器,之后重定义样式的时候就用这个来选中,这里还自定义了一些样式

markup: [
                            {
                                tagName: 'circle',
                                selector: 'button',
                                attrs: {
                                r: 5,
                                stroke: '#fe854f',
                                'stroke-width': 3,
                                fill: 'white',
                                cursor: 'pointer',
                                },
                            },
                            {
                                tagName: 'text',
                                textContent: 'X',
                                selector: 'icon',
                                attrs: {
                                fill: '#fe854f',
                                'font-size': 8,
                                'text-anchor': 'middle',
                                'pointer-events': 'none',
                                y: '0.3em',
                                },
                            },
                    ],

4 .所以当我们需要重定义一个节点的样式的时候,首先要知道他的选择器是什么,然后是选择器对应的节点,以及这些节点可以被操作的属性是什么.然后来调整样式.下面这些都查不出来啊.选择器(Selector)通过节点的 markup 确定


image.png

5 .css选择器来操作样式.不能在定义的时候单独给一个节点传递css样式名,所以只能最后操作一个.或者说我自己在外面嵌套一个来操作.感觉还是没必要的
x6-node,x6-edge
6 .线条的markup

attrs:{
                    line:{
                        stroke:"orange"
                    },
                    wrap:{
                        //透明的外部轮廓,便于选中
                    }
                }

问题2 节点的一些操作

1 .节点位移 node.position(x,y)
2 .节点旋转 node.rotate(30)
3 .节点调整大小 node.resize(100,100)

问题3 如何定制样式Attrs

1 .其实就是覆盖

const rect = new Shape.Rect({
  x: 100,
  y: 40,
  width: 100,
  height: 40,
  attrs: { 
    body: {
      fill: '#2ECC71', // 背景颜色
      stroke: '#000',  // 边框颜色
    },
    label: {
      text: 'rect',    // 文本
      fill: '#333',    // 文字颜色
      fontSize: 13,    // 文字大小
    },
  },
})

问题3 如何基于当前节点添加新的东西

1 .tools里面,markup那一套

const source = graph.addNode({
            id:'node1',
            x: 40,
            y: 40,
            width: 180,
            height: 100,
            label: 'Source',
            attrs:{
                body:{
                    fill:"red",
                    stroke:"yellow"
                },
                label:{
                    text:'hello',
                    fill:"#333",
                    fontSize:20
                }
            },
            tools: [
              {
                name: 'button',
                args: {
                    markup: [
                            {
                                tagName: 'circle',
                                selector: 'button',
                                attrs: {
                                r: 5,
                                stroke: '#fe854f',
                                'stroke-width': 3,
                                fill: 'white',
                                cursor: 'pointer',
                                },
                                className:'node1'
                            },
                            {
                                tagName: 'text',
                                textContent: 'X',
                                selector: 'icon',
                                attrs: {
                                fill: '#fe854f',
                                'font-size': 8,
                                'text-anchor': 'middle',
                                'pointer-events': 'none',
                                y: '0.3em',
                                },
                            },
                    ],
                    x: '100%',
                    y: '100%',
                    offset: { x: -18, y: -18 },
                    onClick({ view }) {
                      const node = view.cell
                      //console.log(view)
                      socket.emit('remove',{id:view.cell.id,room:"1",userId})
                    },
                },
              },
            ],
            ports:{
                groups:{
                    group1:{
                        attrs:{
                            circle: {
                                r: 6,
                                magnet: true,
                                stroke: '#31d0c6',
                                strokeWidth: 2,
                                fill: '#fff',
                              },
                        },
                    }
                },
                //桩模板
                items:[
                    {
                        id:'source-port1',
                        group:'group1'
                    },{
                        id:'source-port2',
                        group:'group1'
                    }
                ]
            }
          })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容