# @knotx/plugins-minimap

小地图插件，为 KnotX 提供画布导航功能。

## 安装

```bash
npm install @knotx/plugins-minimap
```

## 概述

Minimap 插件为 KnotX 提供了小地图功能，允许用户在大型画布中快速导航。该插件基于 `interactjs` 库实现，提供了缩放、平移、视窗控制等功能。

## 实现原理

Minimap 插件的核心实现原理：

1. **节点映射**：将画布上的节点映射到小地图的比例尺中
2. **视窗同步**：实时同步主画布和小地图的视窗状态
3. **交互控制**：支持在小地图上拖拽和点击进行导航
4. **缩放控制**：提供缩放按钮和重置功能

## 依赖关系

### 核心依赖
- `@knotx/core`：提供基础插件架构
- `@knotx/decorators`：提供装饰器支持
- `interactjs`：提供交互功能
- `rxjs`：提供响应式编程支持

### 插件依赖
- `@knotx/plugins-canvas`：获取画布变换状态和容器信息

## API 文档

### 主要类

#### Minimap

小地图插件的主要类，继承自 `BasePlugin`。

```typescript
export class Minimap extends BasePlugin<'minimap', MinimapConfig> {
  name = 'minimap' as const
}
```

### 配置选项

#### MinimapConfig

```typescript
export interface MinimapConfig {
  /** 小地图宽度 */
  width?: number
  /** 小地图高度 */
  height?: number
  /** 节点颜色 */
  nodeColor?: string | ((node: Node) => string)
  /** 视图区域背景颜色 */
  maskColor?: string
  /** 视图区域边框颜色 */
  viewBoxColor?: string
  /** 显示小地图控制按钮 */
  showControls?: boolean
  /** 是否可缩放 */
  zoomable?: boolean
  /** 是否可平移 */
  pannable?: boolean
  /** 与容器的内边距 */
  padding?: number
  /** 节点圆角 */
  nodeBorderRadius?: number
  /** 节点描边宽度 */
  nodeStrokeWidth?: number
  /** 节点描边颜色 */
  nodeStrokeColor?: string | ((node: Node) => string)
  /** 缩放步长 */
  zoomStep?: number
}
```

### 默认配置

```typescript
const defaultProps: Required<Omit<MinimapConfig, 'nodeColor' | 'nodeStrokeColor'>> = {
  width: 200,
  height: 150,
  maskColor: 'rgba(240, 240, 240, 0.6)',
  viewBoxColor: '#4752E6',
  showControls: true,
  zoomable: true,
  pannable: true,
  padding: 12,
  nodeBorderRadius: 2,
  nodeStrokeWidth: 1,
  zoomStep: 0.2,
}
```

## 使用示例

### 基本用法

```typescript
import { Minimap } from '@knotx/plugins-minimap'

const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      width: 200,
      height: 150,
    },
  },
})
```

### 自定义样式

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      width: 250,
      height: 180,
      nodeColor: '#4A90E2',
      maskColor: 'rgba(255, 255, 255, 0.8)',
      viewBoxColor: '#FF6B6B',
      nodeBorderRadius: 4,
      nodeStrokeWidth: 2,
      nodeStrokeColor: '#333',
    },
  },
})
```

### 动态节点颜色

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      nodeColor: (node) => {
        // 根据节点类型返回不同颜色
        switch (node.type) {
          case 'start':
            return '#4CAF50'
          case 'end':
            return '#F44336'
          case 'process':
            return '#2196F3'
          default:
            return '#9E9E9E'
        }
      },
      nodeStrokeColor: (node) => {
        return node.selected ? '#FF9800' : 'transparent'
      },
    },
  },
})
```

### 禁用控制按钮

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      showControls: false,
      zoomable: false,
      pannable: true,
    },
  },
})
```

### 自定义尺寸和位置

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      width: 300,
      height: 200,
      padding: 20,
      zoomStep: 0.3,
    },
  },
})
```

## 高级功能

### 与 Canvas 插件集成

```typescript
import { Canvas } from '@knotx/plugins-canvas'
import { Minimap } from '@knotx/plugins-minimap'

const engine = new Engine({
  plugins: [Canvas, Minimap],
  pluginConfig: {
    canvas: {
      minScale: 0.1,
      maxScale: 3,
    },
    minimap: {
      width: 200,
      height: 150,
    },
  },
})
```

