跳到主要内容

框选

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

  • 如何启用选择与框选
  • 如何配置多选与严格框选
  • 如何设置修饰键与触发事件(eventTypes)

使用

你可以通过插件 Selection 启用选择与框选功能,示例:

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

const graph = new Graph({
  background: {
    color: '#F2F7FA',
  },
})
graph.use(
  new Selection({
    enabled: true,
  }),
)

演示

  • 点击选中节点。
  • 启用多选,按住 Ctrl/Command 后点击节点多选。
  • 启用移动,拖动选框移动节点。
  • 启用框选,在画布空白位置按下鼠标左键,拖动选框来框选节点。
  • 启用严格框选(strict)模式,观察其对框选的影响。
  • 选择与框选配合使用的修饰键,如 alt;按住 alt 键,在画布空白处按下鼠标左键并拖动选框来框选节点。
  • 应用自定义过滤器(排除 circle 节点),圆形节点不能被选中。
  • 应用自定义附加内容(显示选中节点个数),选择两个及以上的节点,触发显示自定义内容。
import './index.less'
import { createRoot } from 'react-dom/client'
import React from 'react'
import { Graph, Selection } from '@antv/x6'
import { Settings, State } from './settings.tsx'

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

  componentDidMount() {
    this.graph = new Graph({
      container: this.container,
      background: {
        color: '#F2F7FA',
      },
    })

    this.graph.use(
      new Selection({
        enabled: true,
        multiple: true,
        rubberband: true,
        movable: true,
        showNodeSelectionBox: true,
      }),
    )

    this.graph.addNode({
      x: 320,
      y: 100,
      width: 100,
      height: 40,
      label: 'Rect',
      attrs: {
        body: {
          stroke: '#8f8f8f',
          strokeWidth: 1,
          fill: '#fff',
          rx: 6,
          ry: 6,
        },
      },
    })

    const source = this.graph.addNode({
      x: 80,
      y: 50,
      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: 240,
      y: 200,
      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,
        },
      },
    })
  }

  onSettingChanged = (options: State) => {
    this.graph.toggleMultipleSelection(options.multiple)
    this.graph.toggleSelectionMovable(options.movable)
    this.graph.toggleRubberband(options.rubberband)
    this.graph.toggleStrictRubberband(options.strict)
    this.graph.setSelectionFilter(options.filter)
    this.graph.setRubberbandModifiers(options.modifiers as any)
    this.graph.setSelectionDisplayContent(
      options.content
        ? (selection) => {
            return `${selection.length} node${
              selection.length > 1 ? 's' : ''
            } selected.`
          }
        : null,
    )
  }

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

  render() {
    return (
      <div className="selection-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 true 是否启用 Selection 插件
className string - 附加样式名,用于定制样式
multiple boolean true 是否启用点击多选,启用后按住 ctrl 或 command 键点击节点实现多选
multipleSelectionModifiers ModifierKey ['ctrl', 'meta'] 用于设置上面点击多选配套的修饰键
rubberband boolean false 是否启用框选节点功能
rubberNode boolean true 框选时是否将节点纳入框选范围计算
rubberEdge boolean false 框选时是否将边纳入框选范围计算
modifiers ModifierKey - 用于设置上面框选配套的修饰键
strict boolean false 选框是否需要完全包围节点时才选中节点
movable boolean true 拖动选框时框选的节点是否一起移动
content string - 设置附加显示的内容
filter Filter - 节点过滤器
showNodeSelectionBox boolean false 是否显示节点的选择框
showEdgeSelectionBox boolean false 是否显示边的选择框
pointerEvents 'none' | 'auto' auto 如果打开 showNodeSelectionBox 时,会在节点上方盖一层元素,导致节点的事件无法响应,此时可以配置 pointerEvents: none 来解决,默认值是 auto
eventTypes SelectionEventType[] ['leftMouseDown', 'mouseWheelDown'] 用于设置框选的触发事件类型
movingRouterFallback string - 批量拖拽框选节点过程中,支持临时将与选中节点相连边的路由降级为指定路由,拖拽停止并空闲后自动恢复为原始路由(推荐在拖拽大量节点且边的原始路由为 manhattan 时,将 movingRouterFallback 设置为 orth,能有效提升拖拽流畅性)

Filter 的类型定义如下:

type Filter = string[] | { id: string }[] | (this: Graph, cell: Cell) => boolean
  • string[]: 节点 shape 数组,指定的节点/边 shape 才能被选中
  • ({ id: string })[]: 节点 ID 数组,指定的节点/边才能被选中
  • (this: Graph, cell: Cell) => boolean: 返回 true 的节点/边才能被选中

ModifierKey 的类型定义如下:

type ModifierKey = string | ('alt' | 'ctrl' | 'meta' | 'shift' | 'space')[] | null

X6 中修饰键包括 alt、ctrl、meta、shift、space 五个,设置修饰键后点击鼠标并按下修饰键即可触发相应的行为。如果框选和画布拖拽平移的触发条件完全相同时,即相同事件类型(eventTypes)和修饰键(modifiers),框选的优先级更高(禁用默认的画布拖拽平移);如果触发条件不同,则互不影响。因此在同时开始框选和拖拽画布时,修饰键就非常有用,比如框选和拖拽画布的触发时机都是鼠标左键在画布空白位置按下(leftMouseDown),这时可以为框选和拖拽画布设置不一样的修饰键,达到同时开启又不冲突的效果。支持配置单个(如 alt)或多个(如 ['alt', 'ctrl'])修饰键,通过数组形式配置的多个修饰键是或关系,比如刚刚配置的修饰键表示按下 alt 或 ctrl,如果需要更加灵活的配置,可以使用如下这些形式:

  • alt 表示按下 alt。
  • [alt, ctrl], 表示按下 alt 或 ctrl。
  • alt|ctrl 表示按下 alt 或 ctrl。
  • alt&ctrl 表示同时按下 alt 和 ctrl。
  • alt|ctrl&shift 表示同时按下 alt 和 shift 或者同时按下 ctrl 和 shift。

SelectionEventType 的类型定义如下:

type SelectionEventType = 'leftMouseDown' | 'mouseWheelDown';

触发框选的交互方式。支持2种形式或者他们之间的组合:

  • leftMouseDown: 按下鼠标左键移动进行拖拽
  • mouseWheelDown: 按下鼠标滚轮进行拖拽

API

graph.select(…)

select(cells: Cell | string | (Cell | string)[]): this

选中指定的节点/边。需要注意的是,该方法不会取消选中当前选中的节点/边,而是将指定的节点/边追加到选区中。如果同时需要取消选中当前选中的节点/边,请使用 resetSelection(…) 方法。

graph.unselect(…)

unselect(cells: Cell | string | (Cell | string)[]): this

取消选中指定的节点/边。

graph.isSelected(…)

isSelected(cell: Cell | string): boolean

返回指定的节点/边是否被选中。

graph.resetSelection(…)

resetSelection(cells?: Cell | string | (Cell | string)[]): this

先清空选区,然后选中提供的节点/边。

graph.getSelectedCells()

getSelectedCells(): Cell[]

获取选中的节点/边。

graph.cleanSelection()

cleanSelection(): this

清空选区。

graph.isSelectionEmpty()

isSelectionEmpty(): boolean

返回选区是否为空。

graph.isSelectionEnabled()

isSelectionEnabled(): boolean

返回是否启用选择能力。

graph.enableSelection()

enableSelection(): this

启用选择能力。

graph.disableSelection()

disableSelection(): this

禁用选择能力。

graph.toggleSelection(…)

toggleSelection(enabled?: boolean): this

切换选择的启用状态。参数如下:

名称 类型 必选 默认值 描述
enabled boolean - 是否启用选择能力,缺省时切换选择的启用状态。

graph.isMultipleSelection()

isMultipleSelection(): boolean

返回是否启用了多选。

graph.enableMultipleSelection()

enableMultipleSelection(): this

启用多选。

graph.disableMultipleSelection()

disableMultipleSelection(): this

禁用多选。

graph.toggleMultipleSelection(…)

toggleMultipleSelection(multiple?: boolean): this

切换多选的启用状态。参数如下:

名称 类型 必选 默认值 描述
multiple boolean - 是否启用多选,缺省时切换多选的启用状态。

graph.isSelectionMovable()

isSelectionMovable(): boolean

返回选中的节点/边是否可以被移动。

graph.enableSelectionMovable()

enableSelectionMovable(): this

启用选中的节点/边的移动。

graph.disableSelectionMovable()

disableSelectionMovable(): this

禁用选中节点/边的移动。

graph.toggleSelectionMovable(…)

toggleSelectionMovable(enabled?: boolean): this

切换选中节点/边是否可以被移动。参数如下:

名称 类型 必选 默认值 描述
enabled boolean - 是否启用选中的节点/边的移动,缺省时切换启用状态。

graph.isRubberbandEnabled()

isRubberbandEnabled(): boolean

返回是否启用了框选。

graph.enableRubberband()

enableRubberband(): this

启用框选。

graph.disableRubberband()

disableRubberband(): this

禁用框选。

graph.toggleRubberband(…)

toggleRubberband(enabled?: boolean): this

切换框选的启用状态。参数如下:

名称 类型 必选 默认值 描述
enabled boolean - 是否启用框选,缺省时切换启用状态。

graph.isStrictRubberband()

isStrictRubberband(): boolean

返回是否启用了严格框选。启用严格框选后,只有节点/边被选框完全包围时才会选中节点/边。

graph.enableStrictRubberband()

enableStrictRubberband(): this

启用严格框选。启用严格框选后,只有节点/边被选框完全包围时才会选中节点/边。

graph.disableStrictRubberband()

disableStrictRubberband(): this

禁用严格框选。禁用严格框选后,只需要选框与节点/边的包围盒相交即可选中节点/边。

graph.toggleStrictRubberband(…)

toggleStrictRubberband(enabled?: boolean): this

切换严格框选的启用状态。参数如下:

名称 类型 必选 默认值 描述
enabled boolean - 是否启用严格框选,缺省时切换启用状态。

graph.setSelectionFilter(…)

setSelectionFilter(
  filter?:
   | null
   | (string | { id: string })[]
   | ((this: Graph, cell: Cell) => boolean)
): this

设置选择的过滤条件,满足过滤条件的节点/边才能被选中。

开启 filter 后,blank 上 rubberband 框选过程中 box:mousemove 和 box:mouseup 事件返回的 nodes、edges 也会应用相同的过滤规则,因此其预览结果会和最终 selection 保持一致。

graph.setRubberbandModifiers(…)

setRubberbandModifiers(modifiers?: string | ModifierKey[] | null): this

设置框选的修饰键,只有同时按下修饰键时才能触发框选。

graph.setSelectionDisplayContent(…)

setSelectionDisplayContent(
  content?:
   | null
   | false
   | string
   | ((this: Graph, selection: Selection, contentElement: HTMLElement) => string)
): this

设置选中节点/边的附加显示内容。

事件

事件名称 参数类型 描述
cell:selected { cell: Cell; options: Model.SetOptions } 节点/边被选中时触发
node:selected { node: Node; options: Model.SetOptions } 节点被选中时触发
edge:selected { edge: Edge; options: Model.SetOptions } 边被选中时触发
cell:unselected { cell: Cell; options: Model.SetOptions } 节点/边被取消选中时触发
node:unselected { node: Node; options: Model.SetOptions } 节点被取消选中时触发
edge:unselected { edge: Edge; options: Model.SetOptions } 边被取消选中时触发
box:mousedown { e: Dom.MouseDownEvent; view: CellView | null; cell: Cell | null; x: number; y: number; nodes: Node[]; edges: Edge[] } 按下 selection box,或在画布空白处开始 rubberband 框选时触发
box:mousemove { e: Dom.MouseMoveEvent; view: CellView | null; cell: Cell | null; x: number; y: number; nodes: Node[]; edges: Edge[] } 拖动 selection box,或 rubberband 框选过程中实时触发
box:mouseup { e: Dom.MouseUpEvent; view: CellView | null; cell: Cell | null; x: number; y: number; nodes: Node[]; edges: Edge[] } 结束拖动 selection box,或结束 rubberband 框选时触发
selection:changed {added: Cell[]; removed: Cell[]; selected: Cell[]; options: Model.SetOptions} 选中的节点/边发生改变(增删)时触发

box:* 事件中的参数说明:

  • x、y:当前鼠标所在的图坐标。
  • nodes、edges:当前 box 对应的节点和边集合。
  • view、cell:当前关联的视图和单元,在 blank 上进行 rubberband 框选时可能为 null。

nodes 和 edges 在不同交互阶段表示的含义如下:

  • 在画布空白处开始或拖动 rubberband 框选时,nodes 和 edges 表示当前选框实时命中的节点和边; strict 和 filter 配置会影响该结果。
  • 在拖动已有 selection box 时,nodes 和 edges 表示当前 selection 中的节点和边。
graph.on('node:selected', ({ node }) => {
  console.log(node)
})

graph.on('box:mousemove', ({ nodes, edges, cell }) => {
  console.log(nodes, edges, cell)
})

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

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

↑↓选择↵打开Esc关闭