mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-16 15:32:51 +00:00
Initial implementation
This commit is contained in:
parent
dea0f58ea0
commit
f469a8dbe1
@ -72,6 +72,7 @@ import { SnapshotMenuItemComponent } from './components/snapshots/snapshot-menu-
|
||||
import { MATERIAL_IMPORTS } from './material.imports';
|
||||
import { DrawingService } from './services/drawing.service';
|
||||
import { ProjectNameValidator } from './components/projects/models/projectNameValidator';
|
||||
import { MatSidenavModule } from '@angular/material';
|
||||
|
||||
|
||||
if (environment.production) {
|
||||
@ -128,6 +129,7 @@ if (environment.production) {
|
||||
PersistenceModule,
|
||||
NgxElectronModule,
|
||||
FileUploadModule,
|
||||
MatSidenavModule,
|
||||
MATERIAL_IMPORTS
|
||||
],
|
||||
providers: [
|
||||
|
@ -5,6 +5,7 @@ import { MatMenuModule, MatIconModule } from '@angular/material';
|
||||
import { MapComponent } from './components/map/map.component';
|
||||
import { DrawLinkToolComponent } from './components/draw-link-tool/draw-link-tool.component';
|
||||
import { NodeSelectInterfaceComponent } from './components/node-select-interface/node-select-interface.component';
|
||||
import { DrawingResizingComponent } from './components/drawing-resizing/drawing-resizing.components';
|
||||
|
||||
import { CssFixer } from './helpers/css-fixer';
|
||||
import { FontFixer } from './helpers/font-fixer';
|
||||
@ -20,6 +21,7 @@ import { MapListeners } from './listeners/map-listeners';
|
||||
import { DraggableListener } from './listeners/draggable-listener';
|
||||
import { DrawingsEventSource } from './events/drawings-event-source';
|
||||
import { NodesEventSource } from './events/nodes-event-source';
|
||||
import { MapDrawingToSvgConverter } from './converters/map/map-drawing-to-svg-converter';
|
||||
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';
|
||||
@ -50,7 +52,8 @@ import { LinksEventSource } from './events/links-event-source';
|
||||
declarations: [
|
||||
MapComponent,
|
||||
DrawLinkToolComponent,
|
||||
NodeSelectInterfaceComponent
|
||||
NodeSelectInterfaceComponent,
|
||||
DrawingResizingComponent
|
||||
],
|
||||
providers: [
|
||||
CssFixer,
|
||||
@ -69,6 +72,7 @@ import { LinksEventSource } from './events/links-event-source';
|
||||
DrawingsEventSource,
|
||||
NodesEventSource,
|
||||
LinksEventSource,
|
||||
MapDrawingToSvgConverter,
|
||||
DrawingToMapDrawingConverter,
|
||||
LabelToMapLabelConverter,
|
||||
LinkToMapLinkConverter,
|
||||
|
@ -0,0 +1,42 @@
|
||||
import { Component, OnInit, ElementRef, OnDestroy, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { DrawingsEventSource } from '../../events/drawings-event-source';
|
||||
import { select } from 'd3-selection';
|
||||
import { DrawingsWidget } from '../../widgets/drawings';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
import { DraggedDataEvent } from '../../events/event-source';
|
||||
import { ResizingEnd } from '../../events/resizing';
|
||||
|
||||
export class DrawingResizedEvent{
|
||||
constructor() {};
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-drawing-resizing',
|
||||
template: `<ng-content></ng-content>`,
|
||||
styleUrls: ['./drawing-resizing.component.scss']
|
||||
})
|
||||
export class DrawingResizingComponent implements OnInit, OnDestroy{
|
||||
private resizingFinished: Subscription;
|
||||
|
||||
@Input('svg') svg: SVGSVGElement;
|
||||
|
||||
constructor(
|
||||
private drawingsWidget: DrawingsWidget,
|
||||
private drawingsEventSource: DrawingsEventSource
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const svg = select(this.svg);
|
||||
|
||||
this.resizingFinished = this.drawingsWidget.resizingFinished.subscribe((evt: ResizingEnd<MapDrawing>) => {
|
||||
console.log("inside component");
|
||||
this.drawingsEventSource.resized.emit(new DraggedDataEvent<MapDrawing>(evt.datum, evt.x, evt.y));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.resizingFinished.unsubscribe();
|
||||
}
|
||||
}
|
@ -7,4 +7,5 @@
|
||||
</filter>
|
||||
</svg>
|
||||
|
||||
<app-draw-link-tool *ngIf="drawLinkTool"></app-draw-link-tool>
|
||||
<app-draw-link-tool *ngIf="drawLinkTool"></app-draw-link-tool>
|
||||
<app-drawing-resizing></app-drawing-resizing>
|
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 281 B |
@ -12,6 +12,7 @@ import { InterfaceLabelWidget } from '../../widgets/interface-label';
|
||||
import { SelectionTool } from '../../tools/selection-tool';
|
||||
import { MovingTool } from '../../tools/moving-tool';
|
||||
import { MapChangeDetectorRef } from '../../services/map-change-detector-ref';
|
||||
import { MapLinkCreated } from '../../events/links';
|
||||
import { CanvasSizeDetector } from '../../helpers/canvas-size-detector';
|
||||
import { MapListeners } from '../../listeners/map-listeners';
|
||||
import { DrawingsWidget } from '../../widgets/drawings';
|
||||
@ -20,6 +21,7 @@ import { Link } from '../../../models/link';
|
||||
import { Drawing } from '../../models/drawing';
|
||||
import { Symbol } from '../../../models/symbol';
|
||||
import { GraphDataManager } from '../../managers/graph-data-manager';
|
||||
import { DraggedDataEvent } from '../../events/event-source';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -36,6 +38,10 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() width = 1500;
|
||||
@Input() height = 600;
|
||||
|
||||
@Output() nodeDragged = new EventEmitter<DraggedDataEvent<Node>>();
|
||||
@Output() drawingDragged = new EventEmitter<DraggedDataEvent<Drawing>>();
|
||||
@Output() onLinkCreated = new EventEmitter<MapLinkCreated>();
|
||||
|
||||
private parentNativeElement: any;
|
||||
private svg: Selection<SVGSVGElement, any, null, undefined>;
|
||||
|
||||
@ -83,6 +89,8 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
@Input('draw-link-tool') drawLinkTool: boolean;
|
||||
|
||||
@Input('is-rectangle-chosen') isRectangleChosen: boolean;
|
||||
|
||||
@Input('readonly') set readonly(value) {
|
||||
this.nodesWidget.draggingEnabled = !value;
|
||||
this.drawingsWidget.draggingEnabled = !value;
|
||||
@ -95,12 +103,16 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
(changes['drawings'] && !changes['drawings'].isFirstChange()) ||
|
||||
(changes['nodes'] && !changes['nodes'].isFirstChange()) ||
|
||||
(changes['links'] && !changes['links'].isFirstChange()) ||
|
||||
(changes['symbols'] && !changes['symbols'].isFirstChange())
|
||||
(changes['symbols'] && !changes['symbols'].isFirstChange() ||
|
||||
(changes['isRectangleChosen'] && !changes['isRectangleChosen'].isFirstChange()))
|
||||
) {
|
||||
if (this.svg.empty && !this.svg.empty()) {
|
||||
if (changes['symbols']) {
|
||||
this.onSymbolsChange(changes['symbols']);
|
||||
}
|
||||
if (changes['isRectangleChosen']){
|
||||
this.onDrawingRectangleActive();
|
||||
}
|
||||
this.changeLayout();
|
||||
}
|
||||
}
|
||||
@ -156,10 +168,46 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.graphDataManager.setNodes(this.nodes);
|
||||
this.graphDataManager.setLinks(this.links);
|
||||
this.graphDataManager.setDrawings(this.drawings);
|
||||
|
||||
this.graphLayout.draw(this.svg, this.context);
|
||||
}
|
||||
|
||||
private onDrawingRectangleActive(){
|
||||
var map = document.getElementsByClassName('map')[0];
|
||||
console.log(this.drawings);
|
||||
|
||||
map.addEventListener('click', (event: MouseEvent) => {
|
||||
console.log(event);
|
||||
|
||||
this.svg.select('g.drawings')
|
||||
.append<SVGElement>('g')
|
||||
.attr("class", 'drawing')
|
||||
.append<SVGGElement>('g')
|
||||
.attr("class", 'drawing_body')
|
||||
.attr('transform', `translate(${event.clientX-1000},${event.clientY-500}) rotate(0)`)
|
||||
.append<SVGRectElement>('rect')
|
||||
.attr('class', 'rect_element noselect')
|
||||
.attr('fill', '#ffffff')
|
||||
.attr('fill-opacity', '1')
|
||||
.attr('stroke', '#000000')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('width', 200)
|
||||
.attr('height', 100);
|
||||
|
||||
let newRectangle = new Drawing;
|
||||
/*drawing_id: string;
|
||||
project_id: string;
|
||||
rotation: number;
|
||||
svg: string;
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
is_selected = false;
|
||||
element: DrawingElement;*/
|
||||
|
||||
//this.onRectangleCreated.emit(null);
|
||||
}, {once : true});
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event) {
|
||||
this.changeLayout();
|
||||
|
@ -0,0 +1,15 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { Converter } from '../converter';
|
||||
import { MapDrawing } from '../../models/map/map-drawing';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class MapDrawingToSvgConverter implements Converter<MapDrawing, string> {
|
||||
constructor(
|
||||
) {}
|
||||
|
||||
convert(mapDrawing: MapDrawing) {
|
||||
return "";
|
||||
}
|
||||
}
|
@ -6,4 +6,5 @@ import { MapDrawing } from "../models/map/map-drawing";
|
||||
@Injectable()
|
||||
export class DrawingsEventSource {
|
||||
public dragged = new EventEmitter<DraggedDataEvent<MapDrawing>>();
|
||||
public resized = new EventEmitter<DraggedDataEvent<MapDrawing>>();
|
||||
}
|
||||
|
@ -7,3 +7,13 @@ export class DataEventSource<T> {
|
||||
}
|
||||
|
||||
export class DraggedDataEvent<T> extends DataEventSource<T> {}
|
||||
|
||||
export class ResizedDataEvent<T> {
|
||||
constructor(
|
||||
public datum: T,
|
||||
public x: number,
|
||||
public y: number,
|
||||
public width: number,
|
||||
public height: number) {
|
||||
}
|
||||
}
|
||||
|
7
src/app/cartography/events/resizing.ts
Normal file
7
src/app/cartography/events/resizing.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export class ResizingEnd<T> {
|
||||
public datum: T;
|
||||
public x: number;
|
||||
public y: number;
|
||||
public width: number;
|
||||
public height: number;
|
||||
}
|
@ -9,7 +9,9 @@ import { RectDrawingWidget } from "./drawings/rect-drawing";
|
||||
import { LineDrawingWidget } from "./drawings/line-drawing";
|
||||
import { EllipseDrawingWidget } from "./drawings/ellipse-drawing";
|
||||
import { MapDrawing } from "../models/map/map-drawing";
|
||||
|
||||
import { drag } from "d3-drag";
|
||||
import { event } from "d3-selection";
|
||||
import { SelectionManager } from "../managers/selection-manager";
|
||||
|
||||
@Injectable()
|
||||
export class DrawingWidget implements Widget {
|
||||
@ -20,7 +22,8 @@ export class DrawingWidget implements Widget {
|
||||
private imageDrawingWidget: ImageDrawingWidget,
|
||||
private rectDrawingWidget: RectDrawingWidget,
|
||||
private lineDrawingWidget: LineDrawingWidget,
|
||||
private ellipseDrawingWidget: EllipseDrawingWidget
|
||||
private ellipseDrawingWidget: EllipseDrawingWidget,
|
||||
private selectionManager: SelectionManager
|
||||
) {
|
||||
this.drawingWidgets = [
|
||||
this.textDrawingWidget,
|
||||
@ -33,17 +36,88 @@ export class DrawingWidget implements Widget {
|
||||
|
||||
public draw(view: SVGSelection) {
|
||||
const drawing_body = view.selectAll<SVGGElement, MapDrawing>("g.drawing_body")
|
||||
.data((l) => [l]);
|
||||
.data((l:MapDrawing) => [l]);
|
||||
|
||||
const drawing_body_enter = drawing_body.enter()
|
||||
.append<SVGGElement>('g')
|
||||
.attr("class", "drawing_body");
|
||||
.attr("class", "drawing_body")
|
||||
|
||||
drawing_body_enter
|
||||
.append<SVGAElement>('line')
|
||||
.attr("class", "top");
|
||||
|
||||
drawing_body_enter
|
||||
.append<SVGAElement>('line')
|
||||
.attr("class", "bottom");
|
||||
|
||||
drawing_body_enter
|
||||
.append<SVGAElement>('line')
|
||||
.attr("class", "right");
|
||||
|
||||
drawing_body_enter
|
||||
.append<SVGAElement>('line')
|
||||
.attr("class", "left");
|
||||
|
||||
const drawing_body_merge = drawing_body.merge(drawing_body_enter)
|
||||
.attr('transform', (d: MapDrawing) => {
|
||||
return `translate(${d.x},${d.y}) rotate(${d.rotation})`;
|
||||
});
|
||||
|
||||
|
||||
drawing_body_merge
|
||||
.select<SVGAElement>('line.top')
|
||||
.attr('stroke', 'transparent')
|
||||
.attr('stroke-width', '8px')
|
||||
// .attr('stroke-dashoffset', '0')
|
||||
// .attr('stroke-dasharray', '3')
|
||||
.attr('x1', '0')
|
||||
.attr('x2', (drawing) => drawing.element.width)
|
||||
.attr('y1', '0')
|
||||
.attr('y2', '0')
|
||||
.attr('draggable', 'true')
|
||||
.attr("cursor", "ns-resize");
|
||||
|
||||
drawing_body_merge
|
||||
.select<SVGAElement>('line.bottom')
|
||||
.attr('stroke', 'transparent')
|
||||
.attr('stroke-width', '8px')
|
||||
// .attr('stroke-dashoffset', '0')
|
||||
// .attr('stroke-dasharray', '3')
|
||||
.attr('x1', '0')
|
||||
.attr('x2', (drawing) => drawing.element.width)
|
||||
.attr('y1', (drawing) => drawing.element.height)
|
||||
.attr('y2', (drawing) => drawing.element.height)
|
||||
.attr('draggable', 'true')
|
||||
.attr("cursor", "ns-resize");
|
||||
|
||||
drawing_body_merge
|
||||
.select<SVGAElement>('line.right')
|
||||
.attr('stroke', 'transparent')
|
||||
.attr('stroke-width', '8px')
|
||||
// .attr('stroke-dashoffset', '0')
|
||||
// .attr('stroke-dasharray', '3')
|
||||
.attr('x1', '0')
|
||||
.attr('x2', '0')
|
||||
.attr('y1', '0')
|
||||
.attr('y2', (drawing) => drawing.element.height)
|
||||
.attr('draggable', 'true')
|
||||
.attr("cursor", "ew-resize");
|
||||
|
||||
drawing_body_merge
|
||||
.select<SVGAElement>('line.left')
|
||||
.attr('stroke', 'transparent')
|
||||
.attr('stroke-width', '8px')
|
||||
// .attr('stroke-dashoffset', '0')
|
||||
// .attr('stroke-dasharray', '3')
|
||||
.attr('x1', (drawing) => drawing.element.width)
|
||||
.attr('x2', (drawing) => drawing.element.width)
|
||||
.attr('y1', '0')
|
||||
.attr('y2', (drawing) => drawing.element.height)
|
||||
.attr('draggable', 'true')
|
||||
.attr("cursor", "ew-resize");
|
||||
|
||||
drawing_body_merge
|
||||
.classed('selected', (n: MapDrawing) => this.selectionManager.isSelected(n));
|
||||
|
||||
this.drawingWidgets.forEach((widget) => {
|
||||
widget.draw(drawing_body_merge);
|
||||
});
|
||||
|
@ -1,18 +1,24 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Injectable, EventEmitter } from "@angular/core";
|
||||
|
||||
import { Widget } from "./widget";
|
||||
import { SVGSelection } from "../models/types";
|
||||
import { Layer } from "../models/layer";
|
||||
import { SvgToDrawingConverter } from "../helpers/svg-to-drawing-converter";
|
||||
import { Draggable } from "../events/draggable";
|
||||
import { Draggable, DraggableDrag, DraggableStart, DraggableEnd } from "../events/draggable";
|
||||
import { DrawingWidget } from "./drawing";
|
||||
import { drag, D3DragEvent } from "d3-drag";
|
||||
import { event } from "d3-selection";
|
||||
import { MapDrawing } from "../models/map/map-drawing";
|
||||
import { Context } from "../models/context";
|
||||
import { EllipseElement } from "../models/drawings/ellipse-element";
|
||||
import { ResizingEnd } from "../events/resizing";
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class DrawingsWidget implements Widget {
|
||||
public draggable = new Draggable<SVGGElement, MapDrawing>();
|
||||
public draggingEnabled = false;
|
||||
public resizingFinished = new EventEmitter<ResizingEnd<MapDrawing>>();
|
||||
|
||||
// public onContextMenu = new EventEmitter<NodeContextMenu>();
|
||||
// public onDrawingClicked = new EventEmitter<NodeClicked>();
|
||||
@ -22,6 +28,7 @@ export class DrawingsWidget implements Widget {
|
||||
constructor(
|
||||
private drawingWidget: DrawingWidget,
|
||||
private svgToDrawingConverter: SvgToDrawingConverter,
|
||||
private context: Context
|
||||
) {
|
||||
this.svgToDrawingConverter = new SvgToDrawingConverter();
|
||||
}
|
||||
@ -62,6 +69,123 @@ export class DrawingsWidget implements Widget {
|
||||
if (this.draggingEnabled) {
|
||||
this.draggable.call(merge);
|
||||
}
|
||||
|
||||
let bottom = drag()
|
||||
.on('start', (datum: MapDrawing) => {
|
||||
document.body.style.cursor = "ns-resize";
|
||||
})
|
||||
.on('drag', (datum: MapDrawing) => {
|
||||
const evt = event;
|
||||
|
||||
if (datum.element instanceof EllipseElement){
|
||||
(datum.element as EllipseElement).cy = (datum.element as EllipseElement).cy + evt.dy/2 < 0 ? 1 : (datum.element as EllipseElement).cy += evt.dy/2;
|
||||
(datum.element as EllipseElement).ry = (datum.element as EllipseElement).ry + evt.dy/2 < 0 ? 1 : (datum.element as EllipseElement).ry += evt.dy/2;
|
||||
}
|
||||
datum.element.height = (datum.element.height + evt.dy) < 0 ? 1: datum.element.height += evt.dy;
|
||||
this.redrawDrawing(view, datum);
|
||||
})
|
||||
.on('end', (datum: MapDrawing) => {
|
||||
document.body.style.cursor = "initial";
|
||||
|
||||
const evt = new ResizingEnd<MapDrawing>();
|
||||
evt.x = datum.x;
|
||||
evt.y = datum. y;
|
||||
evt.width = datum.element.width;
|
||||
evt.height = datum.element.height;
|
||||
evt.datum = datum;
|
||||
|
||||
this.resizingFinished.emit(evt);
|
||||
});
|
||||
|
||||
let y: number;
|
||||
let dy: number;
|
||||
let top = drag()
|
||||
.on('start', () => {
|
||||
y = event.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
|
||||
document.body.style.cursor = "ns-resize";
|
||||
})
|
||||
.on('drag', (datum: MapDrawing) => {
|
||||
const evt = event;
|
||||
dy = y - (evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y);
|
||||
y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
|
||||
|
||||
if ((datum.element.height + dy) < 0){
|
||||
datum.element.height = 1;
|
||||
} else {
|
||||
datum.y = evt.sourceEvent.clientY - this.context.getZeroZeroTransformationPoint().y;
|
||||
datum.element.height += dy;
|
||||
if (datum.element instanceof EllipseElement) {
|
||||
(datum.element as EllipseElement).cy = (datum.element as EllipseElement).cy + dy/2 < 0 ? 1 : (datum.element as EllipseElement).cy += dy/2;
|
||||
(datum.element as EllipseElement).ry = (datum.element as EllipseElement).ry + dy/2 < 0 ? 1 : (datum.element as EllipseElement).ry += dy/2;
|
||||
}
|
||||
}
|
||||
this.redrawDrawing(view, datum);
|
||||
})
|
||||
.on('end', (datum: MapDrawing) => {
|
||||
document.body.style.cursor = "initial";
|
||||
});
|
||||
|
||||
let x: number;
|
||||
let dx: number;
|
||||
let right = drag()
|
||||
.on('start', () => {
|
||||
x = event.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
|
||||
document.body.style.cursor = "ew-resize";
|
||||
})
|
||||
.on('drag', (datum: MapDrawing) => {
|
||||
const evt = event;
|
||||
dx = x - (evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x);
|
||||
x = evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
|
||||
|
||||
if ((datum.element.width + dx) < 0){
|
||||
datum.element.width = 1;
|
||||
} else {
|
||||
datum.x = evt.sourceEvent.clientX - this.context.getZeroZeroTransformationPoint().x;
|
||||
datum.element.width += dx;
|
||||
if (datum.element instanceof EllipseElement) {
|
||||
(datum.element as EllipseElement).cx = (datum.element as EllipseElement).cx + dx/2 < 0 ? 1 : (datum.element as EllipseElement).cx += dx/2;
|
||||
(datum.element as EllipseElement).rx = (datum.element as EllipseElement).rx + dx/2 < 0 ? 1 : (datum.element as EllipseElement).rx += dx/2;
|
||||
}
|
||||
}
|
||||
this.redrawDrawing(view, datum);
|
||||
})
|
||||
.on('end', (datum: MapDrawing) => {
|
||||
document.body.style.cursor = "initial";
|
||||
});
|
||||
|
||||
let left = drag()
|
||||
.on('start', () => {
|
||||
document.body.style.cursor = "ew-resize";
|
||||
})
|
||||
.on('drag', (datum: MapDrawing) => {
|
||||
const evt = event;
|
||||
|
||||
if (datum.element instanceof EllipseElement){
|
||||
(datum.element as EllipseElement).cx = (datum.element as EllipseElement).cx + evt.dx/2 < 0 ? 1 : (datum.element as EllipseElement).cx += evt.dx/2;
|
||||
(datum.element as EllipseElement).rx = (datum.element as EllipseElement).rx + evt.dx/2 < 0 ? 1 : (datum.element as EllipseElement).rx += evt.dx/2;
|
||||
}
|
||||
datum.element.width = (datum.element.width + evt.dx) < 0 ? 1 : datum.element.width += evt.dx;
|
||||
this.redrawDrawing(view, datum);
|
||||
})
|
||||
.on('end', (datum: MapDrawing) => {
|
||||
document.body.style.cursor = "initial";
|
||||
});
|
||||
|
||||
merge
|
||||
.select<SVGAElement>('line.bottom')
|
||||
.call(bottom);
|
||||
|
||||
merge
|
||||
.select<SVGAElement>('line.top')
|
||||
.call(top);
|
||||
|
||||
merge
|
||||
.select<SVGAElement>('line.right')
|
||||
.call(right);
|
||||
|
||||
merge
|
||||
.select<SVGAElement>('line.left')
|
||||
.call(left);
|
||||
}
|
||||
|
||||
private selectDrawing(view: SVGSelection, drawing: MapDrawing) {
|
||||
|
@ -19,7 +19,7 @@ export class RectDrawingWidget implements DrawingShapeWidget {
|
||||
.data((d: MapDrawing) => {
|
||||
return (d.element && d.element instanceof RectElement) ? [d.element] : [];
|
||||
});
|
||||
|
||||
|
||||
const drawing_enter = drawing
|
||||
.enter()
|
||||
.append<SVGRectElement>('rect')
|
||||
|
@ -18,6 +18,69 @@ g.node:hover {
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.draw-menu{
|
||||
position: fixed;
|
||||
background: transparent;
|
||||
top: 20px;
|
||||
left: 92px;
|
||||
width: 320px !important;
|
||||
height: 72px !important;
|
||||
}
|
||||
|
||||
.draw-menu2{
|
||||
position: fixed;
|
||||
background: transparent;
|
||||
top: 20px;
|
||||
left: 92px;
|
||||
width: 320px !important;
|
||||
height: 72px !important;
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.draw-menu button{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.drawer-container{
|
||||
height: 72px !important;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.drawer{
|
||||
width: 320px !important;
|
||||
height: 72px !important;
|
||||
background:#263238;
|
||||
}
|
||||
|
||||
.drawer-content{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.drawer-button{
|
||||
height: 72px;
|
||||
width: 64px!important;
|
||||
background: #263238;
|
||||
padding: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.drawer-arrow-button{
|
||||
width: 40px;
|
||||
height: 72px;
|
||||
padding-top: 16px;
|
||||
background:#263238;
|
||||
position: fixed;
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.drawer-buttons{
|
||||
background:#263238;
|
||||
padding-top: 16px;
|
||||
height: 72px;
|
||||
}
|
||||
|
||||
.project-toolbar .mat-toolbar-multiple-rows {
|
||||
width: auto !important;
|
||||
}
|
||||
@ -41,6 +104,10 @@ svg.map image:hover, svg.map image.chosen, g.selected {
|
||||
filter: url("#grayscale"); /* Chrome doesn't support CSS filters on SVG */
|
||||
}
|
||||
|
||||
g.selected line {
|
||||
stroke: black;
|
||||
}
|
||||
|
||||
path.selected {
|
||||
stroke: darkred;
|
||||
}
|
||||
|
@ -11,6 +11,11 @@
|
||||
[moving-tool]="tools.moving"
|
||||
[draw-link-tool]="tools.draw_link"
|
||||
[readonly]="inReadOnlyMode"
|
||||
[is-rectangle-chosen]="drawTools.isRectangleChosen"
|
||||
(nodeDragged)="onNodeDragged($event)"
|
||||
(drawingDragged)="onDrawingDragged($event)"
|
||||
(onLinkCreated)="onLinkCreated($event)"
|
||||
(onDrawingResized)="onDrawingResized($event)"
|
||||
></app-map>
|
||||
<div class="project-toolbar">
|
||||
<mat-toolbar color="primary" class="project-toolbar">
|
||||
@ -77,6 +82,42 @@
|
||||
</mat-toolbar>
|
||||
</div>
|
||||
|
||||
<div class="draw-menu">
|
||||
<mat-drawer-container class="drawer-container">
|
||||
<mat-drawer #drawer class="drawer">
|
||||
<div class="drawer-buttons">
|
||||
<button mat-icon-button class="drawer-button">
|
||||
<mat-icon>picture_in_picture</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button class="drawer-button" (click)="drawRectangle()">
|
||||
<mat-icon>crop_3_2</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button class="drawer-button">
|
||||
<mat-icon>panorama_fish_eye</mat-icon>
|
||||
<!-- <svg height="72" width="64">
|
||||
<circle cx="32" cy="36" r="20" stroke="white" stroke-width="2" fill="transparent"/>
|
||||
</svg> -->
|
||||
</button>
|
||||
<button mat-icon-button class="drawer-button">
|
||||
<svg height="40" width="40">
|
||||
<line x1="30" y1="10" x2="10" y2="30" style="stroke:white;stroke-width:2" />
|
||||
</svg>
|
||||
</button>
|
||||
<button mat-icon-button class="drawer-arrow-button" (click)="drawer.toggle()">
|
||||
<mat-icon>keyboard_arrow_left</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-drawer>
|
||||
<mat-drawer-content class="drawer-content">
|
||||
<div class="drawer-arrow-button">
|
||||
<button mat-icon-button (click)="drawer.toggle()">
|
||||
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</mat-drawer-content>
|
||||
</mat-drawer-container>
|
||||
</div>
|
||||
|
||||
<app-node-context-menu [project]="project" [server]="server"></app-node-context-menu>
|
||||
</div>
|
||||
|
||||
|
@ -37,6 +37,7 @@ import { MapNode } from '../../cartography/models/map/map-node';
|
||||
import { LinksEventSource } from '../../cartography/events/links-event-source';
|
||||
import { MapDrawing } from '../../cartography/models/map/map-drawing';
|
||||
import { MapPortToPortConverter } from '../../cartography/converters/map/map-port-to-port-converter';
|
||||
import { MapDrawingToSvgConverter } from '../../cartography/converters/map/map-drawing-to-svg-converter';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -62,6 +63,10 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
'draw_link': false
|
||||
};
|
||||
|
||||
protected drawTools = {
|
||||
'isRectangleChosen': false
|
||||
};
|
||||
|
||||
private inReadOnlyMode = false;
|
||||
|
||||
@ViewChild(MapComponent) mapChild: MapComponent;
|
||||
@ -89,7 +94,8 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
private drawingsDataSource: DrawingsDataSource,
|
||||
private nodesEventSource: NodesEventSource,
|
||||
private drawingsEventSource: DrawingsEventSource,
|
||||
private linksEventSource: LinksEventSource
|
||||
private linksEventSource: LinksEventSource,
|
||||
private mapDrawingToSvgConverter: MapDrawingToSvgConverter
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -164,6 +170,10 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
this.drawingsEventSource.dragged.subscribe((evt) => this.onDrawingDragged(evt))
|
||||
);
|
||||
|
||||
this.subscriptions.push(
|
||||
this.drawingsEventSource.resized.subscribe((evt) => this.onDrawingResized(evt))
|
||||
);
|
||||
|
||||
this.subscriptions.push(
|
||||
this.linksEventSource.created.subscribe((evt) => this.onLinkCreated(evt))
|
||||
);
|
||||
@ -272,6 +282,25 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
private onDrawingResized(resizedEvent: DraggedDataEvent<MapDrawing>) {
|
||||
console.log("ready to save");
|
||||
|
||||
const drawing = this.drawingsDataSource.get(resizedEvent.datum.id);
|
||||
console.log(resizedEvent.datum.svg);
|
||||
|
||||
let svgString = this.mapDrawingToSvgConverter.convert(resizedEvent.datum);
|
||||
console.log(resizedEvent.datum);
|
||||
|
||||
/*
|
||||
this.drawingService
|
||||
.updatePosition(this.server, drawing, drawing.x, drawing.y)
|
||||
.subscribe((serverDrawing: Drawing) => {
|
||||
//this.drawingsDataSource.update(serverDrawing);
|
||||
//<svg height="100" width="198"><rect fill="#ffffff" fill-opacity="1.0" height="100" stroke="#000000" stroke-width="2" width="198" /></svg>
|
||||
console.log(serverDrawing.svg);
|
||||
});*/
|
||||
}
|
||||
|
||||
public set readonly(value) {
|
||||
this.inReadOnlyMode = value;
|
||||
if (value) {
|
||||
@ -296,10 +325,18 @@ export class ProjectMapComponent implements OnInit, OnDestroy {
|
||||
this.tools.draw_link = !this.tools.draw_link;
|
||||
}
|
||||
|
||||
public onRectangleCreated(rectangleCreated: any) {
|
||||
this.drawTools.isRectangleChosen = false;
|
||||
}
|
||||
|
||||
public toggleShowInterfaceLabels(enabled: boolean) {
|
||||
this.project.show_interface_labels = enabled;
|
||||
}
|
||||
|
||||
public drawRectangle() {
|
||||
this.drawTools.isRectangleChosen = !this.drawTools.isRectangleChosen;
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.drawingsDataSource.clear();
|
||||
this.nodesDataSource.clear();
|
||||
|
Loading…
x
Reference in New Issue
Block a user