### 监听小地图交互

```typescript
class MinimapInteractionPlugin extends BasePlugin {
  @inject.canvas.transform()
  transform!: CanvasTransformState

  @subscribe.canvas.transform()
  onTransformChange(transform: CanvasTransformState) {
    console.log('Canvas transform changed:', transform)
    // 小地图会自动同步变换状态
  }
}
```

### 自定义小地图行为

```typescript
class CustomMinimapPlugin extends BasePlugin {
  @inject.minimap.config()
  minimapConfig!: MinimapConfig

  @OnInit
  init() {
    // 动态调整小地图配置
    this.minimapConfig.nodeColor = (node) => {
      const isImportant = node.data?.important
      return isImportant ? '#FF5722' : '#607D8B'
    }
  }
}
```

## 样式自定义

### CSS 类名

小地图提供了以下 CSS 类名用于样式自定义：

```css
.knotx-minimap {
  /* 小地图容器 */
  border: 1px solid #ddd;
  border-radius: 4px;
  background: #fff;
}

.knotx-minimap__svg {
  /* SVG 容器 */
  cursor: crosshair;
}

.knotx-minimap__controls {
  /* 控制按钮容器 */
  display: flex;
  gap: 4px;
  margin-top: 8px;
}

.knotx-minimap__button {
  /* 控制按钮 */
  padding: 4px 8px;
  border: 1px solid #ccc;
  background: #f5f5f5;
  cursor: pointer;
}

.knotx-minimap__button:hover {
  background: #e0e0e0;
}

.knotx-minimap__button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
```

### 自定义样式示例

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      width: 200,
      height: 150,
      // 自定义视窗颜色
      viewBoxColor: '#FF6B6B',
      // 自定义蒙版颜色
      maskColor: 'rgba(255, 107, 107, 0.1)',
    },
  },
})
```

## 性能优化

### 节点渲染优化

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      // 使用固定颜色避免函数调用开销
      nodeColor: '#4A90E2',
      nodeStrokeColor: 'transparent',
      // 减少圆角以提高渲染性能
      nodeBorderRadius: 0,
    },
  },
})
```

### 交互优化

```typescript
const engine = new Engine({
  plugins: [Minimap],
  pluginConfig: {
    minimap: {
      // 较小的缩放步长提供更平滑的体验
      zoomStep: 0.1,
      // 合适的尺寸平衡性能和可用性
      width: 180,
      height: 120,
    },
  },
})
```

## 文件目录结构

```
packages/plugins-minimap/
├── src/
│   ├── minimap.tsx             # 主要实现文件
│   └── index.ts               # 导出文件
├── dist/                      # 构建输出目录
├── package.json              # 包配置文件
├── build.config.ts           # 构建配置
├── tsconfig.json             # TypeScript 配置
├── eslint.config.mjs         # ESLint 配置
└── CHANGELOG.md              # 更新日志
```

### 核心文件说明

- **minimap.tsx**：包含 Minimap 插件的主要实现，包括节点映射、视窗同步和交互控制
- **index.ts**：导出 Minimap 类和相关类型定义

## 最佳实践

### 用户体验

1. **合适的尺寸**：根据应用布局选择合适的小地图尺寸
2. **清晰的视觉反馈**：使用对比度高的颜色区分不同元素
3. **平滑的交互**：合理配置缩放步长和动画效果

### 性能优化

1. **固定颜色**：对于大量节点，使用固定颜色而非动态函数
2. **简化样式**：减少不必要的视觉效果以提高渲染性能
3. **合理尺寸**：根据节点数量调整小地图尺寸

### 开发调试

1. **监听状态变化**：在开发阶段监听变换状态变化
2. **测试交互**：确保小地图与主画布的同步正常
3. **验证边界**：测试极端缩放和平移情况

## 注意事项

1. **依赖关系**：确保 Canvas 插件在 Minimap 插件之前加载
2. **性能考虑**：大量节点时，小地图的渲染可能影响性能
3. **响应式设计**：考虑在不同屏幕尺寸下的小地图显示
4. **浏览器兼容性**：依赖 SVG 和现代 JavaScript 特性

## 许可证

MIT
