跳到主要内容

图形变换

在本章节中主要介绍图形变换插件相关的知识,通过阅读,你可以了解到

  • 如何通过交互插件调整节点大小
  • 如何通过交互插件调整节点旋转角度

使用

使用 UI 组件来调整节点尺寸和角度是常见需求。我们提供插件 transform 来实现该功能,代码示例如下:

import { Graph, Transform } from '@antv/x6'

const graph = new Graph({
  background: {
    color: '#F2F7FA',
  },
})
graph.use(
  new Transform({
    resizing: resizingOptions,
    rotating: rotatingOptions,
  }),
)

演示

首先我们体验使用交互修改节点尺寸(点击节点出现操作组件):

import './index.less'
import { createRoot } from 'react-dom/client'
import React from 'react'
import { Graph, Transform } from '@antv/x6'
import { Settings, State } from './settings.tsx'

export default class Example extends React.Component {
  private container: HTMLDivElement
  private graph: Graph

  componentDidMount() {
    this.initGraph({
      enabled: true,
      minWidth: 1,
      maxWidth: 200,
      minHeight: 1,
      maxHeight: 150,
      orthogonal: false,
      restrict: false,
      preserveAspectRatio: false,
    })
  }

  initGraph = (options: State) => {
    if (this.graph) {
      this.graph.dispose()
    }
    this.graph = new Graph({
      container: this.container,
      background: {
        color: '#F2F7FA',
      },
    })

    this.graph.use(
      new Transform({
        resizing: options,
      }),
    )

    const source = this.graph.addNode({
      shape: 'rect',
      x: 32,
      y: 32,
      width: 100,
      height: 40,
      label: 'Hello',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
          rx: 6,
          ry: 6,
        },
      },
    })

    const target = this.graph.addNode({
      shape: 'circle',
      x: 160,
      y: 180,
      width: 60,
      height: 60,
      label: 'World',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
        },
      },
    })

    this.graph.addEdge({
      source,
      target,
      attrs: {
        line: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
        },
      },
    })

    this.graph.centerContent()
  }

  onSettingChanged = (options: State) => {
    this.initGraph(options)
  }

  refContainer = (container: HTMLDivElement) => {
    this.container = container
  }

  render() {
    return (
      <div className="resizing-app">
        <div className="app-side">
          <Settings onChange={this.onSettingChanged} />
        </div>
        <div className="app-content" ref={this.refContainer} />
      </div>
    )
  }
}

const root = createRoot(document.getElementById('container')!)
root.render(<Example />)
window.addEventListener('pagehide', () => root.unmount(), { once: true })

接下来体验使用交互修改节点旋转角度(点击节点出现操作组件):

import './index.less'
import { createRoot } from 'react-dom/client'
import React from 'react'
import { Graph, Transform } from '@antv/x6'
import { Settings, State } from './settings.tsx'

export default class Example extends React.Component {
  private container: HTMLDivElement
  private graph: Graph

  componentDidMount() {
    this.initGraph({
      enabled: true,
      grid: 15,
    })
  }

  initGraph = (options: State) => {
    if (this.graph) {
      this.graph.dispose()
    }
    this.graph = new Graph({
      container: this.container,
      background: {
        color: '#F2F7FA',
      },
    })

    this.graph.use(
      new Transform({
        rotating: options,
      }),
    )

    const source = this.graph.addNode({
      x: 60,
      y: 130,
      width: 100,
      height: 40,
      label: 'Hello',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
          rx: 6,
          ry: 6,
        },
      },
    })

    const target = this.graph.addNode({
      shape: 'circle',
      x: 260,
      y: 120,
      width: 60,
      height: 60,
      label: 'World',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
          rx: 6,
          ry: 6,
        },
      },
    })

    this.graph.addEdge({
      source,
      target,
      attrs: {
        line: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
        },
      },
    })

    this.graph.centerContent()
  }

  onSettingChanged = (options: State) => {
    this.initGraph(options)
  }

  refContainer = (container: HTMLDivElement) => {
    this.container = container
  }

  render() {
    return (
      <div className="rotating-app">
        <div className="app-side">
          <Settings onChange={this.onSettingChanged} />
        </div>
        <div className="app-content" ref={this.refContainer} />
      </div>
    )
  }
}

const root = createRoot(document.getElementById('container')!)
root.render(<Example />)
window.addEventListener('pagehide', () => root.unmount(), { once: true })

配置

调整尺寸

属性名 类型 默认值 必选 描述
enabled boolean false 是否支持调整节点大小
minWidth number 0 最小的调整宽度
minHeight number 0 最小的调整高度
maxWidth number Infinity 最大的调整宽度
maxHeight number Infinity 最大的调整高度
orthogonal boolean true 是否显示中间调整点
restrict boolean false 调整大小边界是否可以超出画布边缘
autoScroll boolean true 拖动位置超过画布时是否自动滚动画布
preserveAspectRatio boolean false 调整大小过程中是否保持节点的宽高比例
allowReverse boolean true 到达最小宽度或者高度时是否允许控制点反向拖动

上面的配置除了支持默认类型外,还支持使用函数的方式来动态修改:

new Transform({
  resizing: {
    enabled: true,
    orthogonal(node: Node) {
      const { enableOrthogonal } = node.getData()
      return enableOrthogonal
    },
  },
})

调整角度

属性名 类型 默认值 必选 描述
enabled boolean false 是否支持调整节点角度
grid number 15 每次旋转的角度

上面的配置除了支持默认类型外,还支持使用函数的方式来动态修改:

new Transform({
  rotating: {
    enabled: true,
    grid() {
      return 30
    },
  },
})

API

graph.createTransformWidget(node: Node)

为节点创建 transform 控件。

graph.clearTransformWidgets()

清除所有 transform 控件。

事件

事件名称 参数类型 描述
node:resize { e: Dom.MouseDownEvent; x: number; y: number; node: Node; view: NodeView } 开始调整节点大小时触发
node:resizing { e: Dom.MouseMoveEvent; x: number; y: number; node: Node; view: NodeView } 调整节点大小时触发
node:resized { e: Dom.MouseUpEvent; x: number; y: number; node: Node; view: NodeView } 调整节点大小后触发
node:rotate { e: Dom.MouseDownEvent; x: number; y: number; node: Node; view: NodeView } 开始旋转节点时触发
node:rotating { e: Dom.MouseMoveEvent; x: number; y: number; node: Node; view: NodeView } 旋转节点时触发
node:rotated { e: Dom.MouseUpEvent; x: number; y: number; node: Node; view: NodeView } 旋转节点后触发
graph.on('node:rotated', ({ node }) => {
  console.log(node.angle())
})

// 我们也可以在插件实例上监听事件
transform.on('node:rotated', ({ node }) => {
  console.log(node.angle())
})
© Copyright 2026 Ant Group Co., Ltd..备案号:京ICP备15032932号-38
全站搜索
文档与示例输入关键词开始搜索

输入关键词,查找文档、API 与示例

↑↓选择↵打开Esc关闭