mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-02 08:42:50 +00:00
Use Map* instead of plain models
This commit is contained in:
parent
17e59fde68
commit
e4e9c671c7
@ -21,6 +21,20 @@ import { DrawingsDraggableListener } from './listeners/drawings-draggable-listen
|
|||||||
import { NodesDraggableListener } from './listeners/nodes-draggable-listener';
|
import { NodesDraggableListener } from './listeners/nodes-draggable-listener';
|
||||||
import { DrawingsEventSource } from './events/drawings-event-source';
|
import { DrawingsEventSource } from './events/drawings-event-source';
|
||||||
import { NodesEventSource } from './events/nodes-event-source';
|
import { NodesEventSource } from './events/nodes-event-source';
|
||||||
|
import { DrawingToMapDrawingConverter } from './converters/map/drawing-to-map-drawing-converter';
|
||||||
|
import { LabelToMapLabelConverter } from './converters/map/label-to-map-label-converter';
|
||||||
|
import { LinkToMapLinkConverter } from './converters/map/link-to-map-link-converter';
|
||||||
|
import { MapDrawingToDrawingConverter } from './converters/map/map-drawing-to-drawing-converter';
|
||||||
|
import { MapLabelToLabelConverter } from './converters/map/map-label-to-label-converter';
|
||||||
|
import { MapLinkNodeToLinkNodeConverter } from './converters/map/map-link-node-to-link-node-converter';
|
||||||
|
import { MapLinkToLinkConverter } from './converters/map/map-link-to-link-converter';
|
||||||
|
import { MapNodeToNodeConverter } from './converters/map/map-node-to-node-converter';
|
||||||
|
import { MapPortToPortConverter } from './converters/map/map-port-to-port-converter';
|
||||||
|
import { MapSymbolToSymbolConverter } from './converters/map/map-symbol-to-symbol-converter';
|
||||||
|
import { NodeToMapNodeConverter } from './converters/map/node-to-map-node-converter';
|
||||||
|
import { PortToMapPortConverter } from './converters/map/port-to-map-port-converter';
|
||||||
|
import { SymbolToMapSymbolConverter } from './converters/map/symbol-to-map-symbol-converter';
|
||||||
|
import { LinkNodeToMapLinkNodeConverter } from './converters/map/link-node-to-map-link-node-converter';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -49,6 +63,20 @@ import { NodesEventSource } from './events/nodes-event-source';
|
|||||||
NodesDraggableListener,
|
NodesDraggableListener,
|
||||||
DrawingsEventSource,
|
DrawingsEventSource,
|
||||||
NodesEventSource,
|
NodesEventSource,
|
||||||
|
DrawingToMapDrawingConverter,
|
||||||
|
LabelToMapLabelConverter,
|
||||||
|
LinkToMapLinkConverter,
|
||||||
|
LinkNodeToMapLinkNodeConverter,
|
||||||
|
MapDrawingToDrawingConverter,
|
||||||
|
MapLabelToLabelConverter,
|
||||||
|
MapLinkNodeToLinkNodeConverter,
|
||||||
|
MapLinkToLinkConverter,
|
||||||
|
MapNodeToNodeConverter,
|
||||||
|
MapPortToPortConverter,
|
||||||
|
MapSymbolToSymbolConverter,
|
||||||
|
NodeToMapNodeConverter,
|
||||||
|
PortToMapPortConverter,
|
||||||
|
SymbolToMapSymbolConverter,
|
||||||
...D3_MAP_IMPORTS
|
...D3_MAP_IMPORTS
|
||||||
],
|
],
|
||||||
exports: [ MapComponent ]
|
exports: [ MapComponent ]
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Component, OnInit, Output, EventEmitter, OnDestroy, ViewChild } from '@angular/core';
|
import { Component, OnInit, Output, EventEmitter, OnDestroy, ViewChild } from '@angular/core';
|
||||||
import { Port } from '../../../models/port';
|
|
||||||
import { DrawingLineWidget } from '../../widgets/drawing-line';
|
import { DrawingLineWidget } from '../../widgets/drawing-line';
|
||||||
import { Node } from '../../models/node';
|
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { NodeSelectInterfaceComponent } from '../node-select-interface/node-select-interface.component';
|
import { NodeSelectInterfaceComponent } from '../node-select-interface/node-select-interface.component';
|
||||||
import { LinkCreated } from '../../events/links';
|
import { LinkCreated } from '../../events/links';
|
||||||
import { NodeClicked } from '../../events/nodes';
|
import { NodeClicked } from '../../events/nodes';
|
||||||
import { NodeWidget } from '../../widgets/node';
|
import { NodeWidget } from '../../widgets/node';
|
||||||
|
import { MapNode } from '../../models/map/map-node';
|
||||||
|
import { MapPort } from '../../models/map/map-port';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -44,8 +44,8 @@ export class DrawLinkToolComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onChooseInterface(event) {
|
public onChooseInterface(event) {
|
||||||
const node: Node = event.node;
|
const node: MapNode = event.node;
|
||||||
const port: Port = event.port;
|
const port: MapPort = event.port;
|
||||||
if (this.drawingLineTool.isDrawing()) {
|
if (this.drawingLineTool.isDrawing()) {
|
||||||
const data = this.drawingLineTool.stop();
|
const data = this.drawingLineTool.stop();
|
||||||
this.linkCreated.emit(new LinkCreated(data['node'], data['port'], node, port));
|
this.linkCreated.emit(new LinkCreated(data['node'], data['port'], node, port));
|
||||||
|
@ -3,13 +3,9 @@ import {
|
|||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { Selection, select } from 'd3-selection';
|
import { Selection, select } from 'd3-selection';
|
||||||
|
|
||||||
import { Node } from "../../models/node";
|
|
||||||
import { Link } from "../../../models/link";
|
|
||||||
import { GraphLayout } from "../../widgets/graph-layout";
|
import { GraphLayout } from "../../widgets/graph-layout";
|
||||||
import { Context } from "../../models/context";
|
import { Context } from "../../models/context";
|
||||||
import { Size } from "../../models/size";
|
import { Size } from "../../models/size";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { Symbol } from '../../../models/symbol';
|
|
||||||
import { NodesWidget } from '../../widgets/nodes';
|
import { NodesWidget } from '../../widgets/nodes';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||||
@ -25,6 +21,15 @@ import { DraggedDataEvent } from '../../events/event-source';
|
|||||||
import { NodesEventSource } from '../../events/nodes-event-source';
|
import { NodesEventSource } from '../../events/nodes-event-source';
|
||||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||||
import { DrawingsWidget } from '../../widgets/drawings';
|
import { DrawingsWidget } from '../../widgets/drawings';
|
||||||
|
import { Node } from '../../models/node';
|
||||||
|
import { Link } from '../../../models/link';
|
||||||
|
import { Drawing } from '../../models/drawing';
|
||||||
|
import { Symbol } from '../../../models/symbol';
|
||||||
|
import { MapNodeToNodeConverter } from '../../converters/map/map-node-to-node-converter';
|
||||||
|
import { NodeToMapNodeConverter } from '../../converters/map/node-to-map-node-converter';
|
||||||
|
import { DrawingToMapDrawingConverter } from '../../converters/map/drawing-to-map-drawing-converter';
|
||||||
|
import { LinkToMapLinkConverter } from '../../converters/map/link-to-map-link-converter';
|
||||||
|
import { SymbolToMapSymbolConverter } from '../../converters/map/symbol-to-map-symbol-converter';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -41,14 +46,16 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
@Input() width = 1500;
|
@Input() width = 1500;
|
||||||
@Input() height = 600;
|
@Input() height = 600;
|
||||||
|
|
||||||
@Output() nodeDragged: EventEmitter<DraggedDataEvent<Node>>;
|
@Output() nodeDragged = new EventEmitter<DraggedDataEvent<Node>>();
|
||||||
@Output() drawingDragged: EventEmitter<DraggedDataEvent<Drawing>>;
|
@Output() drawingDragged = new EventEmitter<DraggedDataEvent<Drawing>>();
|
||||||
@Output() onLinkCreated = new EventEmitter<LinkCreated>();
|
@Output() onLinkCreated = new EventEmitter<LinkCreated>();
|
||||||
|
|
||||||
private parentNativeElement: any;
|
private parentNativeElement: any;
|
||||||
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
||||||
|
|
||||||
private onChangesDetected: Subscription;
|
private onChangesDetected: Subscription;
|
||||||
|
private nodeDraggedSub: Subscription;
|
||||||
|
private drawingDraggedSub: Subscription;
|
||||||
|
|
||||||
protected settings = {
|
protected settings = {
|
||||||
'show_interface_labels': true
|
'show_interface_labels': true
|
||||||
@ -59,6 +66,11 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
private mapChangeDetectorRef: MapChangeDetectorRef,
|
private mapChangeDetectorRef: MapChangeDetectorRef,
|
||||||
private canvasSizeDetector: CanvasSizeDetector,
|
private canvasSizeDetector: CanvasSizeDetector,
|
||||||
private mapListeners: MapListeners,
|
private mapListeners: MapListeners,
|
||||||
|
private mapNodeToNode: MapNodeToNodeConverter,
|
||||||
|
private nodeToMapNode: NodeToMapNodeConverter,
|
||||||
|
private linkToMapLink: LinkToMapLinkConverter,
|
||||||
|
private drawingToMapDrawing: DrawingToMapDrawingConverter,
|
||||||
|
private symbolToMapSymbol: SymbolToMapSymbolConverter,
|
||||||
protected element: ElementRef,
|
protected element: ElementRef,
|
||||||
protected nodesWidget: NodesWidget,
|
protected nodesWidget: NodesWidget,
|
||||||
protected nodeWidget: NodeWidget,
|
protected nodeWidget: NodeWidget,
|
||||||
@ -68,12 +80,10 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
protected selectionToolWidget: SelectionTool,
|
protected selectionToolWidget: SelectionTool,
|
||||||
protected movingToolWidget: MovingTool,
|
protected movingToolWidget: MovingTool,
|
||||||
public graphLayout: GraphLayout,
|
public graphLayout: GraphLayout,
|
||||||
nodesEventSource: NodesEventSource,
|
private nodesEventSource: NodesEventSource,
|
||||||
drawingsEventSource: DrawingsEventSource,
|
private drawingsEventSource: DrawingsEventSource,
|
||||||
) {
|
) {
|
||||||
this.parentNativeElement = element.nativeElement;
|
this.parentNativeElement = element.nativeElement;
|
||||||
this.nodeDragged = nodesEventSource.dragged;
|
|
||||||
this.drawingDragged = drawingsEventSource.dragged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input('show-interface-labels')
|
@Input('show-interface-labels')
|
||||||
@ -138,6 +148,11 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.nodeDraggedSub = this.nodesEventSource.dragged.subscribe((evt) => {
|
||||||
|
const converted = this.mapNodeToNode.convert(evt.datum);
|
||||||
|
this.nodeDragged.emit(new DraggedDataEvent<Node>(converted));
|
||||||
|
});
|
||||||
|
|
||||||
this.mapListeners.onInit(this.svg);
|
this.mapListeners.onInit(this.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +160,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.graphLayout.disconnect(this.svg);
|
this.graphLayout.disconnect(this.svg);
|
||||||
this.onChangesDetected.unsubscribe();
|
this.onChangesDetected.unsubscribe();
|
||||||
this.mapListeners.onDestroy();
|
this.mapListeners.onDestroy();
|
||||||
|
this.nodeDraggedSub.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
public createGraph(domElement: HTMLElement) {
|
public createGraph(domElement: HTMLElement) {
|
||||||
@ -168,13 +184,29 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
this.context.size = this.getSize();
|
this.context.size = this.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.graphLayout.setNodes(this.nodes);
|
this.setNodes(this.nodes);
|
||||||
this.graphLayout.setLinks(this.links);
|
this.setLinks(this.links);
|
||||||
this.graphLayout.setDrawings(this.drawings);
|
this.setDrawings(this.drawings);
|
||||||
|
|
||||||
this.redraw();
|
this.redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setNodes(nodes: Node[]) {
|
||||||
|
this.graphLayout.setNodes(nodes.map((n) => this.nodeToMapNode.convert(n)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private setLinks(links: Link[]) {
|
||||||
|
this.graphLayout.setLinks(links.map((l) => this.linkToMapLink.convert(l)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private setDrawings(drawings: Drawing[]) {
|
||||||
|
this.graphLayout.setDrawings(drawings.map((d) => this.drawingToMapDrawing.convert(d)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private setSymbols(symbols: Symbol[]) {
|
||||||
|
this.nodeWidget.setSymbols(symbols.map((s) => this.symbolToMapSymbol.convert(s)));
|
||||||
|
}
|
||||||
|
|
||||||
private onLinksChange(change: SimpleChange) {
|
private onLinksChange(change: SimpleChange) {
|
||||||
const nodes_by_id = {};
|
const nodes_by_id = {};
|
||||||
this.nodes.forEach((n: Node) => {
|
this.nodes.forEach((n: Node) => {
|
||||||
@ -203,7 +235,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onSymbolsChange(change: SimpleChange) {
|
private onSymbolsChange(change: SimpleChange) {
|
||||||
this.nodeWidget.setSymbols(this.symbols);
|
this.setSymbols(this.symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
public redraw() {
|
public redraw() {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { ChangeDetectorRef, Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
|
||||||
import { MatMenuTrigger } from "@angular/material";
|
import { MatMenuTrigger } from "@angular/material";
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
import { Node } from "../../../cartography/models/node";
|
import { MapNode } from '../../models/map/map-node';
|
||||||
import { Port } from "../../../models/port";
|
import { MapPort } from '../../models/map/map-port';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -18,7 +18,7 @@ export class NodeSelectInterfaceComponent implements OnInit {
|
|||||||
protected topPosition;
|
protected topPosition;
|
||||||
protected leftPosition;
|
protected leftPosition;
|
||||||
|
|
||||||
public node: Node;
|
public node: MapNode;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
@ -35,13 +35,13 @@ export class NodeSelectInterfaceComponent implements OnInit {
|
|||||||
this.changeDetector.detectChanges();
|
this.changeDetector.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public open(node: Node, top: number, left: number) {
|
public open(node: MapNode, top: number, left: number) {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.setPosition(top, left);
|
this.setPosition(top, left);
|
||||||
this.contextMenu.openMenu();
|
this.contextMenu.openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
public chooseInterface(port: Port) {
|
public chooseInterface(port: MapPort) {
|
||||||
this.onChooseInterface.emit({
|
this.onChooseInterface.emit({
|
||||||
'node': this.node,
|
'node': this.node,
|
||||||
'port': port
|
'port': port
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
|
import { LabelToMapLabelConverter } from "./label-to-map-label-converter";
|
||||||
import { LinkNode } from "../../../models/link-node";
|
import { LinkNode } from "../../../models/link-node";
|
||||||
import { MapLinkNode } from "../../models/map/map-link-node";
|
import { MapLinkNode } from "../../models/map/map-link-node";
|
||||||
import { LabelToMapLabelConverter } from "./label-to-map-label-converter";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { MapLink } from "../../models/map/map-link";
|
|
||||||
import { Link } from "../../../models/link";
|
|
||||||
import { LinkNodeToMapLinkNodeConverter } from "./link-node-to-map-link-node-converter";
|
import { LinkNodeToMapLinkNodeConverter } from "./link-node-to-map-link-node-converter";
|
||||||
|
import { Link } from "../../../models/link";
|
||||||
|
import { MapLink } from "../../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { LinkNode } from "../../../models/link-node";
|
|
||||||
import { MapLinkNode } from "../../models/map/map-link-node";
|
import { MapLinkNode } from "../../models/map/map-link-node";
|
||||||
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
|
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
|
||||||
|
import { LinkNode } from "../../../models/link-node";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { MapLink } from "../../models/map/map-link";
|
|
||||||
import { Link } from "../../../models/link";
|
|
||||||
import { MapLinkNodeToLinkNodeConverter } from "./map-link-node-to-link-node-converter";
|
import { MapLinkNodeToLinkNodeConverter } from "./map-link-node-to-link-node-converter";
|
||||||
|
import { Link } from "../../../models/link";
|
||||||
|
import { MapLink } from "../../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -2,9 +2,9 @@ import { Injectable } from "@angular/core";
|
|||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { MapNode } from "../../models/map/map-node";
|
import { MapNode } from "../../models/map/map-node";
|
||||||
import { Node } from "../../models/node";
|
|
||||||
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
|
import { MapLabelToLabelConverter } from "./map-label-to-label-converter";
|
||||||
import { MapPortToPortConverter } from "./map-port-to-port-converter";
|
import { MapPortToPortConverter } from "./map-port-to-port-converter";
|
||||||
|
import { Node } from "../../models/node";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { MapPort } from "../../models/map/map-port";
|
|
||||||
import { Port } from "../../../models/port";
|
import { Port } from "../../../models/port";
|
||||||
|
import { MapPort } from "../../models/map/map-port";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { MapPort } from "../../models/map/map-port";
|
|
||||||
import { Port } from "../../../models/port";
|
import { Port } from "../../../models/port";
|
||||||
|
import { MapPort } from "../../models/map/map-port";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Converter } from "../converter";
|
import { Converter } from "../converter";
|
||||||
import { MapSymbol } from "../../models/map/map-symbol";
|
|
||||||
import { Symbol } from "../../../models/symbol";
|
import { Symbol } from "../../../models/symbol";
|
||||||
|
import { MapSymbol } from "../../models/map/map-symbol";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import { DrawingsDataSource } from "./drawings-datasource";
|
import { DrawingsDataSource } from "./drawings-datasource";
|
||||||
import { Drawing } from "../models/drawing";
|
import { MapDrawing } from "../models/drawing";
|
||||||
|
|
||||||
|
|
||||||
describe('DrawingsDataSource', () => {
|
describe('DrawingsDataSource', () => {
|
||||||
let dataSource: DrawingsDataSource;
|
let dataSource: DrawingsDataSource;
|
||||||
let data: Drawing[];
|
let data: MapDrawing[];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
dataSource = new DrawingsDataSource();
|
dataSource = new DrawingsDataSource();
|
||||||
dataSource.changes.subscribe((drawings: Drawing[]) => {
|
dataSource.changes.subscribe((drawings: MapDrawing[]) => {
|
||||||
data = drawings;
|
data = drawings;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Drawing can be updated', () => {
|
describe('Drawing can be updated', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const drawing = new Drawing();
|
const drawing = new MapDrawing();
|
||||||
drawing.drawing_id = "1";
|
drawing.drawing_id = "1";
|
||||||
drawing.project_id = "project1";
|
drawing.project_id = "project1";
|
||||||
dataSource.add(drawing);
|
dataSource.add(drawing);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { DataSource } from "./datasource";
|
import { DataSource } from "./datasource";
|
||||||
|
import { Drawing } from "../models/drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable, EventEmitter } from "@angular/core";
|
import { Injectable, EventEmitter } from "@angular/core";
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { DraggedDataEvent } from "./event-source";
|
import { DraggedDataEvent } from "./event-source";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DrawingsEventSource {
|
export class DrawingsEventSource {
|
||||||
public dragged = new EventEmitter<DraggedDataEvent<Drawing>>();
|
public dragged = new EventEmitter<DraggedDataEvent<MapDrawing>>();
|
||||||
}
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import { Node } from "../models/node";
|
import { MapNode } from "../models/map/map-node";
|
||||||
import { Port } from "../../models/port";
|
import { MapPort } from "../models/map/map-port";
|
||||||
|
|
||||||
|
|
||||||
export class LinkCreated {
|
export class LinkCreated {
|
||||||
constructor(
|
constructor(
|
||||||
public sourceNode: Node,
|
public sourceNode: MapNode,
|
||||||
public sourcePort: Port,
|
public sourcePort: MapPort,
|
||||||
public targetNode: Node,
|
public targetNode: MapNode,
|
||||||
public targetPort: Port
|
public targetPort: MapPort
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable, EventEmitter } from "@angular/core";
|
import { Injectable, EventEmitter } from "@angular/core";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { DraggedDataEvent } from "./event-source";
|
import { DraggedDataEvent } from "./event-source";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NodesEventSource {
|
export class NodesEventSource {
|
||||||
public dragged = new EventEmitter<DraggedDataEvent<Node>>();
|
public dragged = new EventEmitter<DraggedDataEvent<MapNode>>();
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import { Node } from "../models/node";
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
|
||||||
class NodeEvent {
|
class NodeEvent {
|
||||||
constructor(
|
constructor(
|
||||||
public event: any,
|
public event: any,
|
||||||
public node: Node
|
public node: MapNode
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { Link } from "../../models/link";
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -30,11 +30,11 @@ export class MultiLinkCalculatorHelper {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public assignDataToLinks(links: Link[]) {
|
public assignDataToLinks(links: MapLink[]) {
|
||||||
const links_from_nodes = {};
|
const links_from_nodes = {};
|
||||||
links.forEach((l: Link, i: number) => {
|
links.forEach((l: MapLink, i: number) => {
|
||||||
const sid = l.source.node_id;
|
const sid = l.source.id;
|
||||||
const tid = l.target.node_id;
|
const tid = l.target.id;
|
||||||
const key = (sid < tid ? sid + "," + tid : tid + "," + sid);
|
const key = (sid < tid ? sid + "," + tid : tid + "," + sid);
|
||||||
let idx = 1;
|
let idx = 1;
|
||||||
if (!(key in links_from_nodes)) {
|
if (!(key in links_from_nodes)) {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { DrawingsWidget } from "../widgets/drawings";
|
import { DrawingsWidget } from "../widgets/drawings";
|
||||||
import { DraggableStart } from "../events/draggable";
|
import { DraggableStart } from "../events/draggable";
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { Subscription } from "rxjs";
|
import { Subscription } from "rxjs";
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
import { SelectionManager } from "../managers/selection-manager";
|
||||||
import { DrawingsEventSource } from "../events/drawings-event-source";
|
import { DrawingsEventSource } from "../events/drawings-event-source";
|
||||||
import { DraggedDataEvent } from "../events/event-source";
|
import { DraggedDataEvent } from "../events/event-source";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -22,26 +22,26 @@ export class DrawingsDraggableListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onInit(svg: any) {
|
public onInit(svg: any) {
|
||||||
this.start = this.drawingsWidget.draggable.start.subscribe((evt: DraggableStart<Drawing>) => {
|
this.start = this.drawingsWidget.draggable.start.subscribe((evt: DraggableStart<MapDrawing>) => {
|
||||||
let drawings = this.selectionManager.getSelectedDrawings();
|
const drawings = this.selectionManager.getSelectedDrawings();
|
||||||
if (drawings.filter((n: Drawing) => n.drawing_id === evt.datum.drawing_id).length === 0) {
|
if (drawings.filter((n: MapDrawing) => n.id === evt.datum.id).length === 0) {
|
||||||
this.selectionManager.setSelectedDrawings([evt.datum]);
|
this.selectionManager.setSelectedDrawings([evt.datum]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.drag = this.drawingsWidget.draggable.drag.subscribe((evt: DraggableStart<Drawing>) => {
|
this.drag = this.drawingsWidget.draggable.drag.subscribe((evt: DraggableStart<MapDrawing>) => {
|
||||||
let drawings = this.selectionManager.getSelectedDrawings();
|
const drawings = this.selectionManager.getSelectedDrawings();
|
||||||
drawings.forEach((drawing: Drawing) => {
|
drawings.forEach((drawing: MapDrawing) => {
|
||||||
drawing.x += evt.dx;
|
drawing.x += evt.dx;
|
||||||
drawing.y += evt.dy;
|
drawing.y += evt.dy;
|
||||||
this.drawingsWidget.redrawDrawing(svg, drawing);
|
this.drawingsWidget.redrawDrawing(svg, drawing);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.end = this.drawingsWidget.draggable.end.subscribe((evt: DraggableStart<Drawing>) => {
|
this.end = this.drawingsWidget.draggable.end.subscribe((evt: DraggableStart<MapDrawing>) => {
|
||||||
let drawings = this.selectionManager.getSelectedDrawings();
|
const drawings = this.selectionManager.getSelectedDrawings();
|
||||||
drawings.forEach((drawing: Drawing) => {
|
drawings.forEach((drawing: MapDrawing) => {
|
||||||
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<Drawing>(drawing));
|
this.drawingsEventSource.dragged.emit(new DraggedDataEvent<MapDrawing>(drawing));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { NodesWidget } from "../widgets/nodes";
|
import { NodesWidget } from "../widgets/nodes";
|
||||||
import { DraggableStart } from "../events/draggable";
|
import { DraggableStart } from "../events/draggable";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Subscription } from "rxjs";
|
import { Subscription } from "rxjs";
|
||||||
import { SelectionManager } from "../managers/selection-manager";
|
import { SelectionManager } from "../managers/selection-manager";
|
||||||
import { LinksWidget } from "../widgets/links";
|
import { LinksWidget } from "../widgets/links";
|
||||||
import { GraphLayout } from "../widgets/graph-layout";
|
import { GraphLayout } from "../widgets/graph-layout";
|
||||||
import { NodesEventSource } from "../events/nodes-event-source";
|
import { NodesEventSource } from "../events/nodes-event-source";
|
||||||
import { DraggedDataEvent } from "../events/event-source";
|
import { DraggedDataEvent } from "../events/event-source";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -26,31 +26,32 @@ export class NodesDraggableListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onInit(svg: any) {
|
public onInit(svg: any) {
|
||||||
this.start = this.nodesWidget.draggable.start.subscribe((evt: DraggableStart<Node>) => {
|
this.start = this.nodesWidget.draggable.start.subscribe((evt: DraggableStart<MapNode>) => {
|
||||||
let nodes = this.selectionManager.getSelectedNodes();
|
const nodes = this.selectionManager.getSelectedNodes();
|
||||||
if (nodes.filter((n: Node) => n.node_id === evt.datum.node_id).length === 0) {
|
if (nodes.filter((n: MapNode) => n.id === evt.datum.id).length === 0) {
|
||||||
this.selectionManager.setSelectedNodes([evt.datum]);
|
this.selectionManager.setSelectedNodes([evt.datum]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.drag = this.nodesWidget.draggable.drag.subscribe((evt: DraggableStart<Node>) => {
|
this.drag = this.nodesWidget.draggable.drag.subscribe((evt: DraggableStart<MapNode>) => {
|
||||||
let nodes = this.selectionManager.getSelectedNodes();
|
const nodes = this.selectionManager.getSelectedNodes();
|
||||||
nodes.forEach((node: Node) => {
|
nodes.forEach((node: MapNode) => {
|
||||||
node.x += evt.dx;
|
node.x += evt.dx;
|
||||||
node.y += evt.dy;
|
node.y += evt.dy;
|
||||||
this.nodesWidget.redrawNode(svg, node);
|
this.nodesWidget.redrawNode(svg, node);
|
||||||
|
|
||||||
const links = this.graphLayout.getLinks().filter((link) => link.target.node_id === node.node_id || link.source.node_id === node.node_id);
|
const links = this.graphLayout.getLinks().filter(
|
||||||
|
(link) => link.target.id === node.id || link.source.id === node.id);
|
||||||
links.forEach((link) => {
|
links.forEach((link) => {
|
||||||
this.linksWidget.redrawLink(svg, link);
|
this.linksWidget.redrawLink(svg, link);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.end = this.nodesWidget.draggable.end.subscribe((evt: DraggableStart<Node>) => {
|
this.end = this.nodesWidget.draggable.end.subscribe((evt: DraggableStart<MapNode>) => {
|
||||||
let nodes = this.selectionManager.getSelectedNodes();
|
const nodes = this.selectionManager.getSelectedNodes();
|
||||||
nodes.forEach((node: Node) => {
|
nodes.forEach((node: MapNode) => {
|
||||||
this.nodesEventSource.dragged.emit(new DraggedDataEvent<Node>(node));
|
this.nodesEventSource.dragged.emit(new DraggedDataEvent<MapNode>(node));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { LayersManager } from "./layers-manager";
|
import { LayersManager } from "./layers-manager";
|
||||||
import { Node } from "../models/node";
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
import { Drawing } from "../models/drawing";
|
import { MapLink } from "../models/map/map-link";
|
||||||
import { Link } from "../../models/link";
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
|
||||||
|
|
||||||
describe('LayersManager', () => {
|
describe('LayersManager', () => {
|
||||||
@ -12,9 +12,9 @@ describe('LayersManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('nodes should be added', () => {
|
it('nodes should be added', () => {
|
||||||
const node_1 = new Node();
|
const node_1 = new MapNode();
|
||||||
node_1.z = 1;
|
node_1.z = 1;
|
||||||
const node_2 = new Node();
|
const node_2 = new MapNode();
|
||||||
node_2.z = 2;
|
node_2.z = 2;
|
||||||
|
|
||||||
manager.setNodes([node_1, node_2]);
|
manager.setNodes([node_1, node_2]);
|
||||||
@ -27,9 +27,9 @@ describe('LayersManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('drawings should be added', () => {
|
it('drawings should be added', () => {
|
||||||
const drawing_1 = new Drawing();
|
const drawing_1 = new MapDrawing();
|
||||||
drawing_1.z = 1;
|
drawing_1.z = 1;
|
||||||
const drawing_2 = new Drawing();
|
const drawing_2 = new MapDrawing();
|
||||||
drawing_2.z = 2;
|
drawing_2.z = 2;
|
||||||
|
|
||||||
manager.setDrawings([drawing_1, drawing_2]);
|
manager.setDrawings([drawing_1, drawing_2]);
|
||||||
@ -42,17 +42,17 @@ describe('LayersManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('links should be added', () => {
|
it('links should be added', () => {
|
||||||
const node_1 = new Node();
|
const node_1 = new MapNode();
|
||||||
node_1.z = 1;
|
node_1.z = 1;
|
||||||
|
|
||||||
const node_2 = new Node();
|
const node_2 = new MapNode();
|
||||||
node_2.z = 2;
|
node_2.z = 2;
|
||||||
|
|
||||||
const link_1 = new Link();
|
const link_1 = new MapLink();
|
||||||
link_1.source = node_1;
|
link_1.source = node_1;
|
||||||
link_1.target = node_1;
|
link_1.target = node_1;
|
||||||
|
|
||||||
const link_2 = new Link();
|
const link_2 = new MapLink();
|
||||||
link_2.source = node_1;
|
link_2.source = node_1;
|
||||||
link_2.target = node_1;
|
link_2.target = node_1;
|
||||||
|
|
||||||
@ -64,9 +64,9 @@ describe('LayersManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('layers should be cleared', () => {
|
it('layers should be cleared', () => {
|
||||||
const node_1 = new Node();
|
const node_1 = new MapNode();
|
||||||
node_1.z = 1;
|
node_1.z = 1;
|
||||||
const node_2 = new Node();
|
const node_2 = new MapNode();
|
||||||
node_2.z = 2;
|
node_2.z = 2;
|
||||||
|
|
||||||
manager.setNodes([node_1, node_2]);
|
manager.setNodes([node_1, node_2]);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Layer } from "../models/layer";
|
import { Layer } from "../models/layer";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { Dictionary } from "../models/types";
|
import { Dictionary } from "../models/types";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -23,26 +23,26 @@ export class LayersManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public setNodes(nodes: Node[]) {
|
public setNodes(nodes: MapNode[]) {
|
||||||
nodes
|
nodes
|
||||||
.forEach((node: Node) => {
|
.forEach((node: MapNode) => {
|
||||||
const layer = this.getLayerForKey(node.z.toString());
|
const layer = this.getLayerForKey(node.z.toString());
|
||||||
layer.nodes.push(node);
|
layer.nodes.push(node);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public setDrawings(drawings: Drawing[]) {
|
public setDrawings(drawings: MapDrawing[]) {
|
||||||
drawings
|
drawings
|
||||||
.forEach((drawing: Drawing) => {
|
.forEach((drawing: MapDrawing) => {
|
||||||
const layer = this.getLayerForKey(drawing.z.toString());
|
const layer = this.getLayerForKey(drawing.z.toString());
|
||||||
layer.drawings.push(drawing);
|
layer.drawings.push(drawing);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public setLinks(links: Link[]) {
|
public setLinks(links: MapLink[]) {
|
||||||
links
|
links
|
||||||
.filter((link: Link) => link.source && link.target)
|
.filter((link: MapLink) => link.source && link.target)
|
||||||
.forEach((link: Link) => {
|
.forEach((link: MapLink) => {
|
||||||
const key = Math.min(link.source.z, link.target.z).toString();
|
const key = Math.min(link.source.z, link.target.z).toString();
|
||||||
const layer = this.getLayerForKey(key);
|
const layer = this.getLayerForKey(key);
|
||||||
layer.links.push(link);
|
layer.links.push(link);
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { Subject} from "rxjs";
|
import { Subject} from "rxjs";
|
||||||
|
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { Rectangle } from "../models/rectangle";
|
import { Rectangle } from "../models/rectangle";
|
||||||
import { SelectionManager } from "./selection-manager";
|
import { SelectionManager } from "./selection-manager";
|
||||||
import { NodesDataSource } from "../datasources/nodes-datasource";
|
import { NodesDataSource } from "../datasources/nodes-datasource";
|
||||||
import { LinksDataSource } from "../datasources/links-datasource";
|
import { LinksDataSource } from "../datasources/links-datasource";
|
||||||
import { InRectangleHelper } from "../helpers/in-rectangle-helper";
|
import { InRectangleHelper } from "../helpers/in-rectangle-helper";
|
||||||
import { DrawingsDataSource } from "../datasources/drawings-datasource";
|
import { DrawingsDataSource } from "../datasources/drawings-datasource";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
describe('SelectionManager', () => {
|
describe('SelectionManager', () => {
|
||||||
@ -28,23 +28,23 @@ describe('SelectionManager', () => {
|
|||||||
manager = new SelectionManager(nodesDataSource, linksDataSource, drawingsDataSource, inRectangleHelper);
|
manager = new SelectionManager(nodesDataSource, linksDataSource, drawingsDataSource, inRectangleHelper);
|
||||||
manager.subscribe(selectedRectangleSubject);
|
manager.subscribe(selectedRectangleSubject);
|
||||||
|
|
||||||
const node_1 = new Node();
|
const node_1 = new MapNode();
|
||||||
node_1.node_id = "test1";
|
node_1.id = "test1";
|
||||||
node_1.name = "Node 1";
|
node_1.name = "Node 1";
|
||||||
node_1.x = 150;
|
node_1.x = 150;
|
||||||
node_1.y = 150;
|
node_1.y = 150;
|
||||||
|
|
||||||
nodesDataSource.add(node_1);
|
nodesDataSource.add(node_1);
|
||||||
|
|
||||||
const node_2 = new Node();
|
const node_2 = new MapNode();
|
||||||
node_2.node_id = "test2";
|
node_2.id = "test2";
|
||||||
node_2.name = "Node 2";
|
node_2.name = "Node 2";
|
||||||
node_2.x = 300;
|
node_2.x = 300;
|
||||||
node_2.y = 300;
|
node_2.y = 300;
|
||||||
nodesDataSource.add(node_2);
|
nodesDataSource.add(node_2);
|
||||||
|
|
||||||
const link_1 = new Link();
|
const link_1 = new MapLink();
|
||||||
link_1.link_id = "test1";
|
link_1.id = "test1";
|
||||||
linksDataSource.add(link_1);
|
linksDataSource.add(link_1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -64,26 +64,26 @@ describe('SelectionManager', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('nodes should be manually selected', () => {
|
it('nodes should be manually selected', () => {
|
||||||
const node = new Node();
|
const node = new MapNode();
|
||||||
node.node_id = "test1";
|
node.id = "test1";
|
||||||
manager.setSelectedNodes([node]);
|
manager.setSelectedNodes([node]);
|
||||||
expect(manager.getSelectedNodes().length).toEqual(1);
|
expect(manager.getSelectedNodes().length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('links should be manually selected', () => {
|
it('links should be manually selected', () => {
|
||||||
const link = new Link();
|
const link = new MapLink();
|
||||||
link.link_id = "test1";
|
link.id = "test1";
|
||||||
manager.setSelectedLinks([link]);
|
manager.setSelectedLinks([link]);
|
||||||
expect(manager.getSelectedLinks().length).toEqual(1);
|
expect(manager.getSelectedLinks().length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('items should be cleared', () => {
|
it('items should be cleared', () => {
|
||||||
const link = new Link();
|
const link = new MapLink();
|
||||||
link.link_id = "test1";
|
link.id = "test1";
|
||||||
const node = new Node();
|
const node = new MapNode();
|
||||||
node.node_id = "test1";
|
node.id = "test1";
|
||||||
const drawing = new Drawing();
|
const drawing = new MapDrawing();
|
||||||
drawing.drawing_id = "test1";
|
drawing.id = "test1";
|
||||||
manager.setSelectedLinks([link]);
|
manager.setSelectedLinks([link]);
|
||||||
manager.setSelectedNodes([node]);
|
manager.setSelectedNodes([node]);
|
||||||
manager.setSelectedDrawings([drawing]);
|
manager.setSelectedDrawings([drawing]);
|
||||||
|
@ -5,14 +5,14 @@ import { Subscription } from "rxjs";
|
|||||||
|
|
||||||
import { NodesDataSource } from "../datasources/nodes-datasource";
|
import { NodesDataSource } from "../datasources/nodes-datasource";
|
||||||
import { LinksDataSource } from "../datasources/links-datasource";
|
import { LinksDataSource } from "../datasources/links-datasource";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { InRectangleHelper } from "../helpers/in-rectangle-helper";
|
import { InRectangleHelper } from "../helpers/in-rectangle-helper";
|
||||||
import { Rectangle } from "../models/rectangle";
|
import { Rectangle } from "../models/rectangle";
|
||||||
import { Link} from "../../models/link";
|
|
||||||
import { DataSource } from "../datasources/datasource";
|
import { DataSource } from "../datasources/datasource";
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { InterfaceLabel } from "../models/interface-label";
|
import { InterfaceLabel } from "../models/interface-label";
|
||||||
import { DrawingsDataSource } from "../datasources/drawings-datasource";
|
import { DrawingsDataSource } from "../datasources/drawings-datasource";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
export interface Selectable {
|
export interface Selectable {
|
||||||
@ -23,18 +23,19 @@ export interface Selectable {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SelectionManager {
|
export class SelectionManager {
|
||||||
private selectedNodes: Node[] = [];
|
private selectedNodes: MapNode[] = [];
|
||||||
private selectedLinks: Link[] = [];
|
private selectedLinks: MapLink[] = [];
|
||||||
private selectedDrawings: Drawing[] = [];
|
private selectedDrawings: MapDrawing[] = [];
|
||||||
private selectedInterfaceLabels: InterfaceLabel[] = [];
|
private selectedInterfaceLabels: InterfaceLabel[] = [];
|
||||||
|
|
||||||
private subscription: Subscription;
|
private subscription: Subscription;
|
||||||
|
|
||||||
constructor(private nodesDataSource: NodesDataSource,
|
constructor(
|
||||||
|
private nodesDataSource: NodesDataSource,
|
||||||
private linksDataSource: LinksDataSource,
|
private linksDataSource: LinksDataSource,
|
||||||
private drawingsDataSource: DrawingsDataSource,
|
private drawingsDataSource: DrawingsDataSource,
|
||||||
private inRectangleHelper: InRectangleHelper) {}
|
private inRectangleHelper: InRectangleHelper
|
||||||
|
) {}
|
||||||
|
|
||||||
public subscribe(subject: Subject<Rectangle>) {
|
public subscribe(subject: Subject<Rectangle>) {
|
||||||
this.subscription = subject.subscribe((rectangle: Rectangle) => {
|
this.subscription = subject.subscribe((rectangle: Rectangle) => {
|
||||||
@ -44,9 +45,9 @@ export class SelectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onSelection(rectangle: Rectangle) {
|
public onSelection(rectangle: Rectangle) {
|
||||||
this.selectedNodes = this.getSelectedItemsInRectangle<Node>(this.nodesDataSource, rectangle);
|
// this.selectedNodes = this.getSelectedItemsInRectangle<MapNode>(this.nodesDataSource, rectangle);
|
||||||
this.selectedLinks = this.getSelectedItemsInRectangle<Link>(this.linksDataSource, rectangle);
|
// this.selectedLinks = this.getSelectedItemsInRectangle<MapLink>(this.linksDataSource, rectangle);
|
||||||
this.selectedDrawings = this.getSelectedItemsInRectangle<Drawing>(this.drawingsDataSource, rectangle);
|
// this.selectedDrawings = this.getSelectedItemsInRectangle<MapDrawing>(this.drawingsDataSource, rectangle);
|
||||||
// don't select interfaces for now
|
// don't select interfaces for now
|
||||||
// this.selectedInterfaceLabels = this.getSelectedInterfaceLabelsInRectangle(rectangle);
|
// this.selectedInterfaceLabels = this.getSelectedInterfaceLabelsInRectangle(rectangle);
|
||||||
}
|
}
|
||||||
@ -63,22 +64,22 @@ export class SelectionManager {
|
|||||||
return this.selectedDrawings;
|
return this.selectedDrawings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSelectedNodes(nodes: Node[]) {
|
public setSelectedNodes(nodes: MapNode[]) {
|
||||||
this.selectedNodes = this.setSelectedItems<Node>(this.nodesDataSource, (node: Node) => {
|
// this.selectedNodes = this.setSelectedItems<MapNode>(this.nodesDataSource, (node: MapNode) => {
|
||||||
return !!nodes.find((n: Node) => node.node_id === n.node_id);
|
// return !!nodes.find((n: MapNode) => node.id === n.id);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSelectedLinks(links: Link[]) {
|
public setSelectedLinks(links: MapLink[]) {
|
||||||
this.selectedLinks = this.setSelectedItems<Link>(this.linksDataSource, (link: Link) => {
|
// this.selectedLinks = this.setSelectedItems<MapLink>(this.linksDataSource, (link: MapLink) => {
|
||||||
return !!links.find((l: Link) => link.link_id === l.link_id);
|
// return !!links.find((l: MapLink) => link.link_id === l.link_id);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
public setSelectedDrawings(drawings: Drawing[]) {
|
public setSelectedDrawings(drawings: MapDrawing[]) {
|
||||||
this.selectedDrawings = this.setSelectedItems<Drawing>(this.drawingsDataSource, (drawing: Drawing) => {
|
// this.selectedDrawings = this.setSelectedItems<MapDrawing>(this.drawingsDataSource, (drawing: MapDrawing) => {
|
||||||
return !!drawings.find((d: Drawing) => drawing.drawing_id === d.drawing_id);
|
// return !!drawings.find((d: MapDrawing) => drawing.drawing_id === d.drawing_id);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
public clearSelection() {
|
public clearSelection() {
|
||||||
@ -94,33 +95,33 @@ export class SelectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getSelectedInterfaceLabelsInRectangle(rectangle: Rectangle) {
|
private getSelectedInterfaceLabelsInRectangle(rectangle: Rectangle) {
|
||||||
this.linksDataSource.getItems().forEach((link: Link) => {
|
// this.linksDataSource.getItems().forEach((link: MapLink) => {
|
||||||
if (!(link.source && link.target && link.nodes.length > 1)) {
|
// if (!(link.source && link.target && link.nodes.length > 1)) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
let updated = false;
|
// let updated = false;
|
||||||
|
|
||||||
let x = link.source.x + link.nodes[0].label.x;
|
// let x = link.source.x + link.nodes[0].label.x;
|
||||||
let y = link.source.y + link.nodes[0].label.y;
|
// let y = link.source.y + link.nodes[0].label.y;
|
||||||
|
|
||||||
if (this.inRectangleHelper.inRectangle(rectangle, x, y)) {
|
// if (this.inRectangleHelper.inRectangle(rectangle, x, y)) {
|
||||||
link.nodes[0].label.is_selected = true;
|
// link.nodes[0].label.is_selected = true;
|
||||||
updated = true;
|
// updated = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
x = link.target.x + link.nodes[1].label.x;
|
// x = link.target.x + link.nodes[1].label.x;
|
||||||
y = link.target.y + link.nodes[1].label.y;
|
// y = link.target.y + link.nodes[1].label.y;
|
||||||
|
|
||||||
if (this.inRectangleHelper.inRectangle(rectangle, x, y)) {
|
// if (this.inRectangleHelper.inRectangle(rectangle, x, y)) {
|
||||||
link.nodes[1].label.is_selected = true;
|
// link.nodes[1].label.is_selected = true;
|
||||||
updated = true;
|
// updated = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (updated) {
|
// if (updated) {
|
||||||
this.linksDataSource.update(link);
|
// this.linksDataSource.update(link);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import {Drawing} from "./drawing";
|
import { MapNode } from "./map/map-node";
|
||||||
import {Link} from "../../models/link";
|
import { MapDrawing } from "./map/map-drawing";
|
||||||
import {Node} from "./node";
|
import { MapLink } from "./map/map-link";
|
||||||
|
|
||||||
export class Layer {
|
export class Layer {
|
||||||
constructor(
|
constructor(
|
||||||
public index?: number,
|
public index?: number,
|
||||||
public nodes: Node[] = [],
|
public nodes: MapNode[] = [],
|
||||||
public drawings: Drawing[] = [],
|
public drawings: MapDrawing[] = [],
|
||||||
public links: Link[] = []
|
public links: MapLink[] = []
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { DrawingElement } from "../drawings/drawing-element";
|
||||||
|
|
||||||
export class MapDrawing {
|
export class MapDrawing {
|
||||||
id: string;
|
id: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
@ -6,4 +8,5 @@ export class MapDrawing {
|
|||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
z: number;
|
z: number;
|
||||||
|
element: DrawingElement; // @todo; apply converters
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { MapLinkNode } from "./map-link-node";
|
import { MapLinkNode } from "./map-link-node";
|
||||||
|
import { MapNode } from "./map-node";
|
||||||
|
|
||||||
export class MapLink {
|
export class MapLink {
|
||||||
id: string;
|
id: string;
|
||||||
@ -11,8 +12,8 @@ export class MapLink {
|
|||||||
|
|
||||||
distance: number; // this is not from server
|
distance: number; // this is not from server
|
||||||
length: number; // this is not from server
|
length: number; // this is not from server
|
||||||
source: Node; // this is not from server
|
source: MapNode; // this is not from server
|
||||||
target: Node; // this is not from server
|
target: MapNode; // this is not from server
|
||||||
|
|
||||||
isSelected = false; // this is not from server
|
isSelected = false; // this is not from server
|
||||||
x: number; // this is not from server
|
x: number; // this is not from server
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
import { Selectable } from "../managers/selection-manager";
|
||||||
import { Label } from "./label";
|
import { Label } from "./label";
|
||||||
import { Port } from "../../models/port";
|
import { Port } from "../../models/port";
|
||||||
import { Selectable } from "../managers/selection-manager";
|
|
||||||
|
|
||||||
|
|
||||||
export class Node implements Selectable {
|
export class Node implements Selectable {
|
||||||
|
@ -2,13 +2,13 @@ import { Injectable } from "@angular/core";
|
|||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { DrawingShapeWidget } from "./drawings/drawing-shape-widget";
|
import { DrawingShapeWidget } from "./drawings/drawing-shape-widget";
|
||||||
import { TextDrawingWidget } from "./drawings/text-drawing";
|
import { TextDrawingWidget } from "./drawings/text-drawing";
|
||||||
import { ImageDrawingWidget } from "./drawings/image-drawing";
|
import { ImageDrawingWidget } from "./drawings/image-drawing";
|
||||||
import { RectDrawingWidget } from "./drawings/rect-drawing";
|
import { RectDrawingWidget } from "./drawings/rect-drawing";
|
||||||
import { LineDrawingWidget } from "./drawings/line-drawing";
|
import { LineDrawingWidget } from "./drawings/line-drawing";
|
||||||
import { EllipseDrawingWidget } from "./drawings/ellipse-drawing";
|
import { EllipseDrawingWidget } from "./drawings/ellipse-drawing";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -32,7 +32,7 @@ export class DrawingWidget implements Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const drawing_body = view.selectAll<SVGGElement, Drawing>("g.drawing_body")
|
const drawing_body = view.selectAll<SVGGElement, MapDrawing>("g.drawing_body")
|
||||||
.data((l) => [l]);
|
.data((l) => [l]);
|
||||||
|
|
||||||
const drawing_body_enter = drawing_body.enter()
|
const drawing_body_enter = drawing_body.enter()
|
||||||
@ -40,7 +40,7 @@ export class DrawingWidget implements Widget {
|
|||||||
.attr("class", "drawing_body");
|
.attr("class", "drawing_body");
|
||||||
|
|
||||||
const drawing_body_merge = drawing_body.merge(drawing_body_enter)
|
const drawing_body_merge = drawing_body.merge(drawing_body_enter)
|
||||||
.attr('transform', (d: Drawing) => {
|
.attr('transform', (d: MapDrawing) => {
|
||||||
return `translate(${d.x},${d.y}) rotate(${d.rotation})`;
|
return `translate(${d.x},${d.y}) rotate(${d.rotation})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Layer } from "../models/layer";
|
import { Layer } from "../models/layer";
|
||||||
import { SvgToDrawingConverter } from "../helpers/svg-to-drawing-converter";
|
import { SvgToDrawingConverter } from "../helpers/svg-to-drawing-converter";
|
||||||
import { Draggable } from "../events/draggable";
|
import { Draggable } from "../events/draggable";
|
||||||
import { DrawingWidget } from "./drawing";
|
import { DrawingWidget } from "./drawing";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DrawingsWidget implements Widget {
|
export class DrawingsWidget implements Widget {
|
||||||
public draggable = new Draggable<SVGGElement, Drawing>();
|
public draggable = new Draggable<SVGGElement, MapDrawing>();
|
||||||
public draggingEnabled = false;
|
public draggingEnabled = false;
|
||||||
|
|
||||||
// public onContextMenu = new EventEmitter<NodeContextMenu>();
|
// public onContextMenu = new EventEmitter<NodeContextMenu>();
|
||||||
@ -26,15 +26,15 @@ export class DrawingsWidget implements Widget {
|
|||||||
this.svgToDrawingConverter = new SvgToDrawingConverter();
|
this.svgToDrawingConverter = new SvgToDrawingConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public redrawDrawing(view: SVGSelection, drawing: Drawing) {
|
public redrawDrawing(view: SVGSelection, drawing: MapDrawing) {
|
||||||
this.drawingWidget.draw(this.selectDrawing(view, drawing));
|
this.drawingWidget.draw(this.selectDrawing(view, drawing));
|
||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const drawing = view
|
const drawing = view
|
||||||
.selectAll<SVGGElement, Drawing>("g.drawing")
|
.selectAll<SVGGElement, MapDrawing>("g.drawing")
|
||||||
.data((layer: Layer) => {
|
.data((layer: Layer) => {
|
||||||
layer.drawings.forEach((d: Drawing) => {
|
layer.drawings.forEach((d: MapDrawing) => {
|
||||||
try {
|
try {
|
||||||
d.element = this.svgToDrawingConverter.convert(d.svg);
|
d.element = this.svgToDrawingConverter.convert(d.svg);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -42,14 +42,14 @@ export class DrawingsWidget implements Widget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return layer.drawings;
|
return layer.drawings;
|
||||||
}, (l: Drawing) => {
|
}, (l: MapDrawing) => {
|
||||||
return l.drawing_id;
|
return l.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const drawing_enter = drawing.enter()
|
const drawing_enter = drawing.enter()
|
||||||
.append<SVGGElement>('g')
|
.append<SVGGElement>('g')
|
||||||
.attr('class', 'drawing')
|
.attr('class', 'drawing')
|
||||||
.attr('drawing_id', (l: Drawing) => l.drawing_id)
|
.attr('drawing_id', (l: MapDrawing) => l.id)
|
||||||
|
|
||||||
const merge = drawing.merge(drawing_enter);
|
const merge = drawing.merge(drawing_enter);
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ export class DrawingsWidget implements Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private selectDrawing(view: SVGSelection, drawing: Drawing) {
|
private selectDrawing(view: SVGSelection, drawing: MapDrawing) {
|
||||||
return view.selectAll<SVGGElement, Drawing>(`g.drawing[drawing_id="${drawing.drawing_id}"]`);
|
return view.selectAll<SVGGElement, MapDrawing>(`g.drawing[drawing_id="${drawing.id}"]`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import { TestSVGCanvas } from "../../testing";
|
import { TestSVGCanvas } from "../../testing";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { EllipseDrawingWidget } from "./ellipse-drawing";
|
|
||||||
import { EllipseElement } from "../../models/drawings/ellipse-element";
|
import { EllipseElement } from "../../models/drawings/ellipse-element";
|
||||||
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
import { EllipseDrawingWidget } from "./ellipse-drawing";
|
||||||
|
|
||||||
|
|
||||||
describe('EllipseDrawingWidget', () => {
|
describe('EllipseDrawingWidget', () => {
|
||||||
let svg: TestSVGCanvas;
|
let svg: TestSVGCanvas;
|
||||||
let widget: EllipseDrawingWidget;
|
let widget: EllipseDrawingWidget;
|
||||||
let drawing: Drawing;
|
let drawing: MapDrawing;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
svg = new TestSVGCanvas();
|
svg = new TestSVGCanvas();
|
||||||
drawing = new Drawing();
|
drawing = new MapDrawing();
|
||||||
widget = new EllipseDrawingWidget(new QtDasharrayFixer());
|
widget = new EllipseDrawingWidget(new QtDasharrayFixer());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ describe('EllipseDrawingWidget', () => {
|
|||||||
ellipse.ry = 40;
|
ellipse.ry = 40;
|
||||||
drawing.element = ellipse;
|
drawing.element = ellipse;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { EllipseElement } from "../../models/drawings/ellipse-element";
|
import { EllipseElement } from "../../models/drawings/ellipse-element";
|
||||||
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
||||||
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -17,7 +17,7 @@ export class EllipseDrawingWidget implements DrawingShapeWidget {
|
|||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const drawing = view
|
const drawing = view
|
||||||
.selectAll<SVGEllipseElement, EllipseElement>('ellipse.ellipse_element')
|
.selectAll<SVGEllipseElement, EllipseElement>('ellipse.ellipse_element')
|
||||||
.data((d: Drawing) => {
|
.data((d: MapDrawing) => {
|
||||||
return (d.element && d.element instanceof EllipseElement) ? [d.element] : [];
|
return (d.element && d.element instanceof EllipseElement) ? [d.element] : [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { TestSVGCanvas } from "../../testing";
|
import { TestSVGCanvas } from "../../testing";
|
||||||
import { Drawing } from "../../models/drawing";
|
import { MapDrawing } from "../../models/drawing";
|
||||||
import { ImageDrawingWidget } from "./image-drawing";
|
import { ImageDrawingWidget } from "./image-drawing";
|
||||||
import { ImageElement } from "../../models/drawings/image-element";
|
import { ImageElement } from "../../models/drawings/image-element";
|
||||||
|
|
||||||
@ -7,12 +7,12 @@ import { ImageElement } from "../../models/drawings/image-element";
|
|||||||
describe('ImageDrawingWidget', () => {
|
describe('ImageDrawingWidget', () => {
|
||||||
let svg: TestSVGCanvas;
|
let svg: TestSVGCanvas;
|
||||||
let widget: ImageDrawingWidget;
|
let widget: ImageDrawingWidget;
|
||||||
let drawing: Drawing;
|
let drawing: MapDrawing;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
svg = new TestSVGCanvas();
|
svg = new TestSVGCanvas();
|
||||||
drawing = new Drawing();
|
drawing = new MapDrawing();
|
||||||
widget = new ImageDrawingWidget();
|
widget = new ImageDrawingWidget();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ describe('ImageDrawingWidget', () => {
|
|||||||
image.data = "data:image/svg+xml;base64,DATA";
|
image.data = "data:image/svg+xml;base64,DATA";
|
||||||
drawing.element = image;
|
drawing.element = image;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { ImageElement } from "../../models/drawings/image-element";
|
import { ImageElement } from "../../models/drawings/image-element";
|
||||||
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -11,7 +11,7 @@ export class ImageDrawingWidget implements DrawingShapeWidget {
|
|||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const drawing = view
|
const drawing = view
|
||||||
.selectAll<SVGImageElement, ImageElement>('image.image_element')
|
.selectAll<SVGImageElement, ImageElement>('image.image_element')
|
||||||
.data((d: Drawing) => {
|
.data((d: MapDrawing) => {
|
||||||
return (d.element && d.element instanceof ImageElement) ? [d.element] : [];
|
return (d.element && d.element instanceof ImageElement) ? [d.element] : [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import { TestSVGCanvas } from "../../testing";
|
import { TestSVGCanvas } from "../../testing";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { LineDrawingWidget } from "./line-drawing";
|
import { LineDrawingWidget } from "./line-drawing";
|
||||||
import { LineElement } from "../../models/drawings/line-element";
|
import { LineElement } from "../../models/drawings/line-element";
|
||||||
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
describe('LineDrawingWidget', () => {
|
describe('LineDrawingWidget', () => {
|
||||||
let svg: TestSVGCanvas;
|
let svg: TestSVGCanvas;
|
||||||
let widget: LineDrawingWidget;
|
let widget: LineDrawingWidget;
|
||||||
let drawing: Drawing;
|
let drawing: MapDrawing;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
svg = new TestSVGCanvas();
|
svg = new TestSVGCanvas();
|
||||||
drawing = new Drawing();
|
drawing = new MapDrawing();
|
||||||
widget = new LineDrawingWidget(new QtDasharrayFixer());
|
widget = new LineDrawingWidget(new QtDasharrayFixer());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ describe('LineDrawingWidget', () => {
|
|||||||
line.y2 = 40;
|
line.y2 = 40;
|
||||||
drawing.element = line;
|
drawing.element = line;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { LineElement } from "../../models/drawings/line-element";
|
import { LineElement } from "../../models/drawings/line-element";
|
||||||
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
||||||
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -17,7 +17,7 @@ export class LineDrawingWidget implements DrawingShapeWidget {
|
|||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const drawing = view
|
const drawing = view
|
||||||
.selectAll<SVGLineElement, LineElement>('line.line_element')
|
.selectAll<SVGLineElement, LineElement>('line.line_element')
|
||||||
.data((d: Drawing) => {
|
.data((d: MapDrawing) => {
|
||||||
return (d.element && d.element instanceof LineElement) ? [d.element] : [];
|
return (d.element && d.element instanceof LineElement) ? [d.element] : [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { TestSVGCanvas } from "../../testing";
|
import { TestSVGCanvas } from "../../testing";
|
||||||
import { Drawing } from "../../models/drawing";
|
import { MapDrawing } from "../../models/drawing";
|
||||||
import { RectDrawingWidget } from "./rect-drawing";
|
import { RectDrawingWidget } from "./rect-drawing";
|
||||||
import { RectElement } from "../../models/drawings/rect-element";
|
import { RectElement } from "../../models/drawings/rect-element";
|
||||||
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
||||||
@ -8,12 +8,12 @@ import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
|||||||
describe('RectDrawingWidget', () => {
|
describe('RectDrawingWidget', () => {
|
||||||
let svg: TestSVGCanvas;
|
let svg: TestSVGCanvas;
|
||||||
let widget: RectDrawingWidget;
|
let widget: RectDrawingWidget;
|
||||||
let drawing: Drawing;
|
let drawing: MapDrawing;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
svg = new TestSVGCanvas();
|
svg = new TestSVGCanvas();
|
||||||
drawing = new Drawing();
|
drawing = new MapDrawing();
|
||||||
widget = new RectDrawingWidget(new QtDasharrayFixer());
|
widget = new RectDrawingWidget(new QtDasharrayFixer());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ describe('RectDrawingWidget', () => {
|
|||||||
rect.height = 200;
|
rect.height = 200;
|
||||||
drawing.element = rect;
|
drawing.element = rect;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { RectElement } from "../../models/drawings/rect-element";
|
import { RectElement } from "../../models/drawings/rect-element";
|
||||||
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
||||||
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
import { QtDasharrayFixer } from "../../helpers/qt-dasharray-fixer";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -16,7 +16,7 @@ export class RectDrawingWidget implements DrawingShapeWidget {
|
|||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const drawing = view
|
const drawing = view
|
||||||
.selectAll<SVGRectElement, RectElement>('rect.rect_element')
|
.selectAll<SVGRectElement, RectElement>('rect.rect_element')
|
||||||
.data((d: Drawing) => {
|
.data((d: MapDrawing) => {
|
||||||
return (d.element && d.element instanceof RectElement) ? [d.element] : [];
|
return (d.element && d.element instanceof RectElement) ? [d.element] : [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { TestSVGCanvas } from "../../testing";
|
import { TestSVGCanvas } from "../../testing";
|
||||||
import { TextDrawingWidget } from "./text-drawing";
|
import { TextDrawingWidget } from "./text-drawing";
|
||||||
import { Drawing } from "../../models/drawing";
|
import { MapDrawing } from "../../models/drawing";
|
||||||
import { TextElement } from "../../models/drawings/text-element";
|
import { TextElement } from "../../models/drawings/text-element";
|
||||||
import { FontFixer } from "../../helpers/font-fixer";
|
import { FontFixer } from "../../helpers/font-fixer";
|
||||||
|
|
||||||
describe('TextDrawingWidget', () => {
|
describe('TextDrawingWidget', () => {
|
||||||
let svg: TestSVGCanvas;
|
let svg: TestSVGCanvas;
|
||||||
let widget: TextDrawingWidget;
|
let widget: TextDrawingWidget;
|
||||||
let drawing: Drawing;
|
let drawing: MapDrawing;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
svg = new TestSVGCanvas();
|
svg = new TestSVGCanvas();
|
||||||
drawing = new Drawing();
|
drawing = new MapDrawing();
|
||||||
widget = new TextDrawingWidget(new FontFixer());
|
widget = new TextDrawingWidget(new FontFixer());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ describe('TextDrawingWidget', () => {
|
|||||||
|
|
||||||
drawing.element = text;
|
drawing.element = text;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ describe('TextDrawingWidget', () => {
|
|||||||
text.text = 'THIS' + "\n" + 'IS TEXT';
|
text.text = 'THIS' + "\n" + 'IS TEXT';
|
||||||
drawing.element = text;
|
drawing.element = text;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ describe('TextDrawingWidget', () => {
|
|||||||
text.text = ' Text with whitespaces';
|
text.text = ' Text with whitespaces';
|
||||||
drawing.element = text;
|
drawing.element = text;
|
||||||
|
|
||||||
const drawings = svg.canvas.selectAll<SVGGElement, Drawing>('g.drawing').data([drawing]);
|
const drawings = svg.canvas.selectAll<SVGGElement, MapDrawing>('g.drawing').data([drawing]);
|
||||||
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
const drawings_enter = drawings.enter().append<SVGGElement>('g').classed('drawing', true);
|
||||||
const drawings_merge = drawings.merge(drawings_enter);
|
const drawings_merge = drawings.merge(drawings_enter);
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ import { Injectable } from "@angular/core";
|
|||||||
|
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { TextElement } from "../../models/drawings/text-element";
|
import { TextElement } from "../../models/drawings/text-element";
|
||||||
import { Drawing } from "../../models/drawing";
|
|
||||||
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
import { DrawingShapeWidget } from "./drawing-shape-widget";
|
||||||
import { FontFixer } from "../../helpers/font-fixer";
|
import { FontFixer } from "../../helpers/font-fixer";
|
||||||
import { select } from "d3-selection";
|
import { select } from "d3-selection";
|
||||||
|
import { MapDrawing } from "../../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -20,7 +20,7 @@ export class TextDrawingWidget implements DrawingShapeWidget {
|
|||||||
|
|
||||||
const drawing = view
|
const drawing = view
|
||||||
.selectAll<SVGTextElement, TextElement>('text.text_element')
|
.selectAll<SVGTextElement, TextElement>('text.text_element')
|
||||||
.data((d: Drawing) => {
|
.data((d: MapDrawing) => {
|
||||||
return (d.element && d.element instanceof TextElement) ? [d.element] : [];
|
return (d.element && d.element instanceof TextElement) ? [d.element] : [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import { Context } from "../models/context";
|
import { Context } from "../models/context";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { NodesWidget } from "./nodes";
|
import { NodesWidget } from "./nodes";
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Drawing } from "../models/drawing";
|
|
||||||
import { DrawingLineWidget } from "./drawing-line";
|
import { DrawingLineWidget } from "./drawing-line";
|
||||||
import { SelectionTool } from "../tools/selection-tool";
|
import { SelectionTool } from "../tools/selection-tool";
|
||||||
import { MovingTool } from "../tools/moving-tool";
|
import { MovingTool } from "../tools/moving-tool";
|
||||||
import { LayersWidget } from "./layers";
|
import { LayersWidget } from "./layers";
|
||||||
import { LayersManager } from "../managers/layers-manager";
|
import { LayersManager } from "../managers/layers-manager";
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
import { MapDrawing } from "../models/map/map-drawing";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GraphLayout implements Widget {
|
export class GraphLayout implements Widget {
|
||||||
private nodes: Node[] = [];
|
private nodes: MapNode[] = [];
|
||||||
private links: Link[] = [];
|
private links: MapLink[] = [];
|
||||||
private drawings: Drawing[] = [];
|
private drawings: MapDrawing[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private nodesWidget: NodesWidget,
|
private nodesWidget: NodesWidget,
|
||||||
@ -28,11 +28,11 @@ export class GraphLayout implements Widget {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public setNodes(nodes: Node[]) {
|
public setNodes(nodes: MapNode[]) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setLinks(links: Link[]) {
|
public setLinks(links: MapLink[]) {
|
||||||
this.links = links;
|
this.links = links;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ export class GraphLayout implements Widget {
|
|||||||
return this.links;
|
return this.links;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setDrawings(drawings: Drawing[]) {
|
public setDrawings(drawings: MapDrawing[]) {
|
||||||
this.drawings = drawings;
|
this.drawings = drawings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
import { Selection } from "d3-selection";
|
import { Selection } from "d3-selection";
|
||||||
|
|
||||||
import { TestSVGCanvas } from "../testing";
|
import { TestSVGCanvas } from "../testing";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { LinkNode } from "../../models/link-node";
|
|
||||||
import { Label } from "../models/label";
|
|
||||||
import { InterfaceLabel } from "../models/interface-label";
|
import { InterfaceLabel } from "../models/interface-label";
|
||||||
import { InterfaceLabelWidget } from "./interface-label";
|
import { InterfaceLabelWidget } from "./interface-label";
|
||||||
import { CssFixer } from "../helpers/css-fixer";
|
import { CssFixer } from "../helpers/css-fixer";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
import { MapLinkNode } from "../models/map/map-link-node";
|
||||||
|
import { MapLabel } from "../models/map/map-label";
|
||||||
|
|
||||||
|
|
||||||
describe('InterfaceLabelsWidget', () => {
|
describe('InterfaceLabelsWidget', () => {
|
||||||
let svg: TestSVGCanvas;
|
let svg: TestSVGCanvas;
|
||||||
let widget: InterfaceLabelWidget;
|
let widget: InterfaceLabelWidget;
|
||||||
let linksEnter: Selection<SVGGElement, Link, SVGGElement, any>;
|
let linksEnter: Selection<SVGGElement, MapLink, SVGGElement, any>;
|
||||||
let links: Link[];
|
let links: MapLink[];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
svg = new TestSVGCanvas();
|
svg = new TestSVGCanvas();
|
||||||
|
|
||||||
const node_1 = new Node();
|
const node_1 = new MapNode();
|
||||||
node_1.node_id = "1";
|
node_1.id = "1";
|
||||||
node_1.x = 100;
|
node_1.x = 100;
|
||||||
node_1.y = 200;
|
node_1.y = 200;
|
||||||
|
|
||||||
const node_2 = new Node();
|
const node_2 = new MapNode();
|
||||||
node_2.node_id = "2";
|
node_2.id = "2";
|
||||||
node_2.x = 300;
|
node_2.x = 300;
|
||||||
node_2.y = 400;
|
node_2.y = 400;
|
||||||
|
|
||||||
const link_node_1 = new LinkNode();
|
const link_node_1 = new MapLinkNode();
|
||||||
link_node_1.label = new Label();
|
link_node_1.label = new MapLabel();
|
||||||
link_node_1.label.rotation = 5;
|
link_node_1.label.rotation = 5;
|
||||||
link_node_1.label.text = "Interface 1";
|
link_node_1.label.text = "Interface 1";
|
||||||
link_node_1.label.x = 10;
|
link_node_1.label.x = 10;
|
||||||
link_node_1.label.y = 20;
|
link_node_1.label.y = 20;
|
||||||
link_node_1.label.style = "font-size: 12px";
|
link_node_1.label.style = "font-size: 12px";
|
||||||
|
|
||||||
const link_node_2 = new LinkNode();
|
const link_node_2 = new MapLinkNode();
|
||||||
link_node_2.label = new Label();
|
link_node_2.label = new MapLabel();
|
||||||
link_node_2.label.rotation = 0;
|
link_node_2.label.rotation = 0;
|
||||||
link_node_2.label.text = "Interface 2";
|
link_node_2.label.text = "Interface 2";
|
||||||
link_node_2.label.x = -30;
|
link_node_2.label.x = -30;
|
||||||
link_node_2.label.y = -40;
|
link_node_2.label.y = -40;
|
||||||
link_node_2.label.style = "";
|
link_node_2.label.style = "";
|
||||||
|
|
||||||
const link_1 = new Link();
|
const link_1 = new MapLink();
|
||||||
link_1.link_id = "link1";
|
link_1.id = "link1";
|
||||||
link_1.source = node_1;
|
link_1.source = node_1;
|
||||||
link_1.target = node_2;
|
link_1.target = node_2;
|
||||||
link_1.nodes = [link_node_1, link_node_2];
|
link_1.nodes = [link_node_1, link_node_2];
|
||||||
link_1.link_type = "ethernet";
|
link_1.linkType = "ethernet";
|
||||||
|
|
||||||
links = [link_1];
|
links = [link_1];
|
||||||
|
|
||||||
const linksSelection = svg.canvas
|
const linksSelection = svg.canvas
|
||||||
.selectAll<SVGGElement, Link>('g.link')
|
.selectAll<SVGGElement, MapLink>('g.link')
|
||||||
.data(links);
|
.data(links);
|
||||||
|
|
||||||
linksEnter = linksSelection
|
linksEnter = linksSelection
|
||||||
@ -111,7 +111,7 @@ describe('InterfaceLabelsWidget', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should draw interface label with class `selected` when selected', () => {
|
it('should draw interface label with class `selected` when selected', () => {
|
||||||
links[0].nodes[0].label.is_selected = true;
|
links[0].nodes[0].label.isSelected = true;
|
||||||
|
|
||||||
widget.draw(linksEnter);
|
widget.draw(linksEnter);
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { InterfaceLabel } from "../models/interface-label";
|
import { InterfaceLabel } from "../models/interface-label";
|
||||||
import { CssFixer } from "../helpers/css-fixer";
|
import { CssFixer } from "../helpers/css-fixer";
|
||||||
import { select } from "d3-selection";
|
import { select } from "d3-selection";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class InterfaceLabelWidget {
|
export class InterfaceLabelWidget {
|
||||||
@ -25,27 +25,27 @@ export class InterfaceLabelWidget {
|
|||||||
|
|
||||||
const labels = selection
|
const labels = selection
|
||||||
.selectAll<SVGGElement, InterfaceLabel>('g.interface_label_container')
|
.selectAll<SVGGElement, InterfaceLabel>('g.interface_label_container')
|
||||||
.data((l: Link) => {
|
.data((l: MapLink) => {
|
||||||
const sourceInterface = new InterfaceLabel(
|
const sourceInterface = new InterfaceLabel(
|
||||||
l.link_id,
|
l.id,
|
||||||
'source',
|
'source',
|
||||||
Math.round(l.source.x + l.nodes[0].label.x),
|
Math.round(l.source.x + l.nodes[0].label.x),
|
||||||
Math.round(l.source.y + l.nodes[0].label.y),
|
Math.round(l.source.y + l.nodes[0].label.y),
|
||||||
l.nodes[0].label.text,
|
l.nodes[0].label.text,
|
||||||
l.nodes[0].label.style,
|
l.nodes[0].label.style,
|
||||||
l.nodes[0].label.rotation,
|
l.nodes[0].label.rotation,
|
||||||
l.nodes[0].label.is_selected
|
l.nodes[0].label.isSelected
|
||||||
);
|
);
|
||||||
|
|
||||||
const targetInterface = new InterfaceLabel(
|
const targetInterface = new InterfaceLabel(
|
||||||
l.link_id,
|
l.id,
|
||||||
'target',
|
'target',
|
||||||
Math.round( l.target.x + l.nodes[1].label.x),
|
Math.round( l.target.x + l.nodes[1].label.x),
|
||||||
Math.round( l.target.y + l.nodes[1].label.y),
|
Math.round( l.target.y + l.nodes[1].label.y),
|
||||||
l.nodes[1].label.text,
|
l.nodes[1].label.text,
|
||||||
l.nodes[1].label.style,
|
l.nodes[1].label.style,
|
||||||
l.nodes[1].label.rotation,
|
l.nodes[1].label.rotation,
|
||||||
l.nodes[1].label.is_selected
|
l.nodes[1].label.isSelected
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.enabled) {
|
if (this.enabled) {
|
||||||
|
@ -4,8 +4,8 @@ import { select } from "d3-selection";
|
|||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { LinkStatus } from "../models/link-status";
|
import { LinkStatus } from "../models/link-status";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -13,8 +13,8 @@ export class InterfaceStatusWidget implements Widget {
|
|||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
view.each(function (this: SVGGElement, l: Link) {
|
view.each(function (this: SVGGElement, l: MapLink) {
|
||||||
const link_group = select<SVGGElement, Link>(this);
|
const link_group = select<SVGGElement, MapLink>(this);
|
||||||
const link_path = link_group.select<SVGPathElement>('path');
|
const link_path = link_group.select<SVGPathElement>('path');
|
||||||
|
|
||||||
const start_point: SVGPoint = link_path.node().getPointAtLength(45);
|
const start_point: SVGPoint = link_path.node().getPointAtLength(45);
|
||||||
|
@ -2,12 +2,12 @@ import { Injectable } from "@angular/core";
|
|||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { SerialLinkWidget } from "./links/serial-link";
|
import { SerialLinkWidget } from "./links/serial-link";
|
||||||
import { EthernetLinkWidget } from "./links/ethernet-link";
|
import { EthernetLinkWidget } from "./links/ethernet-link";
|
||||||
import { MultiLinkCalculatorHelper } from "../helpers/multi-link-calculator-helper";
|
import { MultiLinkCalculatorHelper } from "../helpers/multi-link-calculator-helper";
|
||||||
import { InterfaceLabelWidget } from "./interface-label";
|
import { InterfaceLabelWidget } from "./interface-label";
|
||||||
import { InterfaceStatusWidget } from "./interface-status";
|
import { InterfaceStatusWidget } from "./interface-status";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -20,7 +20,7 @@ export class LinkWidget implements Widget {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const link_body = view.selectAll<SVGGElement, Link>("g.link_body")
|
const link_body = view.selectAll<SVGGElement, MapLink>("g.link_body")
|
||||||
.data((l) => [l]);
|
.data((l) => [l]);
|
||||||
|
|
||||||
const link_body_enter = link_body.enter()
|
const link_body_enter = link_body.enter()
|
||||||
@ -41,7 +41,7 @@ export class LinkWidget implements Widget {
|
|||||||
|
|
||||||
link_body_merge
|
link_body_merge
|
||||||
.select<SVGPathElement>('path')
|
.select<SVGPathElement>('path')
|
||||||
.classed('selected', (l: Link) => l.is_selected);
|
.classed('selected', (l: MapLink) => l.isSelected);
|
||||||
|
|
||||||
this.interfaceLabelWidget.draw(link_body_merge);
|
this.interfaceLabelWidget.draw(link_body_merge);
|
||||||
this.interfaceStatusWidget.draw(link_body_merge);
|
this.interfaceStatusWidget.draw(link_body_merge);
|
||||||
|
@ -5,10 +5,10 @@ import { Selection } from "d3-selection";
|
|||||||
import { TestSVGCanvas } from "../testing";
|
import { TestSVGCanvas } from "../testing";
|
||||||
import { Layer } from "../models/layer";
|
import { Layer } from "../models/layer";
|
||||||
import { LinksWidget } from "./links";
|
import { LinksWidget } from "./links";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { LinkWidget } from "./link";
|
import { LinkWidget } from "./link";
|
||||||
import { MultiLinkCalculatorHelper } from "../helpers/multi-link-calculator-helper";
|
import { MultiLinkCalculatorHelper } from "../helpers/multi-link-calculator-helper";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
describe('LinksWidget', () => {
|
describe('LinksWidget', () => {
|
||||||
@ -23,21 +23,21 @@ describe('LinksWidget', () => {
|
|||||||
linkWidget = instance(mock(LinkWidget));
|
linkWidget = instance(mock(LinkWidget));
|
||||||
widget = new LinksWidget(new MultiLinkCalculatorHelper(), linkWidget);
|
widget = new LinksWidget(new MultiLinkCalculatorHelper(), linkWidget);
|
||||||
|
|
||||||
const node_1 = new Node();
|
const node_1 = new MapNode();
|
||||||
node_1.node_id = "1";
|
node_1.id = "1";
|
||||||
node_1.x = 10;
|
node_1.x = 10;
|
||||||
node_1.y = 10;
|
node_1.y = 10;
|
||||||
|
|
||||||
const node_2 = new Node();
|
const node_2 = new MapNode();
|
||||||
node_2.node_id = "2";
|
node_2.id = "2";
|
||||||
node_2.x = 100;
|
node_2.x = 100;
|
||||||
node_2.y = 100;
|
node_2.y = 100;
|
||||||
|
|
||||||
const link_1 = new Link();
|
const link_1 = new MapLink();
|
||||||
link_1.link_id = "link1";
|
link_1.id = "link1";
|
||||||
link_1.source = node_1;
|
link_1.source = node_1;
|
||||||
link_1.target = node_2;
|
link_1.target = node_2;
|
||||||
link_1.link_type = "ethernet";
|
link_1.linkType = "ethernet";
|
||||||
|
|
||||||
layer = new Layer();
|
layer = new Layer();
|
||||||
layer.index = 1;
|
layer.index = 1;
|
||||||
@ -67,7 +67,7 @@ describe('LinksWidget', () => {
|
|||||||
it('should draw links', () => {
|
it('should draw links', () => {
|
||||||
widget.draw(layersEnter);
|
widget.draw(layersEnter);
|
||||||
|
|
||||||
const drew = svg.canvas.selectAll<SVGGElement, Link>('g.link');
|
const drew = svg.canvas.selectAll<SVGGElement, MapLink>('g.link');
|
||||||
const linkNode = drew.nodes()[0];
|
const linkNode = drew.nodes()[0];
|
||||||
expect(linkNode.getAttribute('link_id')).toEqual('link1');
|
expect(linkNode.getAttribute('link_id')).toEqual('link1');
|
||||||
expect(linkNode.getAttribute('map-source')).toEqual('1');
|
expect(linkNode.getAttribute('map-source')).toEqual('1');
|
||||||
|
@ -2,10 +2,10 @@ import { Injectable } from "@angular/core";
|
|||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Link } from "../../models/link";
|
|
||||||
import { MultiLinkCalculatorHelper } from "../helpers/multi-link-calculator-helper";
|
import { MultiLinkCalculatorHelper } from "../helpers/multi-link-calculator-helper";
|
||||||
import { Layer } from "../models/layer";
|
import { Layer } from "../models/layer";
|
||||||
import { LinkWidget } from "./link";
|
import { LinkWidget } from "./link";
|
||||||
|
import { MapLink } from "../models/map/map-link";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LinksWidget implements Widget {
|
export class LinksWidget implements Widget {
|
||||||
@ -15,32 +15,32 @@ export class LinksWidget implements Widget {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public redrawLink(view: SVGSelection, link: Link) {
|
public redrawLink(view: SVGSelection, link: MapLink) {
|
||||||
this.linkWidget.draw(this.selectLink(view, link));
|
this.linkWidget.draw(this.selectLink(view, link));
|
||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const link = view
|
const link = view
|
||||||
.selectAll<SVGGElement, Link>("g.link")
|
.selectAll<SVGGElement, MapLink>("g.link")
|
||||||
.data((layer: Layer) => {
|
.data((layer: Layer) => {
|
||||||
if (layer.links) {
|
if (layer.links) {
|
||||||
const layer_links = layer.links.filter((l: Link) => {
|
const layer_links = layer.links.filter((l: MapLink) => {
|
||||||
return l.target && l.source;
|
return l.target && l.source;
|
||||||
});
|
});
|
||||||
this.multiLinkCalculatorHelper.assignDataToLinks(layer_links);
|
this.multiLinkCalculatorHelper.assignDataToLinks(layer_links);
|
||||||
return layer_links;
|
return layer_links;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}, (l: Link) => {
|
}, (l: MapLink) => {
|
||||||
return l.link_id;
|
return l.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const link_enter = link.enter()
|
const link_enter = link.enter()
|
||||||
.append<SVGGElement>('g')
|
.append<SVGGElement>('g')
|
||||||
.attr('class', 'link')
|
.attr('class', 'link')
|
||||||
.attr('link_id', (l: Link) => l.link_id)
|
.attr('link_id', (l: MapLink) => l.id)
|
||||||
.attr('map-source', (l: Link) => l.source.node_id)
|
.attr('map-source', (l: MapLink) => l.source.id)
|
||||||
.attr('map-target', (l: Link) => l.target.node_id);
|
.attr('map-target', (l: MapLink) => l.target.id);
|
||||||
|
|
||||||
const merge = link.merge(link_enter);
|
const merge = link.merge(link_enter);
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export class LinksWidget implements Widget {
|
|||||||
.remove();
|
.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
private selectLink(view: SVGSelection, link: Link) {
|
private selectLink(view: SVGSelection, link: MapLink) {
|
||||||
return view.selectAll<SVGGElement, Link>(`g.link[link_id="${link.link_id}"]`);
|
return view.selectAll<SVGGElement, MapLink>(`g.link[link_id="${link.id}"]`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { path } from "d3-path";
|
|||||||
|
|
||||||
import { Widget } from "../widget";
|
import { Widget } from "../widget";
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { Link } from "../../../models/link";
|
import { MapLink } from "../../models/map/map-link";
|
||||||
|
|
||||||
class EthernetLinkPath {
|
class EthernetLinkPath {
|
||||||
constructor(
|
constructor(
|
||||||
@ -13,7 +13,7 @@ class EthernetLinkPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class EthernetLinkWidget implements Widget {
|
export class EthernetLinkWidget implements Widget {
|
||||||
private linktoEthernetLink(link: Link) {
|
private linktoEthernetLink(link: MapLink) {
|
||||||
return new EthernetLinkPath(
|
return new EthernetLinkPath(
|
||||||
[link.source.x + link.source.width / 2., link.source.y + link.source.height / 2.],
|
[link.source.x + link.source.width / 2., link.source.y + link.source.height / 2.],
|
||||||
[link.target.x + link.target.width / 2., link.target.y + link.target.height / 2.]
|
[link.target.x + link.target.width / 2., link.target.y + link.target.height / 2.]
|
||||||
@ -24,9 +24,9 @@ export class EthernetLinkWidget implements Widget {
|
|||||||
|
|
||||||
const link = view
|
const link = view
|
||||||
.selectAll<SVGPathElement, EthernetLinkPath>('path.ethernet_link')
|
.selectAll<SVGPathElement, EthernetLinkPath>('path.ethernet_link')
|
||||||
.data((link) => {
|
.data((l) => {
|
||||||
if(link.link_type === 'ethernet') {
|
if (l.linkType === 'ethernet') {
|
||||||
return [this.linktoEthernetLink(link)];
|
return [this.linktoEthernetLink(l)];
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@ import { path } from "d3-path";
|
|||||||
|
|
||||||
import { Widget } from "../widget";
|
import { Widget } from "../widget";
|
||||||
import { SVGSelection } from "../../models/types";
|
import { SVGSelection } from "../../models/types";
|
||||||
import { Link } from "../../../models/link";
|
import { MapLink } from "../../models/map/map-link";
|
||||||
|
|
||||||
|
|
||||||
class SerialLinkPath {
|
class SerialLinkPath {
|
||||||
@ -18,7 +18,7 @@ class SerialLinkPath {
|
|||||||
|
|
||||||
export class SerialLinkWidget implements Widget {
|
export class SerialLinkWidget implements Widget {
|
||||||
|
|
||||||
private linkToSerialLink(link: Link) {
|
private linkToSerialLink(link: MapLink) {
|
||||||
const source = {
|
const source = {
|
||||||
'x': link.source.x + link.source.width / 2,
|
'x': link.source.x + link.source.width / 2,
|
||||||
'y': link.source.y + link.source.height / 2
|
'y': link.source.y + link.source.height / 2
|
||||||
@ -60,9 +60,9 @@ export class SerialLinkWidget implements Widget {
|
|||||||
|
|
||||||
const link = view
|
const link = view
|
||||||
.selectAll<SVGPathElement, SerialLinkPath>('path.serial_link')
|
.selectAll<SVGPathElement, SerialLinkPath>('path.serial_link')
|
||||||
.data((link) => {
|
.data((l) => {
|
||||||
if(link.link_type === 'serial') {
|
if (l.linkType === 'serial') {
|
||||||
return [this.linkToSerialLink(link)];
|
return [this.linkToSerialLink(l)];
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
import { TestSVGCanvas } from "../testing";
|
import { TestSVGCanvas } from "../testing";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { Label } from "../models/label";
|
|
||||||
import { CssFixer } from "../helpers/css-fixer";
|
import { CssFixer } from "../helpers/css-fixer";
|
||||||
import { FontFixer } from "../helpers/font-fixer";
|
import { FontFixer } from "../helpers/font-fixer";
|
||||||
import { NodeWidget } from "./node";
|
import { NodeWidget } from "./node";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
import { MapLabel } from "../models/map/map-label";
|
||||||
|
|
||||||
|
|
||||||
describe('NodesWidget', () => {
|
describe('NodesWidget', () => {
|
||||||
@ -21,9 +21,9 @@ describe('NodesWidget', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('draggable behaviour', () => {
|
describe('draggable behaviour', () => {
|
||||||
let node: Node;
|
let node: MapNode;
|
||||||
const tryToDrag = () => {
|
const tryToDrag = () => {
|
||||||
const drew = svg.canvas.selectAll<SVGGElement, Node>('g.node');
|
const drew = svg.canvas.selectAll<SVGGElement, MapNode>('g.node');
|
||||||
const drewNode = drew.nodes()[0];
|
const drewNode = drew.nodes()[0];
|
||||||
|
|
||||||
drewNode.dispatchEvent(
|
drewNode.dispatchEvent(
|
||||||
@ -38,12 +38,12 @@ describe('NodesWidget', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
node = new Node();
|
node = new MapNode();
|
||||||
node.x = 100;
|
node.x = 100;
|
||||||
node.y = 200;
|
node.y = 200;
|
||||||
node.width = 100;
|
node.width = 100;
|
||||||
node.height = 100;
|
node.height = 100;
|
||||||
node.label = new Label();
|
node.label = new MapLabel();
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should be draggable when enabled', () => {
|
// it('should be draggable when enabled', () => {
|
||||||
|
@ -2,13 +2,12 @@ import { Injectable, EventEmitter } from "@angular/core";
|
|||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { NodeContextMenu, NodeClicked, NodeDragged, NodeDragging } from "../events/nodes";
|
import { NodeContextMenu, NodeClicked, NodeDragged, NodeDragging } from "../events/nodes";
|
||||||
import { CssFixer } from "../helpers/css-fixer";
|
import { CssFixer } from "../helpers/css-fixer";
|
||||||
import { FontFixer } from "../helpers/font-fixer";
|
import { FontFixer } from "../helpers/font-fixer";
|
||||||
import { select, event } from "d3-selection";
|
import { select, event } from "d3-selection";
|
||||||
import { Symbol } from "../../models/symbol";
|
import { MapSymbol } from "../models/map/map-symbol";
|
||||||
import { D3DragEvent, drag } from "d3-drag";
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -20,21 +19,21 @@ export class NodeWidget implements Widget {
|
|||||||
public onNodeDragged = new EventEmitter<NodeDragged>();
|
public onNodeDragged = new EventEmitter<NodeDragged>();
|
||||||
public onNodeDragging = new EventEmitter<NodeDragging>();
|
public onNodeDragging = new EventEmitter<NodeDragging>();
|
||||||
|
|
||||||
private symbols: Symbol[] = [];
|
private symbols: MapSymbol[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private cssFixer: CssFixer,
|
private cssFixer: CssFixer,
|
||||||
private fontFixer: FontFixer,
|
private fontFixer: FontFixer,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public setSymbols(symbols: Symbol[]) {
|
public setSymbols(symbols: MapSymbol[]) {
|
||||||
this.symbols = symbols;
|
this.symbols = symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
const node_body = view.selectAll<SVGGElement, Node>("g.node_body")
|
const node_body = view.selectAll<SVGGElement, MapNode>("g.node_body")
|
||||||
.data((n) => [n]);
|
.data((n) => [n]);
|
||||||
|
|
||||||
const node_body_enter = node_body.enter()
|
const node_body_enter = node_body.enter()
|
||||||
@ -50,52 +49,52 @@ export class NodeWidget implements Widget {
|
|||||||
.attr('class', 'label');
|
.attr('class', 'label');
|
||||||
|
|
||||||
const node_body_merge = node_body.merge(node_body_enter)
|
const node_body_merge = node_body.merge(node_body_enter)
|
||||||
.classed('selected', (n: Node) => n.is_selected)
|
.classed('selected', (n: MapNode) => n.isSelected)
|
||||||
.on("contextmenu", function (n: Node, i: number) {
|
.on("contextmenu", function (n: MapNode, i: number) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
self.onContextMenu.emit(new NodeContextMenu(event, n));
|
||||||
})
|
})
|
||||||
.on('click', (n: Node) => {
|
.on('click', (n: MapNode) => {
|
||||||
this.onNodeClicked.emit(new NodeClicked(event, n));
|
this.onNodeClicked.emit(new NodeClicked(event, n));
|
||||||
});
|
});
|
||||||
|
|
||||||
// update image of node
|
// update image of node
|
||||||
node_body_merge
|
node_body_merge
|
||||||
.select<SVGImageElement>('image')
|
.select<SVGImageElement>('image')
|
||||||
.attr('xnode:href', (n: Node) => {
|
.attr('xnode:href', (n: MapNode) => {
|
||||||
const symbol = this.symbols.find((s: Symbol) => s.symbol_id === n.symbol);
|
const symbol = this.symbols.find((s: MapSymbol) => s.id === n.symbol);
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
|
return 'data:image/svg+xml;base64,' + btoa(symbol.raw);
|
||||||
}
|
}
|
||||||
// @todo; we need to have default image
|
// @todo; we need to have default image
|
||||||
return 'data:image/svg+xml;base64,none';
|
return 'data:image/svg+xml;base64,none';
|
||||||
})
|
})
|
||||||
.attr('width', (n: Node) => n.width)
|
.attr('width', (n: MapNode) => n.width)
|
||||||
.attr('height', (n: Node) => n.height)
|
.attr('height', (n: MapNode) => n.height)
|
||||||
.attr('x', (n: Node) => 0)
|
.attr('x', (n: MapNode) => 0)
|
||||||
.attr('y', (n: Node) => 0)
|
.attr('y', (n: MapNode) => 0)
|
||||||
.on('mouseover', function (this, n: Node) {
|
.on('mouseover', function (this, n: MapNode) {
|
||||||
select(this).attr("class", "over");
|
select(this).attr("class", "over");
|
||||||
})
|
})
|
||||||
.on('mouseout', function (this, n: Node) {
|
.on('mouseout', function (this, n: MapNode) {
|
||||||
select(this).attr("class", "");
|
select(this).attr("class", "");
|
||||||
});
|
});
|
||||||
|
|
||||||
node_body_merge
|
node_body_merge
|
||||||
.attr('transform', (n: Node) => {
|
.attr('transform', (n: MapNode) => {
|
||||||
return `translate(${n.x},${n.y})`;
|
return `translate(${n.x},${n.y})`;
|
||||||
});
|
});
|
||||||
|
|
||||||
node_body_merge
|
node_body_merge
|
||||||
.select<SVGTextElement>('text.label')
|
.select<SVGTextElement>('text.label')
|
||||||
// .attr('y', (n: Node) => n.label.y - n.height / 2. + 10) // @todo: server computes y in auto way
|
// .attr('y', (n: Node) => n.label.y - n.height / 2. + 10) // @todo: server computes y in auto way
|
||||||
.attr('style', (n: Node) => {
|
.attr('style', (n: MapNode) => {
|
||||||
let styles = this.cssFixer.fix(n.label.style);
|
let styles = this.cssFixer.fix(n.label.style);
|
||||||
styles = this.fontFixer.fixStyles(styles);
|
styles = this.fontFixer.fixStyles(styles);
|
||||||
return styles;
|
return styles;
|
||||||
})
|
})
|
||||||
.text((n: Node) => n.label.text)
|
.text((n: MapNode) => n.label.text)
|
||||||
.attr('x', function (this: SVGTextElement, n: Node) {
|
.attr('x', function (this: SVGTextElement, n: MapNode) {
|
||||||
if (n.label.x === null) {
|
if (n.label.x === null) {
|
||||||
// center
|
// center
|
||||||
const bbox = this.getBBox();
|
const bbox = this.getBBox();
|
||||||
@ -103,7 +102,7 @@ export class NodeWidget implements Widget {
|
|||||||
}
|
}
|
||||||
return n.label.x + NodeWidget.NODE_LABEL_MARGIN;
|
return n.label.x + NodeWidget.NODE_LABEL_MARGIN;
|
||||||
})
|
})
|
||||||
.attr('y', function (this: SVGTextElement, n: Node) {
|
.attr('y', function (this: SVGTextElement, n: MapNode) {
|
||||||
let bbox = this.getBBox();
|
let bbox = this.getBBox();
|
||||||
|
|
||||||
if (n.label.x === null) {
|
if (n.label.x === null) {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { Widget } from "./widget";
|
import { Widget } from "./widget";
|
||||||
import { Node } from "../models/node";
|
|
||||||
import { SVGSelection } from "../models/types";
|
import { SVGSelection } from "../models/types";
|
||||||
import { Layer } from "../models/layer";
|
import { Layer } from "../models/layer";
|
||||||
import { NodeWidget } from "./node";
|
import { NodeWidget } from "./node";
|
||||||
import { Draggable } from "../events/draggable";
|
import { Draggable } from "../events/draggable";
|
||||||
|
import { MapNode } from "../models/map/map-node";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NodesWidget implements Widget {
|
export class NodesWidget implements Widget {
|
||||||
static NODE_LABEL_MARGIN = 3;
|
static NODE_LABEL_MARGIN = 3;
|
||||||
|
|
||||||
public draggable = new Draggable<SVGGElement, Node>();
|
public draggable = new Draggable<SVGGElement, MapNode>();
|
||||||
public draggingEnabled = false;
|
public draggingEnabled = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -20,26 +20,26 @@ export class NodesWidget implements Widget {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public redrawNode(view: SVGSelection, node: Node) {
|
public redrawNode(view: SVGSelection, node: MapNode) {
|
||||||
this.nodeWidget.draw(this.selectNode(view, node));
|
this.nodeWidget.draw(this.selectNode(view, node));
|
||||||
}
|
}
|
||||||
|
|
||||||
public draw(view: SVGSelection) {
|
public draw(view: SVGSelection) {
|
||||||
const node = view
|
const node = view
|
||||||
.selectAll<SVGGElement, Node>("g.node")
|
.selectAll<SVGGElement, MapNode>("g.node")
|
||||||
.data((layer: Layer) => {
|
.data((layer: Layer) => {
|
||||||
if (layer.nodes) {
|
if (layer.nodes) {
|
||||||
return layer.nodes;
|
return layer.nodes;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}, (n: Node) => {
|
}, (n: MapNode) => {
|
||||||
return n.node_id;
|
return n.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const node_enter = node.enter()
|
const node_enter = node.enter()
|
||||||
.append<SVGGElement>('g')
|
.append<SVGGElement>('g')
|
||||||
.attr('class', 'node')
|
.attr('class', 'node')
|
||||||
.attr('node_id', (n: Node) => n.node_id)
|
.attr('node_id', (n: MapNode) => n.id)
|
||||||
|
|
||||||
const merge = node.merge(node_enter);
|
const merge = node.merge(node_enter);
|
||||||
|
|
||||||
@ -54,8 +54,8 @@ export class NodesWidget implements Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private selectNode(view: SVGSelection, node: Node) {
|
private selectNode(view: SVGSelection, node: MapNode) {
|
||||||
return view.selectAll<SVGGElement, Node>(`g.node[node_id="${node.node_id}"]`);
|
return view.selectAll<SVGGElement, MapNode>(`g.node[node_id="${node.id}"]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ export class MoveLayerUpActionComponent implements OnInit {
|
|||||||
|
|
||||||
moveLayerUp() {
|
moveLayerUp() {
|
||||||
this.node.z++;
|
this.node.z++;
|
||||||
|
this.nodesDataSource.update(this.node);
|
||||||
this.nodeService
|
this.nodeService
|
||||||
.update(this.server, this.node)
|
.update(this.server, this.node)
|
||||||
.subscribe((node: Node) => {});
|
.subscribe((node: Node) => {});
|
||||||
|
@ -37,14 +37,14 @@ export class ProjectMapShortcutsComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
onDeleteHandler(event: KeyboardEvent): boolean {
|
onDeleteHandler(event: KeyboardEvent): boolean {
|
||||||
if (!this.projectService.isReadOnly(this.project)) {
|
if (!this.projectService.isReadOnly(this.project)) {
|
||||||
const selectedNodes = this.selectionManager.getSelectedNodes();
|
// const selectedNodes = this.selectionManager.getSelectedNodes();
|
||||||
if (selectedNodes) {
|
// if (selectedNodes) {
|
||||||
selectedNodes.forEach((node) => {
|
// selectedNodes.forEach((node) => {
|
||||||
this.nodesService.delete(this.server, node).subscribe(data => {
|
// this.nodesService.delete(this.server, node).subscribe(data => {
|
||||||
this.toaster.success("Node has been deleted");
|
// this.toaster.success("Node has been deleted");
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import { LinkCreated } from '../../cartography/events/links';
|
|||||||
import { NodeWidget } from '../../cartography/widgets/node';
|
import { NodeWidget } from '../../cartography/widgets/node';
|
||||||
import { DraggedDataEvent } from '../../cartography/events/event-source';
|
import { DraggedDataEvent } from '../../cartography/events/event-source';
|
||||||
import { DrawingService } from '../../services/drawing.service';
|
import { DrawingService } from '../../services/drawing.service';
|
||||||
|
import { MapNodeToNodeConverter } from '../../cartography/converters/map/map-node-to-node-converter';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -77,6 +78,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
private mapChangeDetectorRef: MapChangeDetectorRef,
|
private mapChangeDetectorRef: MapChangeDetectorRef,
|
||||||
private nodeWidget: NodeWidget,
|
private nodeWidget: NodeWidget,
|
||||||
private selectionManager: SelectionManager,
|
private selectionManager: SelectionManager,
|
||||||
|
private mapNodeToNode: MapNodeToNodeConverter,
|
||||||
protected nodesDataSource: NodesDataSource,
|
protected nodesDataSource: NodesDataSource,
|
||||||
protected linksDataSource: LinksDataSource,
|
protected linksDataSource: LinksDataSource,
|
||||||
protected drawingsDataSource: DrawingsDataSource,
|
protected drawingsDataSource: DrawingsDataSource,
|
||||||
@ -187,8 +189,9 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
setUpMapCallbacks(project: Project) {
|
setUpMapCallbacks(project: Project) {
|
||||||
const onContextMenu = this.nodeWidget.onContextMenu.subscribe((eventNode: NodeContextMenu) => {
|
const onContextMenu = this.nodeWidget.onContextMenu.subscribe((eventNode: NodeContextMenu) => {
|
||||||
|
const node = this.mapNodeToNode.convert(eventNode.node);
|
||||||
this.nodeContextMenu.open(
|
this.nodeContextMenu.open(
|
||||||
eventNode.node,
|
node,
|
||||||
eventNode.event.clientY,
|
eventNode.event.clientY,
|
||||||
eventNode.event.clientX
|
eventNode.event.clientX
|
||||||
);
|
);
|
||||||
|
@ -16,9 +16,11 @@ export class WebServiceMessage {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectWebServiceHandler {
|
export class ProjectWebServiceHandler {
|
||||||
constructor(private nodesDataSource: NodesDataSource,
|
constructor(
|
||||||
|
private nodesDataSource: NodesDataSource,
|
||||||
private linksDataSource: LinksDataSource,
|
private linksDataSource: LinksDataSource,
|
||||||
private drawingsDataSource: DrawingsDataSource) {}
|
private drawingsDataSource: DrawingsDataSource
|
||||||
|
) {}
|
||||||
|
|
||||||
public connect(ws: Subject<WebServiceMessage>) {
|
public connect(ws: Subject<WebServiceMessage>) {
|
||||||
const subscription = ws.subscribe((message: WebServiceMessage) => {
|
const subscription = ws.subscribe((message: WebServiceMessage) => {
|
||||||
|
@ -14,7 +14,6 @@ describe('DrawingService', () => {
|
|||||||
let httpClient: HttpClient;
|
let httpClient: HttpClient;
|
||||||
let httpTestingController: HttpTestingController;
|
let httpTestingController: HttpTestingController;
|
||||||
let httpServer: HttpServer;
|
let httpServer: HttpServer;
|
||||||
let service: DrawingService;
|
|
||||||
let server: Server;
|
let server: Server;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -32,7 +31,6 @@ describe('DrawingService', () => {
|
|||||||
httpClient = TestBed.get(HttpClient);
|
httpClient = TestBed.get(HttpClient);
|
||||||
httpTestingController = TestBed.get(HttpTestingController);
|
httpTestingController = TestBed.get(HttpTestingController);
|
||||||
httpServer = TestBed.get(HttpServer);
|
httpServer = TestBed.get(HttpServer);
|
||||||
service = TestBed.get(DrawingService);
|
|
||||||
server = getTestServer();
|
server = getTestServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ describe('LinkService', () => {
|
|||||||
let httpClient: HttpClient;
|
let httpClient: HttpClient;
|
||||||
let httpTestingController: HttpTestingController;
|
let httpTestingController: HttpTestingController;
|
||||||
let httpServer: HttpServer;
|
let httpServer: HttpServer;
|
||||||
let service: LinkService;
|
|
||||||
let server: Server;
|
let server: Server;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -32,7 +31,6 @@ describe('LinkService', () => {
|
|||||||
httpClient = TestBed.get(HttpClient);
|
httpClient = TestBed.get(HttpClient);
|
||||||
httpTestingController = TestBed.get(HttpTestingController);
|
httpTestingController = TestBed.get(HttpTestingController);
|
||||||
httpServer = TestBed.get(HttpServer);
|
httpServer = TestBed.get(HttpServer);
|
||||||
service = TestBed.get(LinkService);
|
|
||||||
server = getTestServer();
|
server = getTestServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ import {Port} from "../models/port";
|
|||||||
export class LinkService {
|
export class LinkService {
|
||||||
|
|
||||||
|
|
||||||
constructor(private httpServer: HttpServer) { }
|
constructor(
|
||||||
|
private httpServer: HttpServer) {}
|
||||||
|
|
||||||
createLink(
|
createLink(
|
||||||
server: Server, source_node: Node, source_port: Port, target_node: Node, target_port: Port) {
|
server: Server, source_node: Node, source_port: Port, target_node: Node, target_port: Port) {
|
||||||
|
@ -12,7 +12,8 @@ import { SettingsService } from "./settings.service";
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectService {
|
export class ProjectService {
|
||||||
|
|
||||||
constructor(private httpServer: HttpServer,
|
constructor(
|
||||||
|
private httpServer: HttpServer,
|
||||||
private settingsService: SettingsService) {}
|
private settingsService: SettingsService) {}
|
||||||
|
|
||||||
get(server: Server, project_id: string) {
|
get(server: Server, project_id: string) {
|
||||||
|
@ -14,7 +14,6 @@ describe('SymbolService', () => {
|
|||||||
let httpClient: HttpClient;
|
let httpClient: HttpClient;
|
||||||
let httpTestingController: HttpTestingController;
|
let httpTestingController: HttpTestingController;
|
||||||
let httpServer: HttpServer;
|
let httpServer: HttpServer;
|
||||||
let service: SymbolService;
|
|
||||||
let server: Server;
|
let server: Server;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -32,7 +31,6 @@ describe('SymbolService', () => {
|
|||||||
httpClient = TestBed.get(HttpClient);
|
httpClient = TestBed.get(HttpClient);
|
||||||
httpTestingController = TestBed.get(HttpTestingController);
|
httpTestingController = TestBed.get(HttpTestingController);
|
||||||
httpServer = TestBed.get(HttpServer);
|
httpServer = TestBed.get(HttpServer);
|
||||||
service = TestBed.get(SymbolService);
|
|
||||||
server = getTestServer();
|
server = getTestServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user