---
title: 框选
order: 5
redirect_from:
  - /zh/docs
  - /zh/docs/tutorial
  - /zh/docs/tutorial/plugins
---

:::info{title=在本章节中，主要介绍框选插件相关的知识，通过阅读，你可以了解到：}

- 如何开启选择交互
  :::

## 使用

我们提供了一个独立的插件包 `@antv/x6-plugin-selection` 来使用框选功能。

```shell
# npm
$ npm install @antv/x6-plugin-selection --save

# yarn
$ yarn add @antv/x6-plugin-selection
```

然后我们在代码中这样使用：

```ts
import { Selection } from "@antv/x6-plugin-selection";

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

## 演示

- 点击选中节点。
- 启用多选，按住 Ctrl/Command 后点击节点多选。
- 启用移动，拖动选框移动节点。
- 启用框选，在画布空白位置按下鼠标左键，拖动选框来框选节点。
- 启用严格框选模式(strict)，观察对框选的影响。
- 选择与框选配合使用的修饰键，如 `alt` 键，按住 `alt` 键并画布空白位置按下鼠标左键，拖动选框来框选节点。
- 应用自定义过滤器(排除 circle 节点)，圆形节点不能被选中。
- 应用自定义附加内容(显示选中节点个数)，选择两个及以上的节点，触发显示自定义内容。

<code id="plugin-selection" src="@/src/tutorial/plugins/selection/index.tsx"></code>

## 配置

| 属性名                     | 类型           | 默认值             | 必选 | 描述                                                                                                                                           |
| -------------------------- | -------------- | ------------------ | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| enabled                    | boolean        | `false`            |      | 是否开启框选功能                                                                                                                               |
| className                  | string         | -                  |      | 附加样式名，用于定制样式                                                                                                                       |
| multiple                   | boolean        | `true`             |      | 是否启用点击多选，启用后按住 `ctrl` 或 `command` 键点击节点实现多选                                                                            |
| multipleSelectionModifiers | ModifierKey    | `['ctrl', 'meta']` |      | 用于设置上面点击多选配套的修饰键                                                                                                               |
| rubberband                 | boolean        | `false`            |      | 是否启用多选节点功能                                                                                                                           |
| modifiers                  | ModifierKey    | -                  |      | 设置修饰键后需要点击鼠标并按下修饰键才能触发多选                                                                                               |
| strict                     | boolean        | `false`            |      | 选框是否需要完全包围节点时才选中节点                                                                                                           |
| movable                    | boolean        | `true`             |      | 拖动选框时框选的节点是否一起移动                                                                                                               |
| content                    | string         | -                  |      | 设置附加显示的内容                                                                                                                             |
| filter                     | Filter         | -                  |      | 节点过滤器                                                                                                                                     |
| showNodeSelectionBox       | boolean        | `false`            |      | 是否显示节点的选择框                                                                                                                           |
| showEdgeSelectionBox       | boolean        | `false`            |      | 是否显示边的选择框                                                                                                                             |
| pointerEvents              | `node \| auto` | `auto`             |      | 如果打开 `showNodeSelectionBox` 时，会在节点上方盖一层元素，导致节点的事件无法响应，此时可以配置 `pointerEvents: none` 来解决，默认值是 `auto` |

`Filter` 的类型定义如下：

```ts
type Filter = string[] | { id: string }[] | (this: Graph, cell: Cell) => boolean
```

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

`ModifierKey` 的类型定义如下：

```ts
type ModifierKey = string | ("alt" | "ctrl" | "meta" | "shift")[] | null;
```

X6 中修饰键包括 `'alt'`、`'ctrl'`、`'meta'`、`'shift'` 四个，设置修饰键后需要点击鼠标并按下修饰键才能触发相应的行为。修饰键在某些场景下非常有用，比如同时开始框选和拖拽画布时，而框选和拖拽画布的触发时机都是鼠标左键在画布空白位置按下，这时可以为框选和拖拽画布设置不一样的修饰键，达到同时开启又不冲突的效果。支持配置单个（如 `'alt'`）或多个（如 `['alt', 'ctrl']`）修饰键，通过数组形式配置的多个修饰键是或关系，比如刚刚配置的修饰键表示按下 `'alt'` 或 `'ctrl'`，如果需要更加灵活的配置，可以使用如下这些形式：

- `'alt|ctrl'` 表示按下 `'alt'` 或 `'ctrl'`。
- `'alt&ctrl'` 表示同时按下 `'alt'` 和 `'ctrl'`。
- `'alt|ctrl&shift'` 表示同时按下 `'alt'` 和 `'shift'` 或者同时按下 `'ctrl'` 和 `'shift'`。

## API

### graph.select(...)

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

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

### graph.unselect(...)

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

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

### graph.isSelected(...)

```sign
isSelected(cell: Cell | string): boolean
```

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

### graph.resetSelection(...)

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

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

### graph.getSelectedCells()

```sign
getSelectedCells(): Cell[]
```

获取选中的节点/边。

### graph.cleanSelection()

```sign
cleanSelection(): this
```

清空选区。

### graph.isSelectionEmpty()

```sign
cleanSelection(): boolean
```

返回选区是否为空。

### graph.isSelectionEnabled()

```sign
isSelectionEnabled(): boolean
```

是否启用选择能力。

### graph.enableSelection()

```sign
enableSelection(): this
```

启用选择能力。

### graph.disableSelection()

```sign
disableSelection(): this
```

禁用选择能力。

### graph.toggleSelection(...)

```sign
toggleSelection(enabled?: boolean): this
```

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

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

### graph.isMultipleSelection()

```sign
isMultipleSelection(): boolean
```

是否启用了多选。

### graph.enableMultipleSelection()

```sign
enableMultipleSelection(): this
```

启用多选。

### graph.disableMultipleSelection()

```sign
disableMultipleSelection(): this
```

禁用多选。

### graph.toggleMultipleSelection(...)

```sign
toggleMultipleSelection(multiple?: boolean): this
```

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

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

### graph.isSelectionMovable()

```sign
isSelectionMovable(): boolean
```

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

### graph.enableSelectionMovable()

```sign
enableSelectionMovable(): this
```

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

### graph.disableSelectionMovable()

```sign
disableSelectionMovable(): this
```

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

### graph.toggleSelectionMovable(...)

```sign
toggleSelectionMovable(enabled?: boolean): this
```

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

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

### graph.isRubberbandEnabled()

```sign
isRubberbandEnabled(): boolean
```

返回是否启用了框选。

### graph.enableRubberband()

```sign
enableRubberband(): this
```

启用框选。

### graph.disableRubberband()

```sign
disableRubberband(): this
```

禁用框选。

### graph.toggleRubberband(...)

```sign
toggleRubberband(enabled?: boolean): this
```

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

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

### graph.isStrictRubberband()

```sign
isStrictRubberband(): boolean
```

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

### graph.enableStrictRubberband()

```sign
enableStrictRubberband(): this
```

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

### graph.disableStrictRubberband()

```sign
disableStrictRubberband(): this
```

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

### graph.toggleStrictRubberband(...)

```sign
toggleStrictRubberband(enabled?: boolean): this
```

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

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

### graph.setSelectionFilter(...)

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

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

### graph.setRubberbandModifiers(...)

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

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

### graph.setSelectionDisplayContent(...)

```sign
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 }`                                     | 边被取消选中时触发                |
| `selection:changed` | `{added: Cell[]; removed: Cell[]; selected: Cell[]; options: Model.SetOptions}` | 选中的节点/边发生改变(增删)时触发 |

```ts
graph.on("node:selected", ({ node }) => {
  console.log(node);
});

// 我们也可以在插件实例上监听事件
selection.on("node:selected", ({ node }) => {
  console.log(node);
});
```
