@ganwei-web/plugin-runtime
v0.0.14
Published
可视化平台自定义插件独立运行依赖包
Readme
@ganwei-web/plugin-runtime - 可视化平台插件独立运行依赖包
概述
@ganwei-web/plugin-runtime 是一个轻量级的运行时依赖包,用于支持可视化平台自定义插件�?独立开发和调试*。它提供了:
- �?
shared-lib兼容�?BaseComponent和服务接�?- 模拟�?Node/Topology 数据模型 - 独立的开发调试服务器组件
- 插件项目脚手架生成器
核心优势
- 无需完整项目:外部开发者只需获得此依赖包,无需访问核心框架代码
- 独立运行:插件可以脱离主项目独立开发、调试和预览
- 接口兼容:与主项目的
shared-lib接口保持一致,接入时无需修改业务代码 - 模拟数据:内置数据源�?SignalR 模拟,支持完整的交互调试
安装
npm install @ganwei-web/plugin-runtime使用方式
方式一:使�?Schematics 生成独立插件项目(推荐)
- 安装 Angular CLI �?Schematics�?```bash npm install -g @angular/[email protected]
2. 生成独立插件项目�?```bash
ng g @ganwei-web/plugin-runtime:standalone-plugin plugin-my-component- 进入项目并安装依赖:
cd plugin-my-component
npm install- 启动开发服务器�?```bash npm run dev
### 方式二:手动集成到现有插�?
1. 在现有插件项目中安装依赖�?```bash
npm install @ganwei-web/plugin-runtime- 修改导入路径�?```typescript // 原导入(主项目运行时�?import { BaseComponent, StyleService } from 'shared-lib'; import { Node } from '@topology/core';
// 新导入(独立运行时) import { BaseComponent, StyleService } from '@ganwei-web/plugin-runtime'; import { Node } from '@ganwei-web/plugin-runtime';
3. �?`app.component.ts` 中使用开发服务器�?```typescript
import { Component } from '@angular/core';
import { PluginDevServerComponent } from '@ganwei-web/plugin-runtime';
import { MyPluginComponent } from './component/my-plugin.component';
@Component({
selector: 'app-root',
template: `
<plugin-dev-server
[pluginComponent]="pluginComponent"
[initialPen]="initialPen"
[mockData]="mockData">
</plugin-dev-server>
`
})
export class AppComponent {
pluginComponent = MyPluginComponent;
initialPen = {
rect: { width: 400, height: 300 },
datasourceId: 'test-datasource'
};
mockData = {
value: 42,
status: 'normal'
};
}API 参�?
BaseComponent
�?shared-lib 中的 BaseComponent 接口完全一致:
export abstract class BaseComponent {
@Input() pen: Node;
@Input() canvas: Topology;
@Input() isWorkspace: boolean;
@Input() visible: boolean;
style: any;
abstract getStyle(): void;
abstract handleSignalrData(data: ISignalrData): void;
abstract handleDatasource(data: any): void;
}服务
StyleService
getBBox(node, canvas)- 获取元素边界框样�?-getFont(node)- 获取字体样式getBackground(node)- 获取背景样式getBorder(node)- 获取边框样式getShadow(node)- 获取阴影样式
DatasourceService
sendInitialValue- BehaviorSubject,数据源初始�?-dataSourceDataMap- Map,数据源数据缓存setMockData(guid, data)- 设置模拟数据
RefreshService
refreshNode- BehaviorSubject,刷新节点事�?-refresh(nodeId)- 触发节点刷新
SignalrDataService
signalrData- BehaviorSubject,SignalR数据emit(data)- 发送模拟数�?
开发调试组�?
PluginDevServerComponent
独立开发服务器的核心组件,提供�?- 插件渲染区域
- 刷新按钮
- 模拟数据注入
- SignalR数据模拟
- 当前 Pen 属性查�? 输入属性:
pluginComponent- 要调试的插件组件�?-initialPen- 初始 Pen 属性(可选)mockData- 初始模拟数据(可选)
项目结构
plugin-runtime/
├── src/
�? ├── models/
�? �? ├── node.model.ts # Node/Pen 数据模型
�? �? └── topology.model.ts # Topology 接口
�? ├── services/
�? �? ├── style.service.ts # 样式服务
�? �? ├── datasource.service.ts # 数据源服�?�? �? ├── refresh.service.ts # 刷新服务
�? �? └── signalr-data.service.ts # SignalR服务
�? ├── mock/
�? �? ├── pen.mock.ts # Pen 模拟数据生成�?�? �? └── canvas.mock.ts # Canvas 模拟�?�? ├── dev-server/
�? �? └── plugin-dev-server.component.ts # 开发调试服务器
�? ├── base.component.ts # 基础组件
�? └── public-api.ts # 公共导出
├── schematics/
�? └── standalone-plugin/ # 独立插件脚手�?└── package.json接入主项目流�?
- **独立开发阶�?*:使�?
@ganwei-web/plugin-runtime开发调�?2. 代码迁移:将src/app/component/下的组件代码复制到主项目�?plugins/<plugin-name>/src/app/component/ - 导入替换:将
@ganwei-web/plugin-runtime替换�?shared-lib - 构建打包:使用主项目�?
ng build <plugin-name>命令打包
导入映射对照�?
| 独立运行�?| 主项目运行时 |
|-----------|------------|
| @ganwei-web/plugin-runtime | shared-lib |
| @ganwei-web/plugin-runtime (Node) | @topology/core |
注意事项
- **不要修改运行时源�?:
@ganwei-web/plugin-runtime是公共依赖,修改会影响所有插�?2. **保持接口一�?:独立运行时开发的插件,接入主项目时只需修改导入路径 - 模拟数据:独立运行时的数据源�?SignalR 都是模拟的,接入后会使用真实数据
- 样式兼容:
StyleService提供的样式与主项目完全一�?
开发示�?
完整插件组件示例
import { Component, Input, ChangeDetectorRef, NgZone } from '@angular/core';
import { Node, BaseComponent, StyleService, RefreshService, SignalrDataService, DatasourceService } from '@ganwei-web/plugin-runtime';
interface IMyPluginExtendKeys {
title?: string;
showValue?: boolean;
}
@Component({
selector: 'app-plugin-my',
template: `
<div [ngStyle]="style" class="my-plugin">
<h3>{{ pen.title || '默认标题' }}</h3>
<div *ngIf="pen.showValue" class="value">{{ dataValue }}</div>
</div>
`,
styles: [`
.my-plugin {
padding: 10px;
h3 { margin: 0 0 10px; }
.value { font-size: 24px; color: #1890ff; }
}
`]
})
export class PluginMyComponent extends BaseComponent {
@Input() pen: Node & IMyPluginExtendKeys;
dataValue: any = '--';
constructor(
cdr: ChangeDetectorRef,
refreshService: RefreshService,
signalrDataService: SignalrDataService,
styleService: StyleService,
datasourceService: DatasourceService,
ngZone: NgZone
) {
super(cdr, styleService, refreshService, signalrDataService, datasourceService, ngZone);
}
getStyle() {
this.style = {
...this.styleService.getBBox(this.pen, this.canvas),
...this.styleService.getFont(this.pen),
...this.styleService.getBackground(this.pen),
...this.styleService.getBorder(this.pen)
};
}
handleSignalrData(data: any) {
console.log('实时数据:', data);
}
handleDatasource(data: any) {
this.dataValue = data?.value ?? '--';
this.cdr.detectChanges();
}
}许可�?
MIT
