@knotx/plugins-minimap 0.4.12 → 0.4.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +402 -0
- package/README.md +395 -4
- package/package.json +11 -16
package/README.en.md
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# @knotx/plugins-minimap
|
|
2
|
+
|
|
3
|
+
Minimap plugin that provides canvas navigation functionality for KnotX.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @knotx/plugins-minimap
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The Minimap plugin provides minimap functionality for KnotX, allowing users to quickly navigate in large canvases. This plugin is built on the `interactjs` library and provides zoom, pan, viewport control, and other features.
|
|
14
|
+
|
|
15
|
+
## Implementation Principle
|
|
16
|
+
|
|
17
|
+
The core implementation principles of the Minimap plugin:
|
|
18
|
+
|
|
19
|
+
1. **Node Mapping**: Maps nodes on the canvas to the minimap scale
|
|
20
|
+
2. **Viewport Synchronization**: Real-time synchronization of viewport state between main canvas and minimap
|
|
21
|
+
3. **Interaction Control**: Supports dragging and clicking on the minimap for navigation
|
|
22
|
+
4. **Zoom Control**: Provides zoom buttons and reset functionality
|
|
23
|
+
|
|
24
|
+
## Dependencies
|
|
25
|
+
|
|
26
|
+
### Core Dependencies
|
|
27
|
+
- `@knotx/core`: Provides base plugin architecture
|
|
28
|
+
- `@knotx/decorators`: Provides decorator support
|
|
29
|
+
- `interactjs`: Provides interaction functionality
|
|
30
|
+
- `rxjs`: Provides reactive programming support
|
|
31
|
+
|
|
32
|
+
### Plugin Dependencies
|
|
33
|
+
- `@knotx/plugins-canvas`: Retrieves canvas transform state and container information
|
|
34
|
+
|
|
35
|
+
## API Documentation
|
|
36
|
+
|
|
37
|
+
### Main Classes
|
|
38
|
+
|
|
39
|
+
#### Minimap
|
|
40
|
+
|
|
41
|
+
The main class of the Minimap plugin, extending `BasePlugin`.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
export class Minimap extends BasePlugin<'minimap', MinimapConfig> {
|
|
45
|
+
name = 'minimap' as const
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Configuration Options
|
|
50
|
+
|
|
51
|
+
#### MinimapConfig
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export interface MinimapConfig {
|
|
55
|
+
/** Minimap width */
|
|
56
|
+
width?: number
|
|
57
|
+
/** Minimap height */
|
|
58
|
+
height?: number
|
|
59
|
+
/** Node color */
|
|
60
|
+
nodeColor?: string | ((node: Node) => string)
|
|
61
|
+
/** Viewport area background color */
|
|
62
|
+
maskColor?: string
|
|
63
|
+
/** Viewport area border color */
|
|
64
|
+
viewBoxColor?: string
|
|
65
|
+
/** Show minimap control buttons */
|
|
66
|
+
showControls?: boolean
|
|
67
|
+
/** Whether zoomable */
|
|
68
|
+
zoomable?: boolean
|
|
69
|
+
/** Whether pannable */
|
|
70
|
+
pannable?: boolean
|
|
71
|
+
/** Padding from container */
|
|
72
|
+
padding?: number
|
|
73
|
+
/** Node border radius */
|
|
74
|
+
nodeBorderRadius?: number
|
|
75
|
+
/** Node stroke width */
|
|
76
|
+
nodeStrokeWidth?: number
|
|
77
|
+
/** Node stroke color */
|
|
78
|
+
nodeStrokeColor?: string | ((node: Node) => string)
|
|
79
|
+
/** Zoom step */
|
|
80
|
+
zoomStep?: number
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Default Configuration
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const defaultProps: Required<Omit<MinimapConfig, 'nodeColor' | 'nodeStrokeColor'>> = {
|
|
88
|
+
width: 200,
|
|
89
|
+
height: 150,
|
|
90
|
+
maskColor: 'rgba(240, 240, 240, 0.6)',
|
|
91
|
+
viewBoxColor: '#4752E6',
|
|
92
|
+
showControls: true,
|
|
93
|
+
zoomable: true,
|
|
94
|
+
pannable: true,
|
|
95
|
+
padding: 12,
|
|
96
|
+
nodeBorderRadius: 2,
|
|
97
|
+
nodeStrokeWidth: 1,
|
|
98
|
+
zoomStep: 0.2,
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Usage Examples
|
|
103
|
+
|
|
104
|
+
### Basic Usage
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { Minimap } from '@knotx/plugins-minimap'
|
|
108
|
+
|
|
109
|
+
const engine = new Engine({
|
|
110
|
+
plugins: [Minimap],
|
|
111
|
+
pluginConfig: {
|
|
112
|
+
minimap: {
|
|
113
|
+
width: 200,
|
|
114
|
+
height: 150,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Custom Styling
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const engine = new Engine({
|
|
124
|
+
plugins: [Minimap],
|
|
125
|
+
pluginConfig: {
|
|
126
|
+
minimap: {
|
|
127
|
+
width: 250,
|
|
128
|
+
height: 180,
|
|
129
|
+
nodeColor: '#4A90E2',
|
|
130
|
+
maskColor: 'rgba(255, 255, 255, 0.8)',
|
|
131
|
+
viewBoxColor: '#FF6B6B',
|
|
132
|
+
nodeBorderRadius: 4,
|
|
133
|
+
nodeStrokeWidth: 2,
|
|
134
|
+
nodeStrokeColor: '#333',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Dynamic Node Colors
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const engine = new Engine({
|
|
144
|
+
plugins: [Minimap],
|
|
145
|
+
pluginConfig: {
|
|
146
|
+
minimap: {
|
|
147
|
+
nodeColor: (node) => {
|
|
148
|
+
// Return different colors based on node type
|
|
149
|
+
switch (node.type) {
|
|
150
|
+
case 'start':
|
|
151
|
+
return '#4CAF50'
|
|
152
|
+
case 'end':
|
|
153
|
+
return '#F44336'
|
|
154
|
+
case 'process':
|
|
155
|
+
return '#2196F3'
|
|
156
|
+
default:
|
|
157
|
+
return '#9E9E9E'
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
nodeStrokeColor: (node) => {
|
|
161
|
+
return node.selected ? '#FF9800' : 'transparent'
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Disable Control Buttons
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const engine = new Engine({
|
|
172
|
+
plugins: [Minimap],
|
|
173
|
+
pluginConfig: {
|
|
174
|
+
minimap: {
|
|
175
|
+
showControls: false,
|
|
176
|
+
zoomable: false,
|
|
177
|
+
pannable: true,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Custom Size and Position
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const engine = new Engine({
|
|
187
|
+
plugins: [Minimap],
|
|
188
|
+
pluginConfig: {
|
|
189
|
+
minimap: {
|
|
190
|
+
width: 300,
|
|
191
|
+
height: 200,
|
|
192
|
+
padding: 20,
|
|
193
|
+
zoomStep: 0.3,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Advanced Features
|
|
200
|
+
|
|
201
|
+
### Integration with Canvas Plugin
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
205
|
+
import { Minimap } from '@knotx/plugins-minimap'
|
|
206
|
+
|
|
207
|
+
const engine = new Engine({
|
|
208
|
+
plugins: [Canvas, Minimap],
|
|
209
|
+
pluginConfig: {
|
|
210
|
+
canvas: {
|
|
211
|
+
minScale: 0.1,
|
|
212
|
+
maxScale: 3,
|
|
213
|
+
},
|
|
214
|
+
minimap: {
|
|
215
|
+
width: 200,
|
|
216
|
+
height: 150,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Listening to Minimap Interactions
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
class MinimapInteractionPlugin extends BasePlugin {
|
|
226
|
+
@inject.canvas.transform()
|
|
227
|
+
transform!: CanvasTransformState
|
|
228
|
+
|
|
229
|
+
@subscribe.canvas.transform()
|
|
230
|
+
onTransformChange(transform: CanvasTransformState) {
|
|
231
|
+
console.log('Canvas transform changed:', transform)
|
|
232
|
+
// Minimap will automatically sync transform state
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Custom Minimap Behavior
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
class CustomMinimapPlugin extends BasePlugin {
|
|
241
|
+
@inject.minimap.config()
|
|
242
|
+
minimapConfig!: MinimapConfig
|
|
243
|
+
|
|
244
|
+
@OnInit
|
|
245
|
+
init() {
|
|
246
|
+
// Dynamically adjust minimap configuration
|
|
247
|
+
this.minimapConfig.nodeColor = (node) => {
|
|
248
|
+
const isImportant = node.data?.important
|
|
249
|
+
return isImportant ? '#FF5722' : '#607D8B'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Style Customization
|
|
256
|
+
|
|
257
|
+
### CSS Class Names
|
|
258
|
+
|
|
259
|
+
The minimap provides the following CSS class names for style customization:
|
|
260
|
+
|
|
261
|
+
```css
|
|
262
|
+
.knotx-minimap {
|
|
263
|
+
/* Minimap container */
|
|
264
|
+
border: 1px solid #ddd;
|
|
265
|
+
border-radius: 4px;
|
|
266
|
+
background: #fff;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.knotx-minimap__svg {
|
|
270
|
+
/* SVG container */
|
|
271
|
+
cursor: crosshair;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.knotx-minimap__controls {
|
|
275
|
+
/* Control buttons container */
|
|
276
|
+
display: flex;
|
|
277
|
+
gap: 4px;
|
|
278
|
+
margin-top: 8px;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.knotx-minimap__button {
|
|
282
|
+
/* Control buttons */
|
|
283
|
+
padding: 4px 8px;
|
|
284
|
+
border: 1px solid #ccc;
|
|
285
|
+
background: #f5f5f5;
|
|
286
|
+
cursor: pointer;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.knotx-minimap__button:hover {
|
|
290
|
+
background: #e0e0e0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.knotx-minimap__button:disabled {
|
|
294
|
+
opacity: 0.5;
|
|
295
|
+
cursor: not-allowed;
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Custom Style Example
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
const engine = new Engine({
|
|
303
|
+
plugins: [Minimap],
|
|
304
|
+
pluginConfig: {
|
|
305
|
+
minimap: {
|
|
306
|
+
width: 200,
|
|
307
|
+
height: 150,
|
|
308
|
+
// Custom viewport color
|
|
309
|
+
viewBoxColor: '#FF6B6B',
|
|
310
|
+
// Custom mask color
|
|
311
|
+
maskColor: 'rgba(255, 107, 107, 0.1)',
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
})
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Performance Optimization
|
|
318
|
+
|
|
319
|
+
### Node Rendering Optimization
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const engine = new Engine({
|
|
323
|
+
plugins: [Minimap],
|
|
324
|
+
pluginConfig: {
|
|
325
|
+
minimap: {
|
|
326
|
+
// Use fixed color to avoid function call overhead
|
|
327
|
+
nodeColor: '#4A90E2',
|
|
328
|
+
nodeStrokeColor: 'transparent',
|
|
329
|
+
// Reduce border radius for better rendering performance
|
|
330
|
+
nodeBorderRadius: 0,
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Interaction Optimization
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
const engine = new Engine({
|
|
340
|
+
plugins: [Minimap],
|
|
341
|
+
pluginConfig: {
|
|
342
|
+
minimap: {
|
|
343
|
+
// Smaller zoom step for smoother experience
|
|
344
|
+
zoomStep: 0.1,
|
|
345
|
+
// Appropriate size balancing performance and usability
|
|
346
|
+
width: 180,
|
|
347
|
+
height: 120,
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
})
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## File Directory Structure
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
packages/plugins-minimap/
|
|
357
|
+
├── src/
|
|
358
|
+
│ ├── minimap.tsx # Main implementation file
|
|
359
|
+
│ └── index.ts # Export file
|
|
360
|
+
├── dist/ # Build output directory
|
|
361
|
+
├── package.json # Package configuration
|
|
362
|
+
├── build.config.ts # Build configuration
|
|
363
|
+
├── tsconfig.json # TypeScript configuration
|
|
364
|
+
├── eslint.config.mjs # ESLint configuration
|
|
365
|
+
└── CHANGELOG.md # Changelog
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Core Files Description
|
|
369
|
+
|
|
370
|
+
- **minimap.tsx**: Contains the main implementation of the Minimap plugin, including node mapping, viewport synchronization, and interaction control
|
|
371
|
+
- **index.ts**: Exports the Minimap class and related type definitions
|
|
372
|
+
|
|
373
|
+
## Best Practices
|
|
374
|
+
|
|
375
|
+
### User Experience
|
|
376
|
+
|
|
377
|
+
1. **Appropriate Size**: Choose suitable minimap size based on application layout
|
|
378
|
+
2. **Clear Visual Feedback**: Use high-contrast colors to distinguish different elements
|
|
379
|
+
3. **Smooth Interactions**: Configure zoom steps and animation effects appropriately
|
|
380
|
+
|
|
381
|
+
### Performance Optimization
|
|
382
|
+
|
|
383
|
+
1. **Fixed Colors**: Use fixed colors instead of dynamic functions for large numbers of nodes
|
|
384
|
+
2. **Simplified Styles**: Reduce unnecessary visual effects to improve rendering performance
|
|
385
|
+
3. **Reasonable Size**: Adjust minimap size based on node count
|
|
386
|
+
|
|
387
|
+
### Development and Debugging
|
|
388
|
+
|
|
389
|
+
1. **Monitor State Changes**: Listen to transform state changes during development
|
|
390
|
+
2. **Test Interactions**: Ensure proper synchronization between minimap and main canvas
|
|
391
|
+
3. **Verify Boundaries**: Test extreme zoom and pan scenarios
|
|
392
|
+
|
|
393
|
+
## Notes
|
|
394
|
+
|
|
395
|
+
1. **Dependencies**: Ensure Canvas plugin is loaded before Minimap plugin
|
|
396
|
+
2. **Performance Considerations**: With many nodes, minimap rendering may impact performance
|
|
397
|
+
3. **Responsive Design**: Consider minimap display on different screen sizes
|
|
398
|
+
4. **Browser Compatibility**: Depends on SVG and modern JavaScript features
|
|
399
|
+
|
|
400
|
+
## License
|
|
401
|
+
|
|
402
|
+
MIT
|
package/README.md
CHANGED
|
@@ -1,11 +1,402 @@
|
|
|
1
|
-
|
|
1
|
+
# @knotx/plugins-minimap
|
|
2
|
+
|
|
3
|
+
小地图插件,为 KnotX 提供画布导航功能。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
2
6
|
|
|
3
7
|
```bash
|
|
4
|
-
|
|
8
|
+
npm install @knotx/plugins-minimap
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 概述
|
|
12
|
+
|
|
13
|
+
Minimap 插件为 KnotX 提供了小地图功能,允许用户在大型画布中快速导航。该插件基于 `interactjs` 库实现,提供了缩放、平移、视窗控制等功能。
|
|
14
|
+
|
|
15
|
+
## 实现原理
|
|
16
|
+
|
|
17
|
+
Minimap 插件的核心实现原理:
|
|
18
|
+
|
|
19
|
+
1. **节点映射**:将画布上的节点映射到小地图的比例尺中
|
|
20
|
+
2. **视窗同步**:实时同步主画布和小地图的视窗状态
|
|
21
|
+
3. **交互控制**:支持在小地图上拖拽和点击进行导航
|
|
22
|
+
4. **缩放控制**:提供缩放按钮和重置功能
|
|
23
|
+
|
|
24
|
+
## 依赖关系
|
|
25
|
+
|
|
26
|
+
### 核心依赖
|
|
27
|
+
- `@knotx/core`:提供基础插件架构
|
|
28
|
+
- `@knotx/decorators`:提供装饰器支持
|
|
29
|
+
- `interactjs`:提供交互功能
|
|
30
|
+
- `rxjs`:提供响应式编程支持
|
|
31
|
+
|
|
32
|
+
### 插件依赖
|
|
33
|
+
- `@knotx/plugins-canvas`:获取画布变换状态和容器信息
|
|
34
|
+
|
|
35
|
+
## API 文档
|
|
36
|
+
|
|
37
|
+
### 主要类
|
|
38
|
+
|
|
39
|
+
#### Minimap
|
|
40
|
+
|
|
41
|
+
小地图插件的主要类,继承自 `BasePlugin`。
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
export class Minimap extends BasePlugin<'minimap', MinimapConfig> {
|
|
45
|
+
name = 'minimap' as const
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 配置选项
|
|
50
|
+
|
|
51
|
+
#### MinimapConfig
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export interface MinimapConfig {
|
|
55
|
+
/** 小地图宽度 */
|
|
56
|
+
width?: number
|
|
57
|
+
/** 小地图高度 */
|
|
58
|
+
height?: number
|
|
59
|
+
/** 节点颜色 */
|
|
60
|
+
nodeColor?: string | ((node: Node) => string)
|
|
61
|
+
/** 视图区域背景颜色 */
|
|
62
|
+
maskColor?: string
|
|
63
|
+
/** 视图区域边框颜色 */
|
|
64
|
+
viewBoxColor?: string
|
|
65
|
+
/** 显示小地图控制按钮 */
|
|
66
|
+
showControls?: boolean
|
|
67
|
+
/** 是否可缩放 */
|
|
68
|
+
zoomable?: boolean
|
|
69
|
+
/** 是否可平移 */
|
|
70
|
+
pannable?: boolean
|
|
71
|
+
/** 与容器的内边距 */
|
|
72
|
+
padding?: number
|
|
73
|
+
/** 节点圆角 */
|
|
74
|
+
nodeBorderRadius?: number
|
|
75
|
+
/** 节点描边宽度 */
|
|
76
|
+
nodeStrokeWidth?: number
|
|
77
|
+
/** 节点描边颜色 */
|
|
78
|
+
nodeStrokeColor?: string | ((node: Node) => string)
|
|
79
|
+
/** 缩放步长 */
|
|
80
|
+
zoomStep?: number
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 默认配置
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const defaultProps: Required<Omit<MinimapConfig, 'nodeColor' | 'nodeStrokeColor'>> = {
|
|
88
|
+
width: 200,
|
|
89
|
+
height: 150,
|
|
90
|
+
maskColor: 'rgba(240, 240, 240, 0.6)',
|
|
91
|
+
viewBoxColor: '#4752E6',
|
|
92
|
+
showControls: true,
|
|
93
|
+
zoomable: true,
|
|
94
|
+
pannable: true,
|
|
95
|
+
padding: 12,
|
|
96
|
+
nodeBorderRadius: 2,
|
|
97
|
+
nodeStrokeWidth: 1,
|
|
98
|
+
zoomStep: 0.2,
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 使用示例
|
|
103
|
+
|
|
104
|
+
### 基本用法
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { Minimap } from '@knotx/plugins-minimap'
|
|
108
|
+
|
|
109
|
+
const engine = new Engine({
|
|
110
|
+
plugins: [Minimap],
|
|
111
|
+
pluginConfig: {
|
|
112
|
+
minimap: {
|
|
113
|
+
width: 200,
|
|
114
|
+
height: 150,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 自定义样式
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const engine = new Engine({
|
|
124
|
+
plugins: [Minimap],
|
|
125
|
+
pluginConfig: {
|
|
126
|
+
minimap: {
|
|
127
|
+
width: 250,
|
|
128
|
+
height: 180,
|
|
129
|
+
nodeColor: '#4A90E2',
|
|
130
|
+
maskColor: 'rgba(255, 255, 255, 0.8)',
|
|
131
|
+
viewBoxColor: '#FF6B6B',
|
|
132
|
+
nodeBorderRadius: 4,
|
|
133
|
+
nodeStrokeWidth: 2,
|
|
134
|
+
nodeStrokeColor: '#333',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 动态节点颜色
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const engine = new Engine({
|
|
144
|
+
plugins: [Minimap],
|
|
145
|
+
pluginConfig: {
|
|
146
|
+
minimap: {
|
|
147
|
+
nodeColor: (node) => {
|
|
148
|
+
// 根据节点类型返回不同颜色
|
|
149
|
+
switch (node.type) {
|
|
150
|
+
case 'start':
|
|
151
|
+
return '#4CAF50'
|
|
152
|
+
case 'end':
|
|
153
|
+
return '#F44336'
|
|
154
|
+
case 'process':
|
|
155
|
+
return '#2196F3'
|
|
156
|
+
default:
|
|
157
|
+
return '#9E9E9E'
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
nodeStrokeColor: (node) => {
|
|
161
|
+
return node.selected ? '#FF9800' : 'transparent'
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 禁用控制按钮
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const engine = new Engine({
|
|
172
|
+
plugins: [Minimap],
|
|
173
|
+
pluginConfig: {
|
|
174
|
+
minimap: {
|
|
175
|
+
showControls: false,
|
|
176
|
+
zoomable: false,
|
|
177
|
+
pannable: true,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
})
|
|
5
181
|
```
|
|
6
182
|
|
|
7
|
-
|
|
183
|
+
### 自定义尺寸和位置
|
|
8
184
|
|
|
9
|
-
```
|
|
185
|
+
```typescript
|
|
186
|
+
const engine = new Engine({
|
|
187
|
+
plugins: [Minimap],
|
|
188
|
+
pluginConfig: {
|
|
189
|
+
minimap: {
|
|
190
|
+
width: 300,
|
|
191
|
+
height: 200,
|
|
192
|
+
padding: 20,
|
|
193
|
+
zoomStep: 0.3,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 高级功能
|
|
200
|
+
|
|
201
|
+
### 与 Canvas 插件集成
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { Canvas } from '@knotx/plugins-canvas'
|
|
10
205
|
import { Minimap } from '@knotx/plugins-minimap'
|
|
206
|
+
|
|
207
|
+
const engine = new Engine({
|
|
208
|
+
plugins: [Canvas, Minimap],
|
|
209
|
+
pluginConfig: {
|
|
210
|
+
canvas: {
|
|
211
|
+
minScale: 0.1,
|
|
212
|
+
maxScale: 3,
|
|
213
|
+
},
|
|
214
|
+
minimap: {
|
|
215
|
+
width: 200,
|
|
216
|
+
height: 150,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 监听小地图交互
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
class MinimapInteractionPlugin extends BasePlugin {
|
|
226
|
+
@inject.canvas.transform()
|
|
227
|
+
transform!: CanvasTransformState
|
|
228
|
+
|
|
229
|
+
@subscribe.canvas.transform()
|
|
230
|
+
onTransformChange(transform: CanvasTransformState) {
|
|
231
|
+
console.log('Canvas transform changed:', transform)
|
|
232
|
+
// 小地图会自动同步变换状态
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 自定义小地图行为
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
class CustomMinimapPlugin extends BasePlugin {
|
|
241
|
+
@inject.minimap.config()
|
|
242
|
+
minimapConfig!: MinimapConfig
|
|
243
|
+
|
|
244
|
+
@OnInit
|
|
245
|
+
init() {
|
|
246
|
+
// 动态调整小地图配置
|
|
247
|
+
this.minimapConfig.nodeColor = (node) => {
|
|
248
|
+
const isImportant = node.data?.important
|
|
249
|
+
return isImportant ? '#FF5722' : '#607D8B'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## 样式自定义
|
|
256
|
+
|
|
257
|
+
### CSS 类名
|
|
258
|
+
|
|
259
|
+
小地图提供了以下 CSS 类名用于样式自定义:
|
|
260
|
+
|
|
261
|
+
```css
|
|
262
|
+
.knotx-minimap {
|
|
263
|
+
/* 小地图容器 */
|
|
264
|
+
border: 1px solid #ddd;
|
|
265
|
+
border-radius: 4px;
|
|
266
|
+
background: #fff;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.knotx-minimap__svg {
|
|
270
|
+
/* SVG 容器 */
|
|
271
|
+
cursor: crosshair;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.knotx-minimap__controls {
|
|
275
|
+
/* 控制按钮容器 */
|
|
276
|
+
display: flex;
|
|
277
|
+
gap: 4px;
|
|
278
|
+
margin-top: 8px;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.knotx-minimap__button {
|
|
282
|
+
/* 控制按钮 */
|
|
283
|
+
padding: 4px 8px;
|
|
284
|
+
border: 1px solid #ccc;
|
|
285
|
+
background: #f5f5f5;
|
|
286
|
+
cursor: pointer;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.knotx-minimap__button:hover {
|
|
290
|
+
background: #e0e0e0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.knotx-minimap__button:disabled {
|
|
294
|
+
opacity: 0.5;
|
|
295
|
+
cursor: not-allowed;
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 自定义样式示例
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
const engine = new Engine({
|
|
303
|
+
plugins: [Minimap],
|
|
304
|
+
pluginConfig: {
|
|
305
|
+
minimap: {
|
|
306
|
+
width: 200,
|
|
307
|
+
height: 150,
|
|
308
|
+
// 自定义视窗颜色
|
|
309
|
+
viewBoxColor: '#FF6B6B',
|
|
310
|
+
// 自定义蒙版颜色
|
|
311
|
+
maskColor: 'rgba(255, 107, 107, 0.1)',
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
})
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## 性能优化
|
|
318
|
+
|
|
319
|
+
### 节点渲染优化
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const engine = new Engine({
|
|
323
|
+
plugins: [Minimap],
|
|
324
|
+
pluginConfig: {
|
|
325
|
+
minimap: {
|
|
326
|
+
// 使用固定颜色避免函数调用开销
|
|
327
|
+
nodeColor: '#4A90E2',
|
|
328
|
+
nodeStrokeColor: 'transparent',
|
|
329
|
+
// 减少圆角以提高渲染性能
|
|
330
|
+
nodeBorderRadius: 0,
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 交互优化
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
const engine = new Engine({
|
|
340
|
+
plugins: [Minimap],
|
|
341
|
+
pluginConfig: {
|
|
342
|
+
minimap: {
|
|
343
|
+
// 较小的缩放步长提供更平滑的体验
|
|
344
|
+
zoomStep: 0.1,
|
|
345
|
+
// 合适的尺寸平衡性能和可用性
|
|
346
|
+
width: 180,
|
|
347
|
+
height: 120,
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
})
|
|
11
351
|
```
|
|
352
|
+
|
|
353
|
+
## 文件目录结构
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
packages/plugins-minimap/
|
|
357
|
+
├── src/
|
|
358
|
+
│ ├── minimap.tsx # 主要实现文件
|
|
359
|
+
│ └── index.ts # 导出文件
|
|
360
|
+
├── dist/ # 构建输出目录
|
|
361
|
+
├── package.json # 包配置文件
|
|
362
|
+
├── build.config.ts # 构建配置
|
|
363
|
+
├── tsconfig.json # TypeScript 配置
|
|
364
|
+
├── eslint.config.mjs # ESLint 配置
|
|
365
|
+
└── CHANGELOG.md # 更新日志
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### 核心文件说明
|
|
369
|
+
|
|
370
|
+
- **minimap.tsx**:包含 Minimap 插件的主要实现,包括节点映射、视窗同步和交互控制
|
|
371
|
+
- **index.ts**:导出 Minimap 类和相关类型定义
|
|
372
|
+
|
|
373
|
+
## 最佳实践
|
|
374
|
+
|
|
375
|
+
### 用户体验
|
|
376
|
+
|
|
377
|
+
1. **合适的尺寸**:根据应用布局选择合适的小地图尺寸
|
|
378
|
+
2. **清晰的视觉反馈**:使用对比度高的颜色区分不同元素
|
|
379
|
+
3. **平滑的交互**:合理配置缩放步长和动画效果
|
|
380
|
+
|
|
381
|
+
### 性能优化
|
|
382
|
+
|
|
383
|
+
1. **固定颜色**:对于大量节点,使用固定颜色而非动态函数
|
|
384
|
+
2. **简化样式**:减少不必要的视觉效果以提高渲染性能
|
|
385
|
+
3. **合理尺寸**:根据节点数量调整小地图尺寸
|
|
386
|
+
|
|
387
|
+
### 开发调试
|
|
388
|
+
|
|
389
|
+
1. **监听状态变化**:在开发阶段监听变换状态变化
|
|
390
|
+
2. **测试交互**:确保小地图与主画布的同步正常
|
|
391
|
+
3. **验证边界**:测试极端缩放和平移情况
|
|
392
|
+
|
|
393
|
+
## 注意事项
|
|
394
|
+
|
|
395
|
+
1. **依赖关系**:确保 Canvas 插件在 Minimap 插件之前加载
|
|
396
|
+
2. **性能考虑**:大量节点时,小地图的渲染可能影响性能
|
|
397
|
+
3. **响应式设计**:考虑在不同屏幕尺寸下的小地图显示
|
|
398
|
+
4. **浏览器兼容性**:依赖 SVG 和现代 JavaScript 特性
|
|
399
|
+
|
|
400
|
+
## 许可证
|
|
401
|
+
|
|
402
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knotx/plugins-minimap",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "Minimap Plugin for Knotx",
|
|
5
5
|
"author": "boenfu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,26 +28,21 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"
|
|
32
|
-
"@knotx/
|
|
33
|
-
"@knotx/plugins-canvas": "0.4.12"
|
|
31
|
+
"@knotx/jsx": "0.4.14",
|
|
32
|
+
"@knotx/plugins-canvas": "0.4.14"
|
|
34
33
|
},
|
|
35
34
|
"dependencies": {
|
|
36
|
-
"
|
|
37
|
-
"@interactjs/core": "^1.10.27",
|
|
38
|
-
"@interactjs/modifiers": "^1.10.27",
|
|
39
|
-
"@interactjs/types": "^1.10.27",
|
|
35
|
+
"interactjs": "^1.10.27",
|
|
40
36
|
"rxjs": "^7.8.1",
|
|
41
|
-
"@knotx/core": "0.4.
|
|
42
|
-
"@knotx/decorators": "0.4.
|
|
37
|
+
"@knotx/core": "0.4.14",
|
|
38
|
+
"@knotx/decorators": "0.4.14"
|
|
43
39
|
},
|
|
44
40
|
"devDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"@knotx/
|
|
47
|
-
"@knotx/
|
|
48
|
-
"@knotx/
|
|
49
|
-
"@knotx/
|
|
50
|
-
"@knotx/typescript-config": "0.4.12"
|
|
41
|
+
"@knotx/build-config": "0.4.14",
|
|
42
|
+
"@knotx/eslint-config": "0.4.14",
|
|
43
|
+
"@knotx/jsx": "0.4.14",
|
|
44
|
+
"@knotx/plugins-canvas": "0.4.14",
|
|
45
|
+
"@knotx/typescript-config": "0.4.14"
|
|
51
46
|
},
|
|
52
47
|
"scripts": {
|
|
53
48
|
"build": "unbuild",
|