未验证 提交 7e048363 编写于 作者: 麦壳饼's avatar 麦壳饼 提交者: GitHub

Merge pull request #416 from wq1234wq/master

ntv/x6 导入X6图形库
......@@ -49,7 +49,7 @@
"@angular/platform-browser": "~11.2.14",
"@angular/platform-browser-dynamic": "~11.2.14",
"@angular/router": "~11.2.14",
"@antv/x6": "^1.23.12",
"@antv/x6": "^1.24.4",
"@delon/abc": "^11.10.2",
"@delon/acl": "^11.10.2",
"@delon/auth": "^11.10.2",
......
......@@ -26,7 +26,8 @@ export class StartupService {
private settingService: SettingsService,
private aclService: ACLService,
private titleService: TitleService,
private httpClient: HttpClient, @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
private httpClient: HttpClient,
@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
) {
iconSrv.addIcon(...ICONS_AUTO, ...ICONS);
}
......@@ -38,107 +39,106 @@ export class StartupService {
var token = this.tokenService;
if (token && token.get() && token.get()?.token) {
return concat(this.httpClient.get(`assets/tmp/i18n/${this.i18n.defaultLang}.json`).pipe(map(langData => {
this.translate.setTranslation(this.i18n.defaultLang, langData);
this.translate.setDefaultLang(this.i18n.defaultLang);
})), this.httpClient.get(
'api/Account/MyInfo'
).pipe(map(appData => {
const res = appData as NzSafeAny;
console.log(res)
this.settingService.setApp({ name: 'IotSharp', description: 'IotSharp' });
this.settingService.setUser(res.data.customer);
this.aclService.setFull(true);
var menu = [
{
"text": "主导航1",
"i18n": "menu.main",
"group": true,
"hideInBreadcrumb": true,
"children": [
return concat(
this.httpClient.get(`assets/tmp/i18n/${this.i18n.defaultLang}.json`).pipe(
map((langData) => {
this.translate.setTranslation(this.i18n.defaultLang, langData);
this.translate.setDefaultLang(this.i18n.defaultLang);
}),
),
this.httpClient.get('api/Account/MyInfo').pipe(
map((appData) => {
const res = appData as NzSafeAny;
console.log(res);
this.settingService.setApp({ name: 'IotSharp', description: 'IotSharp' });
this.settingService.setUser(res.data.customer);
this.aclService.setFull(true);
var menu = [
{
"text": "仪表盘",
"i18n": "menu.dashboard",
"icon": "anticon-dashboard",
"children": [
text: '主导航1',
i18n: 'menu.main',
group: true,
hideInBreadcrumb: true,
children: [
{
"text": "仪表盘V1",
"link": "/dashboard/v1",
"i18n": "menu.dashboard.v1"
}
]
},
{
"text": "租户管理",
"icon": "anticon-rocket",
"shortcutRoot": true,
"i18n": "menu.tenant.tenantmanage",
"children": [
text: '仪表盘',
i18n: 'menu.dashboard',
icon: 'anticon-dashboard',
children: [
{
text: '仪表盘V1',
link: '/dashboard/v1',
i18n: 'menu.dashboard.v1',
},
],
},
{
"text": "租户列表",
"link": "/iot/tenant/tenantlist",
"i18n": "menu.tenant.tenantlist"
}
]
},
{
"text": "客户管理",
"icon": "anticon-appstore",
"i18n": "menu.customer.customermanage",
"children": [
text: '租户管理',
icon: 'anticon-rocket',
shortcutRoot: true,
i18n: 'menu.tenant.tenantmanage',
children: [
{
text: '租户列表',
link: '/iot/tenant/tenantlist',
i18n: 'menu.tenant.tenantlist',
},
],
},
{
"text": "客户列表",
"link": "/iot/customer/customerlist",
"i18n": "menu.customer.customerlist"
}
]
},
{
"text": "设备管理",
"icon": "anticon-appstore",
"i18n": "menu.device.devicemanage",
"children": [
text: '客户管理',
icon: 'anticon-appstore',
i18n: 'menu.customer.customermanage',
children: [
{
text: '客户列表',
link: '/iot/customer/customerlist',
i18n: 'menu.customer.customerlist',
},
],
},
{
"text": "设备列表",
"link": "/iot/device/devicelist",
"i18n": "menu.device.devicelist"
}
]
}
]
}]
if (!res.data.menu) {
res.data.menu = menu;
}
this.menuService.add(res.data.menu);
this.titleService.default = '';
this.titleService.suffix = res.data.tenant.name;
}))).toPromise()
text: '设备管理',
icon: 'anticon-appstore',
i18n: 'menu.device.devicemanage',
children: [
{
text: '设备列表',
link: '/iot/device/devicelist',
i18n: 'menu.device.devicelist',
},
{
text: '设计',
link: '/iot/device/devicegraph',
// i18n: 'menu.device.devicelist',
},
],
},
],
},
];
if (!res.data.menu) {
res.data.menu = menu;
}
this.menuService.add(res.data.menu);
this.titleService.default = '';
this.titleService.suffix = res.data.tenant.name;
}),
),
).toPromise();
} else {
return concat(this.httpClient.get(`assets/tmp/i18n/${this.i18n.defaultLang}.json`).pipe(map(langData => {
this.translate.setTranslation(this.i18n.defaultLang, langData);
this.translate.setDefaultLang(this.i18n.defaultLang);
}))).toPromise()
return concat(
this.httpClient.get(`assets/tmp/i18n/${this.i18n.defaultLang}.json`).pipe(
map((langData) => {
this.translate.setTranslation(this.i18n.defaultLang, langData);
this.translate.setDefaultLang(this.i18n.defaultLang);
}),
),
).toPromise();
}
// return new Promise((resolve) => {
// zip(this.httpClient.get(`assets/tmp/i18n/${this.i18n.defaultLang}.json`), this.httpClient.get('assets/tmp/app-data.json'))
// .pipe(
......
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DevicegraphComponent } from './devicegraph.component';
describe('DevicegraphComponent', () => {
let component: DevicegraphComponent;
let fixture: ComponentFixture<DevicegraphComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ DevicegraphComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DevicegraphComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
import { Graph, Edge, Shape, NodeView } from '@antv/x6';
@Component({
selector: 'app-devicegraph',
templateUrl: './devicegraph.component.html',
styleUrls: ['./devicegraph.component.less'],
})
export class DevicegraphComponent implements OnInit {
@Input()
id: Number = -1;
@ViewChild('container', { static: true })
private container!: ElementRef;
graph!: Graph;
magnetAvailabilityHighlighter = {
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#47C769',
},
},
};
constructor() {}
ngOnInit(): void {
this.graph = new Graph({
grid: true,
container: this.container.nativeElement,
width: 800,
height: 600,
highlighting: {
magnetAvailable: this.magnetAvailabilityHighlighter,
magnetAdsorbed: {
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#31d0c6',
},
},
},
},
connecting: {
snap: true,
allowBlank: false,
allowLoop: false,
highlight: true,
connector: 'rounded',
connectionPoint: 'boundary',
router: {
name: 'er',
args: {
direction: 'V',
},
},
createEdge() {
return new Shape.Edge({
attrs: {
line: {
stroke: '#a0a0a0',
strokeWidth: 1,
targetMarker: {
name: 'classic',
size: 7,
},
},
},
});
},
validateConnection({ sourceView, targetView, targetMagnet }) {
if (!targetMagnet) {
return false;
}
if (targetMagnet.getAttribute('port-group') !== 'in') {
return false;
}
if (targetView) {
const node = targetView.cell;
if (node instanceof Device) {
const portId = targetMagnet.getAttribute('port');
const usedInPorts = node.getUsedInPorts(this);
if (usedInPorts.find((port) => port && port.id === portId)) {
return false;
}
}
}
return true;
},
},
});
this.graph.addNode(new Device().resize(120, 40).position(200, 50).updateInPorts(this.graph));
this.graph.addNode(new Device().resize(120, 40).position(400, 50).updateInPorts(this.graph));
this.graph.addNode(new GateWay().resize(120, 40).position(300, 250).updateInPorts(this.graph));
this.graph.addNode(new Device().resize(120, 40).position(300, 50).updateInPorts(this.graph));
this.graph.addNode(new Device().resize(120, 40).position(400, 50).updateInPorts(this.graph));
// this.graph.fromJSON(this.data);
this.graph.on('edge:connected', ({ previousView, currentView }) => {
if (previousView) {
this.update(previousView as NodeView);
}
if (currentView) {
this.update(currentView as NodeView);
}
console.log(previousView);
});
this.graph.on('edge:removed', ({ edge, options }) => {
if (!options.ui) {
return;
}
const target = edge.getTargetCell();
if (target instanceof Device) {
target.updateInPorts(this.graph);
}
console.log(target);
});
this.graph.on('edge:mouseenter', ({ edge }) => {
edge.addTools([
'source-arrowhead',
'target-arrowhead',
{
name: 'button-remove',
args: {
distance: -30,
},
},
]);
console.log(edge);
});
this.graph.on('edge:mouseleave', ({ edge }) => {
edge.removeTools();
});
}
update(view: NodeView) {
const cell = view.cell;
if (cell instanceof Device) {
cell.getInPorts().forEach((port) => {
const portNode = view.findPortElem(port.id!, 'portBody');
view.unhighlight(portNode, {
highlighter: this.magnetAvailabilityHighlighter,
});
});
cell.updateInPorts(this.graph);
}
}
}
class Device extends Shape.Rect {
getInPorts() {
return this.getPortsByGroup('in');
}
getOutPorts() {
return this.getPortsByGroup('out');
}
getUsedInPorts(graph: Graph) {
const incomingEdges = graph.getIncomingEdges(this) || [];
return incomingEdges.map((edge: Edge) => {
const portId = edge.getTargetPortId();
return this.getPort(portId!);
});
}
getNewInPorts(length: number) {
return Array.from(
{
length,
},
() => {
return {
group: 'in',
};
},
);
}
updateInPorts(graph: Graph) {
const minNumberOfPorts = 1;
const ports = this.getInPorts();
const usedPorts = this.getUsedInPorts(graph);
const newPorts = this.getNewInPorts(Math.max(minNumberOfPorts - usedPorts.length, 1));
if (ports.length === minNumberOfPorts && ports.length - usedPorts.length > 0) {
// noop
} else if (ports.length === usedPorts.length) {
this.addPorts(newPorts);
} else if (ports.length + 1 > usedPorts.length) {
this.prop(['ports', 'items'], this.getOutPorts().concat(usedPorts).concat(newPorts), {
rewrite: true,
});
}
return this;
}
}
Device.config({
attrs: {
root: {
magnet: false,
},
body: {
fill: '#f5f5f5',
stroke: '#d9d9d9',
strokeWidth: 1,
},
},
ports: {
items: [
{
group: 'out',
},
],
groups: {
in: {
position: {
name: 'top',
},
attrs: {
portBody: {
magnet: 'passive',
r: 6,
stroke: '#ffa940',
fill: '#fff',
strokeWidth: 2,
},
},
},
out: {
position: {
name: 'bottom',
},
attrs: {
portBody: {
magnet: true,
r: 6,
fill: '#fff',
stroke: '#3199FF',
strokeWidth: 2,
},
},
},
},
},
portMarkup: [
{
tagName: 'circle',
selector: 'portBody',
},
],
});
class GateWay extends Shape.Circle {
getInPorts() {
return this.getPortsByGroup('in');
}
getOutPorts() {
return this.getPortsByGroup('out');
}
getUsedInPorts(graph: Graph) {
const incomingEdges = graph.getIncomingEdges(this) || [];
return incomingEdges.map((edge: Edge) => {
const portId = edge.getTargetPortId();
return this.getPort(portId!);
});
}
getNewInPorts(length: number) {
return Array.from(
{
length,
},
() => {
return {
group: 'in',
};
},
);
}
updateInPorts(graph: Graph) {
const minNumberOfPorts = 8;
const ports = this.getInPorts();
const usedPorts = this.getUsedInPorts(graph);
const newPorts = this.getNewInPorts(Math.max(minNumberOfPorts - usedPorts.length, 1));
if (ports.length === minNumberOfPorts && ports.length - usedPorts.length > 0) {
// noop
} else if (ports.length === usedPorts.length) {
this.addPorts(newPorts);
} else if (ports.length + 1 > usedPorts.length) {
this.prop(['ports', 'items'], this.getOutPorts().concat(usedPorts).concat(newPorts), {
rewrite: true,
});
}
return this;
}
}
GateWay.config({
attrs: {
root: {
magnet: false,
},
body: {
fill: '#ffa940',
stroke: '#d9d9d9',
strokeWidth: 1,
},
},
ports: {
items: [
{
group: 'out',
},
],
groups: {
in: {
position: {
name: 'top',
},
attrs: {
portBody: {
magnet: 'passive',
r: 6,
stroke: '#ffa940',
fill: '#fff',
strokeWidth: 2,
},
},
},
out: {
position: {
name: 'bottom',
},
attrs: {
portBody: {
magnet: true,
r: 6,
fill: '#fff',
stroke: '#3199FF',
strokeWidth: 2,
},
},
},
},
},
portMarkup: [
{
tagName: 'circle',
selector: 'portBody',
},
],
});
......@@ -5,6 +5,7 @@ import { environment } from '@env/environment';
// layout
import { LayoutBasicComponent } from '../layout/basic/basic.component';
import { LayoutBlankComponent } from '../layout/blank/blank.component';
import { DevicegraphComponent } from './device/devicegraph/devicegraph.component';
import { DevicelistComponent } from './device/devicelist/devicelist.component';
import { TenantlistComponent } from './tenant/tenantlist/tenantlist.component';
......@@ -37,6 +38,7 @@ const routes: Routes = [
{ path: 'user/userlist', component: UserlistComponent },
{ path: 'customer', loadChildren: () => import('./customer/customer.module').then((m) => m.CustomerModule) },
{ path: 'device/devicelist', component: DevicelistComponent },
{ path: 'device/devicegraph', component: DevicegraphComponent },
],
},
......
......@@ -13,6 +13,7 @@ import { ProppartComponent } from './device/deviceprop/proppart/proppart.compone
import { DesignerComponent } from './device/designer/designer.component';
import { UserlistComponent } from './user/userlist/userlist.component';
import { UserformComponent } from './user/userform/userform.component';
import { DevicegraphComponent } from './device/devicegraph/devicegraph.component';
const COMPONENTS: Type<null>[] = [];
......@@ -29,6 +30,7 @@ const COMPONENTS: Type<null>[] = [];
DesignerComponent,
UserlistComponent,
UserformComponent,
DevicegraphComponent,
],
})
export class RoutesModule {}
......@@ -3,7 +3,8 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": ["node"]
"types": ["node"],
"skipLibCheck": true,
},
"files": ["src/main.ts", "src/polyfills.ts"],
"include": ["src/**/*.d.ts"]
......
......@@ -34,6 +34,9 @@
"postinstall": "npm run install:husky"
},
"dependencies": {
"@antv/x6": "^1.24.4",
"@antv/x6-react-components": "^1.1.13",
"@antv/x6-vue3-shape": "^1.0.0",
"@iconify/iconify": "^2.0.2",
"@logicflow/core": "^0.5.0",
"@logicflow/extension": "^0.5.0",
......@@ -45,6 +48,8 @@
"cropperjs": "^1.5.12",
"crypto-js": "^4.0.0",
"echarts": "^5.1.2",
"guid-typescript": "^1.0.9",
"imagemin-gifsicle": "^7.0.0",
"intro.js": "^4.1.0",
"lodash-es": "^4.17.21",
"mockjs": "^1.1.0",
......
......@@ -42,6 +42,16 @@ const iotsharp: AppRouteModule = {
icon: 'simple-icons:about-dot-me',
},
},
{
path: 'devicegraph',
name: 'devicegraph',
component: () => import('../../../views/iotsharp/device/devicegraph.vue'),
meta: {
// title: t('routes.iotsharp.device'),
title: t('设计'),
icon: 'simple-icons:about-dot-me',
},
},
{
path: 'user',
name: 'User',
......
<template>
<div class="x6-graph-wrap">
<div ref="container" class="x6-graph"></div>
</div>
</template>
<script lang="ts">
//安装完X6但是报缺少MenuItem的错,是没有安装 @antv/x6-react-components,手动执行 yarn add @antv/x6-react-components,在angular这个又不是必要的,很有趣
import { Graph, Edge, Shape, NodeView } from '@antv/x6';
import { defineComponent, ref } from 'vue'; // reactive
const magnetAvailabilityHighlighter = {
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#47C769',
},
},
};
export default defineComponent({
name: 'Index',
setup() {
const canUndo = ref(true);
const canRedo = ref(false);
const graph = ref(Graph);
const init: (any) => void = (that) => {
that.graph = new Graph({
grid: true,
container: that.$refs.container as HTMLDivElement,
width: 800,
height: 600,
highlighting: {
magnetAvailable: magnetAvailabilityHighlighter,
magnetAdsorbed: {
name: 'stroke',
args: {
attrs: {
fill: '#fff',
stroke: '#31d0c6',
},
},
},
},
connecting: {
snap: true,
allowBlank: false,
allowLoop: false,
highlight: true,
connector: 'rounded',
connectionPoint: 'boundary',
router: {
name: 'er',
args: {
direction: 'V',
},
},
createEdge() {
return new Shape.Edge({
attrs: {
line: {
stroke: '#a0a0a0',
strokeWidth: 1,
targetMarker: {
name: 'classic',
size: 7,
},
},
},
});
},
validateConnection({ sourceView, targetView, targetMagnet }) {
if (!targetMagnet) {
return false;
}
if (targetMagnet.getAttribute('port-group') !== 'in') {
return false;
}
if (targetView) {
const node = targetView.cell;
if (node instanceof Device) {
const portId = targetMagnet.getAttribute('port');
const usedInPorts = node.getUsedInPorts(this);
if (usedInPorts.find((port) => port && port.id === portId)) {
return false;
}
}
}
return true;
},
},
});
that.graph.addNode(
new Device({
attrs: {
root: {
magnet: false,
},
body: {
fill: '#f5f5f5',
stroke: '#d9d9d9',
strokeWidth: 1,
},
},
ports: {
items: [
{
group: 'out',
},
],
groups: {
in: {
position: {
name: 'top',
},
attrs: {
portBody: {
magnet: 'passive',
r: 6,
stroke: '#ffa940',
fill: '#fff',
strokeWidth: 2,
},
},
},
out: {
position: {
name: 'bottom',
},
attrs: {
portBody: {
magnet: true,
r: 6,
fill: '#fff',
stroke: '#3199FF',
strokeWidth: 2,
},
},
},
},
},
portMarkup: [
{
tagName: 'circle',
selector: 'portBody',
},
],
})
.resize(120, 40)
.position(200, 50)
.updateInPorts(that.graph)
);
that.graph.addNode(new Device().resize(120, 40).position(0, 0).updateInPorts(that.graph));
that.graph.addNode(
new GateWay().resize(120, 40).position(300, 250).updateInPorts(that.graph)
);
that.graph.addNode(
new Device().resize(120, 40).position(300, 50).updateInPorts(that.graph)
);
that.graph.addNode(
new Device().resize(120, 40).position(400, 50).updateInPorts(that.graph)
);
// this.graph.fromJSON(this.data);
that.graph.on('edge:connected', ({ previousView, currentView }) => {
if (previousView) {
update(previousView as NodeView);
}
if (currentView) {
update(currentView as NodeView);
}
console.log(previousView);
});
that.graph.on('edge:removed', ({ edge, options }) => {
if (!options.ui) {
return;
}
const target = edge.getTargetCell();
if (target instanceof Device) {
target.updateInPorts(that.graph);
}
console.log(target);
});
that.graph.on('edge:mouseenter', ({ edge }) => {
edge.addTools([
'source-arrowhead',
'target-arrowhead',
{
name: 'button-remove',
args: {
distance: -30,
},
},
]);
console.log(edge);
});
that.graph.on('edge:mouseleave', ({ edge }) => {
edge.removeTools();
});
};
const update: (view: NodeView) => void = (view: NodeView) => {
const cell = view.cell;
if (cell instanceof Device) {
cell.getInPorts().forEach((port) => {
const portNode = view.findPortElem(port.id!, 'portBody');
view.unhighlight(portNode, {
highlighter: magnetAvailabilityHighlighter,
});
});
cell.updateInPorts(graph);
}
};
return {
canUndo,
canRedo,
history,
init,
update,
graph,
};
},
mounted() {
/* eslint-disable */
const that = this as any;
this.$nextTick(function () {
that.init(that);
});
},
});
class Device extends Shape.Circle {
getInPorts() {
return this.getPortsByGroup('in');
}
getOutPorts() {
return this.getPortsByGroup('out');
}
getUsedInPorts(graph: Graph) {
const incomingEdges = graph.getIncomingEdges(this) || [];
return incomingEdges.map((edge: Edge) => {
const portId = edge.getTargetPortId();
return this.getPort(portId!);
});
}
getNewInPorts(length: number) {
return Array.from(
{
length,
},
() => {
return {
group: 'in',
};
}
);
}
updateInPorts(graph: Graph) {
const minNumberOfPorts = 1;
const ports = this.getInPorts();
const usedPorts = this.getUsedInPorts(graph);
const newPorts = this.getNewInPorts(Math.max(minNumberOfPorts - usedPorts.length, 1));
if (ports.length === minNumberOfPorts && ports.length - usedPorts.length > 0) {
// noop
} else if (ports.length === usedPorts.length) {
this.addPorts(newPorts);
} else if (ports.length + 1 > usedPorts.length) {
this.prop(['ports', 'items'], this.getOutPorts().concat(usedPorts).concat(newPorts), {
rewrite: true,
});
}
return this;
}
}
//只是demo,实际上是这个JSON结构应该从后端传过来,然后在Device的构造方法中传入,参看左上角第一个设备
Device.config({
attrs: {
root: {
magnet: false,
},
body: {
fill: '#f5f5f5',
stroke: '#d9d9d9',
strokeWidth: 1,
},
},
ports: {
items: [
{
group: 'out',
},
],
groups: {
in: {
position: {
name: 'top',
},
attrs: {
portBody: {
magnet: 'passive',
r: 6,
stroke: '#ffa940',
fill: '#fff',
strokeWidth: 2,
},
},
},
out: {
position: {
name: 'bottom',
},
attrs: {
portBody: {
magnet: true,
r: 6,
fill: '#fff',
stroke: '#3199FF',
strokeWidth: 2,
},
},
},
},
},
portMarkup: [
{
tagName: 'circle',
selector: 'portBody',
},
],
});
class GateWay extends Shape.Rect {
getInPorts() {
return this.getPortsByGroup('in');
}
getOutPorts() {
return this.getPortsByGroup('out');
}
getUsedInPorts(graph: Graph) {
const incomingEdges = graph.getIncomingEdges(this) || [];
return incomingEdges.map((edge: Edge) => {
const portId = edge.getTargetPortId();
return this.getPort(portId!);
});
}
getNewInPorts(length: number) {
return Array.from(
{
length,
},
() => {
return {
group: 'in',
};
}
);
}
updateInPorts(graph: Graph) {
const minNumberOfPorts = 8;
const ports = this.getInPorts();
const usedPorts = this.getUsedInPorts(graph);
const newPorts = this.getNewInPorts(Math.max(minNumberOfPorts - usedPorts.length, 1));
if (ports.length === minNumberOfPorts && ports.length - usedPorts.length > 0) {
// noop
} else if (ports.length === usedPorts.length) {
this.addPorts(newPorts);
} else if (ports.length + 1 > usedPorts.length) {
this.prop(['ports', 'items'], this.getOutPorts().concat(usedPorts).concat(newPorts), {
rewrite: true,
});
}
return this;
}
}
GateWay.config({
attrs: {
root: {
magnet: false,
},
body: {
fill: '#ffa940',
stroke: '#d9d9d9',
strokeWidth: 1,
},
},
ports: {
items: [
{
group: 'out',
},
],
groups: {
in: {
position: {
name: 'top',
},
attrs: {
portBody: {
magnet: 'passive',
r: 6,
stroke: '#ffa940',
fill: '#fff',
strokeWidth: 2,
},
},
},
out: {
position: {
name: 'bottom',
},
attrs: {
portBody: {
magnet: true,
r: 6,
fill: '#fff',
stroke: '#3199FF',
strokeWidth: 2,
},
},
},
},
},
portMarkup: [
{
tagName: 'circle',
selector: 'portBody',
},
],
});
</script>
<style scoped></style>
......@@ -3,6 +3,7 @@
<div class="mb-4">
<a-button class="mr-2" @click="Open"> 新增 </a-button>
<a-button class="mr-2" @click="reloadTable">刷新 </a-button>
<a-button class="mr-2" @click="graphtest">X6 Test </a-button>
</div>
<BasicTable @register="registerTable" :searchInfo="searchInfo" @expand="handleexpand">
......@@ -24,7 +25,7 @@
</tr>
</tbody>
</table>
<BasicTitle helpMessage="遥测数据" >遥测数据</BasicTitle>
<BasicTitle helpMessage="遥测数据">遥测数据</BasicTitle>
<table style="width: 100%">
<tbody>
......@@ -66,12 +67,14 @@
</BasicTable>
<deviceform @register="registerDrawer" @success="handleSuccess" />
<propform @register="propDrawer" @success="handleSuccess" />
<devicegraph @register="graphtestDrawer" @success="handleSuccess" />
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue';
import { BasicTable, ColumnChangeParam, useTable, TableAction } from '/@/components/Table';
import { useDrawer } from '/@/components/Drawer';
import deviceform from './deviceform.vue';
import propform from './propform.vue';
import { useRouter } from 'vue-router';
......@@ -90,6 +93,7 @@
searchInfo.customerId = router.currentRoute.value.query.customerid;
const [propDrawer, { openDrawer: openPropDrawer }] = useDrawer();
const [registerDrawer, { openDrawer: openDrawer }] = useDrawer();
function onChange() {
console.log('onChange', arguments);
}
......@@ -123,7 +127,13 @@
isUpdate: false,
});
}
function graphtest(): void {
opengraphtestDrawer(true, {
// one of you need transfer data
data: {},
title: 'dummy title',
});
}
function PropEdit(record: Recordable) {
GetAttributeLatest({ id: record.id }).then((x) => {
let b = [{ keyName: 'id', value: record.id }, ...x];
......@@ -172,8 +182,11 @@
PropEdit,
handleexpand,
registerDrawer,
graphtest,
propDrawer,
openPropDrawer,
searchInfo,
};
},
......
......@@ -23,7 +23,6 @@
</template>
<script lang="ts">
import { Guid } from 'guid-typescript';
import { GetIdentity, Save, Update, SetAttribute } from '../../../api/iotsharp/device';
import { defineComponent, ref, computed, unref } from 'vue';
import { BasicForm, useForm } from '/@/components/Form/index';
......@@ -59,14 +58,14 @@
async function handleSubmit() {
try {
const values = await validate();
console.log(values);
setDrawerProps({ confirmLoading: true });
// TODO custom api
GetIdentity(values.id).then((x) => {
delete values.id; //remove extra data
// delete values.accesstoken;
GetIdentity(values.id).then((x) => {
delete values.id; //remove extra data
// delete values.accesstoken;
SetAttribute(values, x.identityId).then((y) => {
emit('success');
......
import { shallowRef, ref, onMounted } from 'vue';
import { Graph } from '@antv/x6';
import '@antv/x6-vue3-shape';
import Comp from './devicegraph.vue';
export default function useGraph() {
const container = ref<HTMLElement | null>(null);
const graph = shallowRef<Graph | null>();
onMounted(() => {
if (container.value) {
graph.value = new Graph({
container: container.value,
panning: true,
});
graph.value.addNode({
id: 'node1',
x: 40,
y: 40,
width: 100,
height: 40,
shape: 'vue3-shape',
// here are 4 ways usages:
// 1. component: Comp
// 2. component: <Comp />
// 3. component: () => <Comp />
// 4. component: 'text node'
component: Comp,
});
}
});
return {
container,
graph,
};
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册