diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 65bade96..79b52ee1 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -40,6 +40,7 @@ import { AppComponent } from './app.component';
import { MapComponent } from './cartography/map/map.component';
import { CreateSnapshotDialogComponent, ProjectMapComponent } from './project-map/project-map.component';
import { ServersComponent, AddServerDialogComponent } from './servers/servers.component';
+import { ContextMenuComponent } from './shared/context-menu/context-menu.component';
@NgModule({
@@ -53,6 +54,7 @@ import { ServersComponent, AddServerDialogComponent } from './servers/servers.co
ProjectsComponent,
DefaultLayoutComponent,
ProgressDialogComponent,
+ ContextMenuComponent,
],
imports: [
NgbModule.forRoot(),
diff --git a/src/app/cartography/map/map.component.html b/src/app/cartography/map/map.component.html
index c56fc706..aaf936ff 100644
--- a/src/app/cartography/map/map.component.html
+++ b/src/app/cartography/map/map.component.html
@@ -1 +1,15 @@
+
+
diff --git a/src/app/cartography/map/map.component.scss b/src/app/cartography/map/map.component.scss
index c41075de..194c56d0 100644
--- a/src/app/cartography/map/map.component.scss
+++ b/src/app/cartography/map/map.component.scss
@@ -1,3 +1,7 @@
svg {
display: block;
}
+
+.context-menu {
+ position: absolute;
+}
diff --git a/src/app/cartography/map/map.component.ts b/src/app/cartography/map/map.component.ts
index ca00d3c5..988ad28a 100644
--- a/src/app/cartography/map/map.component.ts
+++ b/src/app/cartography/map/map.component.ts
@@ -1,4 +1,8 @@
-import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChange } from '@angular/core';
+import {
+ ChangeDetectorRef,
+ Component, ElementRef, Input, NgZone, OnChanges, OnDestroy, OnInit, SimpleChange,
+ ViewChild
+} from '@angular/core';
import { D3, D3Service } from 'd3-ng2-service';
import { Selection } from 'd3-selection';
@@ -8,12 +12,22 @@ import { GraphLayout } from "../shared/widgets/graph.widget";
import { Context } from "../../map/models/context";
import { Size } from "../shared/models/size.model";
import { Drawing } from "../shared/models/drawing.model";
+import {MatMenuTrigger} from "@angular/material";
+import {NodeOnContextMenuListener} from "../shared/widgets/nodes.widget";
+import {DomSanitizer} from "@angular/platform-browser";
+class NodeOnContextMenu implements NodeOnContextMenuListener {
+ constructor(private component: MapComponent) {}
+
+ onContextMenu() {
+ this.component.contextMenu.openMenu();
+ }
+}
@Component({
selector: 'app-map',
- templateUrl: '../../map/map.component.html',
- styleUrls: ['../../map/map.component.css']
+ templateUrl: './map.component.html',
+ styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit, OnChanges, OnDestroy {
@Input() nodes: Node[] = [];
@@ -21,10 +35,10 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
@Input() drawings: Drawing[] = [];
@Input() width = 1500;
@Input() height = 600;
- @Input() phylloRadius = 7;
- @Input() pointRadius= 2;
@Input() windowFullSize = true;
+ @ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
+
private d3: D3;
private parentNativeElement: any;
private svg: Selection;
@@ -32,19 +46,25 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
private graphLayout: GraphLayout;
private graphContext: Context;
+ public contextMenuTop;
+ public contextMenuLeft;
+
constructor(protected element: ElementRef,
- protected d3Service: D3Service
+ protected d3Service: D3Service,
+ protected sanitizer: DomSanitizer,
+ protected changeDetector: ChangeDetectorRef
) {
this.d3 = d3Service.getD3();
this.parentNativeElement = element.nativeElement;
+
+ this.contextMenuLeft = this.sanitizer.bypassSecurityTrustStyle("0");
+ this.contextMenuTop = this.sanitizer.bypassSecurityTrustStyle("0");
}
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
if (
(changes['width'] && !changes['width'].isFirstChange()) ||
(changes['height'] && !changes['height'].isFirstChange()) ||
- (changes['phylloRadius'] && !changes['phylloRadius'].isFirstChange()) ||
- (changes['pointRadius'] && !changes['pointRadius'].isFirstChange()) ||
(changes['drawings'] && !changes['drawings'].isFirstChange()) ||
(changes['nodes'] && !changes['nodes'].isFirstChange()) ||
(changes['links'] && !changes['links'].isFirstChange())
@@ -89,7 +109,15 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
this.graphLayout = new GraphLayout();
this.graphLayout.draw(this.svg, this.graphContext);
+ // this.graphLayout.getNodesWidget().setOnContextMenuListener(new NodeOnContextMenu(self));
+ this.graphLayout.getNodesWidget().setOnContextMenuCallback((event: any) => {
+ this.contextMenuLeft = this.sanitizer.bypassSecurityTrustStyle(event.clientX + "px");
+ this.contextMenuTop = this.sanitizer.bypassSecurityTrustStyle(event.clientY + "px");
+ this.changeDetector.detectChanges();
+
+ this.contextMenu.openMenu();
+ });
}
}
diff --git a/src/app/cartography/shared/listeners/node-on-context-menu-listener.ts b/src/app/cartography/shared/listeners/node-on-context-menu-listener.ts
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/src/app/cartography/shared/listeners/node-on-context-menu-listener.ts
@@ -0,0 +1 @@
+
diff --git a/src/app/cartography/shared/widgets/graph.widget.ts b/src/app/cartography/shared/widgets/graph.widget.ts
index d4c59a19..df91ce62 100644
--- a/src/app/cartography/shared/widgets/graph.widget.ts
+++ b/src/app/cartography/shared/widgets/graph.widget.ts
@@ -34,6 +34,10 @@ export class GraphLayout implements Widget {
this.drawings = drawings;
}
+ public getNodesWidget() {
+ return this.nodesWidget;
+ }
+
draw(view: SVGSelection, context: Context) {
const self = this;
@@ -59,7 +63,7 @@ export class GraphLayout implements Widget {
this.linksWidget.draw(canvas, this.links);
this.nodesWidget.draw(canvas, this.nodes);
- this.drawingsWidget.draw(canvas, this.drawings)
+ this.drawingsWidget.draw(canvas, this.drawings);
const onZoom = function(this: SVGSVGElement) {
const e: D3ZoomEvent = event;
diff --git a/src/app/cartography/shared/widgets/nodes.widget.ts b/src/app/cartography/shared/widgets/nodes.widget.ts
index 53489d12..c06c9f05 100644
--- a/src/app/cartography/shared/widgets/nodes.widget.ts
+++ b/src/app/cartography/shared/widgets/nodes.widget.ts
@@ -1,13 +1,31 @@
import {Widget} from "./widget";
import {Node} from "../models/node.model";
import {SVGSelection} from "../../../map/models/types";
+import { event } from "d3-selection";
+import { D3} from "d3-ng2-service";
+
import {D3DragEvent} from "d3-drag";
import {select} from "d3-selection";
+import {isUndefined} from "util";
+export interface NodeOnContextMenuListener {
+ onContextMenu(): void;
+};
export class NodesWidget implements Widget {
+ private onContextMenuListener: NodeOnContextMenuListener;
+ private onContextMenuCallback: (event: any) => void;
+
constructor() {}
+ public setOnContextMenuListener(onContextMenuListener: NodeOnContextMenuListener) {
+ this.onContextMenuListener = onContextMenuListener;
+ }
+
+ public setOnContextMenuCallback(onContextMenuCallback: (event: any) => void) {
+ this.onContextMenuCallback = onContextMenuCallback;
+ }
+
public draw(view: SVGSelection, nodes: Node[]) {
const self = this;
@@ -33,7 +51,17 @@ export class NodesWidget implements Widget {
const node_image = node_enter.append('image')
.attr('xlink:href', (n: Node) => 'data:image/svg+xml;base64,' + btoa(n.icon.raw))
.attr('width', (n: Node) => n.width)
- .attr('height', (n: Node) => n.height);
+ .attr('height', (n: Node) => n.height)
+ .on("contextmenu", function (n: Node, i: number) {
+ // if (self.onContextMenuListener !== ) {
+ // self.onContextMenuListener.onContextMenu();
+ // }
+ console.log(event);
+ event.preventDefault();
+ if (self.onContextMenuCallback !== null) {
+ self.onContextMenuCallback(event);
+ }
+ });
node_enter.append('circle')
.attr('class', 'node_point')
diff --git a/src/app/map/map.component.css b/src/app/map/map.component.css
deleted file mode 100644
index c41075de..00000000
--- a/src/app/map/map.component.css
+++ /dev/null
@@ -1,3 +0,0 @@
-svg {
- display: block;
-}
diff --git a/src/app/map/map.component.html b/src/app/map/map.component.html
deleted file mode 100644
index 5fe8c1c8..00000000
--- a/src/app/map/map.component.html
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/app/shared/context-menu/context-menu.component.html b/src/app/shared/context-menu/context-menu.component.html
new file mode 100644
index 00000000..5c371fb9
--- /dev/null
+++ b/src/app/shared/context-menu/context-menu.component.html
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/app/shared/context-menu/context-menu.component.scss b/src/app/shared/context-menu/context-menu.component.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/src/app/shared/context-menu/context-menu.component.spec.ts b/src/app/shared/context-menu/context-menu.component.spec.ts
new file mode 100644
index 00000000..9343e130
--- /dev/null
+++ b/src/app/shared/context-menu/context-menu.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ContextMenuComponent } from './context-menu.component';
+
+describe('ContextMenuComponent', () => {
+ let component: ContextMenuComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ContextMenuComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ContextMenuComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/context-menu/context-menu.component.ts b/src/app/shared/context-menu/context-menu.component.ts
new file mode 100644
index 00000000..e03e4966
--- /dev/null
+++ b/src/app/shared/context-menu/context-menu.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { MatMenuTrigger } from '@angular/material';
+
+
+@Component({
+ selector: 'app-context-menu',
+ templateUrl: './context-menu.component.html',
+ styleUrls: ['./context-menu.component.scss']
+})
+export class ContextMenuComponent implements OnInit {
+ @ViewChild(MatMenuTrigger) contextMenu: MatMenuTrigger;
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+ openContextMenu(event) {
+ event.preventDefault();
+ this.contextMenu.openMenu();
+ }
+
+}
+