mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-19 04:57:51 +00:00
Drawings, ref. #10
This commit is contained in:
parent
5690db42cd
commit
2eb7246f87
@ -7,6 +7,7 @@ import { Link } from "../shared/models/link.model";
|
||||
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";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -17,6 +18,7 @@ import { Size } from "../shared/models/size.model";
|
||||
export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input() nodes: Node[] = [];
|
||||
@Input() links: Link[] = [];
|
||||
@Input() drawings: Drawing[] = [];
|
||||
@Input() width = 1500;
|
||||
@Input() height = 600;
|
||||
@Input() phylloRadius = 7;
|
||||
@ -43,6 +45,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
(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())
|
||||
) {
|
||||
@ -115,6 +118,7 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
this.graphLayout.setNodes(this.nodes);
|
||||
this.graphLayout.setLinks(this.links);
|
||||
this.graphLayout.setDrawings(this.drawings);
|
||||
|
||||
this.redraw();
|
||||
}
|
||||
|
9
src/app/cartography/shared/models/drawing.model.ts
Normal file
9
src/app/cartography/shared/models/drawing.model.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export class Drawing {
|
||||
drawing_id: string;
|
||||
project_id: string;
|
||||
rotation: number;
|
||||
svg: string;
|
||||
x: number;
|
||||
y: number;
|
||||
z: number;
|
||||
}
|
60
src/app/cartography/shared/widgets/drawings.widget.ts
Normal file
60
src/app/cartography/shared/widgets/drawings.widget.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import {Widget} from "./widget";
|
||||
import {Drawing} from "../models/drawing.model";
|
||||
import {SVGSelection} from "../../../map/models/types";
|
||||
|
||||
|
||||
export class DrawingsWidget implements Widget {
|
||||
constructor() {}
|
||||
|
||||
public draw(view: SVGSelection, drawings: Drawing[]) {
|
||||
const drawing = view.selectAll<SVGGElement, Drawing>('g.drawing')
|
||||
.data(drawings);
|
||||
|
||||
const drawing_enter = drawing.enter()
|
||||
.append<SVGGElement>('g')
|
||||
.attr('class', 'drawing');
|
||||
|
||||
const parser = new DOMParser();
|
||||
|
||||
const drawing_image = drawing_enter.append<SVGImageElement>('image')
|
||||
.attr('xlink:href', (d: Drawing) => {
|
||||
let svg = d.svg;
|
||||
if (svg.indexOf("xmlns") < 0) {
|
||||
svg = svg.replace('svg', 'svg xmlns="http://www.w3.org/2000/svg"');
|
||||
}
|
||||
|
||||
return 'data:image/svg+xml;base64,' + btoa(svg);
|
||||
})
|
||||
.attr('width', (d: Drawing) => {
|
||||
const svg_dom = parser.parseFromString(d.svg, 'text/xml');
|
||||
const roots = svg_dom.getElementsByTagName('svg');
|
||||
if (roots.length > 0) {
|
||||
if (roots[0].hasAttribute('width')) {
|
||||
return roots[0].getAttribute('width');
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.attr('height', (d: Drawing) => {
|
||||
const svg_dom = parser.parseFromString(d.svg, 'text/xml');
|
||||
const roots = svg_dom.getElementsByTagName('svg');
|
||||
if (roots.length > 0) {
|
||||
if (roots[0].hasAttribute('height')) {
|
||||
return roots[0].getAttribute('height');
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
const drawing_merge = drawing.merge(drawing_enter)
|
||||
.attr('transform', (d: Drawing) => {
|
||||
return `translate(${d.x},${d.y})`;
|
||||
});
|
||||
|
||||
drawing.exit().remove();
|
||||
}
|
||||
|
||||
private appendSVG(svg: string) {
|
||||
|
||||
}
|
||||
}
|
@ -7,14 +7,18 @@ import { SVGSelection } from "../../../map/models/types";
|
||||
import { LinksWidget } from "./links.widget";
|
||||
import { D3ZoomEvent, zoom } from "d3-zoom";
|
||||
import { event } from "d3-selection";
|
||||
import {Drawing} from "../models/drawing.model";
|
||||
import {DrawingsWidget} from "./drawings.widget";
|
||||
|
||||
export class GraphLayout implements Widget {
|
||||
|
||||
private nodes: Node[] = [];
|
||||
private links: Link[] = [];
|
||||
private drawings: Drawing[] = [];
|
||||
|
||||
private nodesWidget = new NodesWidget();
|
||||
private linksWidget = new LinksWidget();
|
||||
private drawingsWidget = new DrawingsWidget();
|
||||
|
||||
private centerZeroZeroPoint = true;
|
||||
|
||||
@ -26,42 +30,46 @@ export class GraphLayout implements Widget {
|
||||
this.links = links;
|
||||
}
|
||||
|
||||
public setDrawings(drawings: Drawing[]) {
|
||||
this.drawings = drawings;
|
||||
}
|
||||
|
||||
draw(view: SVGSelection, context: Context) {
|
||||
const self = this;
|
||||
|
||||
const drawing = view
|
||||
.selectAll<SVGGElement, Context>('g.drawing')
|
||||
const canvas = view
|
||||
.selectAll<SVGGElement, Context>('g.canvas')
|
||||
.data([context]);
|
||||
|
||||
const drawingEnter = drawing.enter()
|
||||
const canvasEnter = canvas.enter()
|
||||
.append<SVGGElement>('g')
|
||||
.attr('class', 'drawing');
|
||||
.attr('class', 'canvas');
|
||||
|
||||
if (this.centerZeroZeroPoint) {
|
||||
drawing.attr(
|
||||
canvas.attr(
|
||||
'transform',
|
||||
(ctx: Context) => `translate(${ctx.getSize().width / 2}, ${ctx.getSize().height / 2})`);
|
||||
}
|
||||
|
||||
const links = drawingEnter.append<SVGGElement>('g')
|
||||
.attr('class', 'links');
|
||||
// const links = canvasEnter.append<SVGGElement>('g')
|
||||
// .attr('class', 'links');
|
||||
//
|
||||
// const nodes = canvasEnter.append<SVGGElement>('g')
|
||||
// .attr('class', 'nodes');
|
||||
|
||||
const nodes = drawingEnter.append<SVGGElement>('g')
|
||||
.attr('class', 'nodes');
|
||||
|
||||
this.linksWidget.draw(drawing, this.links);
|
||||
this.nodesWidget.draw(drawing, this.nodes);
|
||||
this.linksWidget.draw(canvas, this.links);
|
||||
this.nodesWidget.draw(canvas, this.nodes);
|
||||
this.drawingsWidget.draw(canvas, this.drawings)
|
||||
|
||||
const onZoom = function(this: SVGSVGElement) {
|
||||
const e: D3ZoomEvent<SVGSVGElement, any> = event;
|
||||
if (self.centerZeroZeroPoint) {
|
||||
drawing.attr(
|
||||
canvas.attr(
|
||||
'transform',
|
||||
`translate(${context.getSize().width / 2 + e.transform.x}, ` +
|
||||
`${context.getSize().height / 2 + e.transform.y}) scale(${e.transform.k})`);
|
||||
} else {
|
||||
drawing.attr('transform', e.transform.toString());
|
||||
canvas.attr('transform', e.transform.toString());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1 +1 @@
|
||||
<svg preserveAspectRatio="none"></svg>
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none"></svg>
|
||||
|
Before Width: | Height: | Size: 39 B After Width: | Height: | Size: 83 B |
@ -1,5 +1,5 @@
|
||||
<div *ngIf="project" class="project-map">
|
||||
<app-map [nodes]="nodes" [links]="links"></app-map>
|
||||
<app-map [nodes]="nodes" [links]="links" [drawings]="drawings"></app-map>
|
||||
|
||||
<div class="project-toolbar">
|
||||
<mat-toolbar color="primary" class="project-toolbar">
|
||||
|
@ -25,6 +25,7 @@ import { Snapshot } from "../shared/models/snapshot";
|
||||
import { ProgressDialogService } from "../shared/progress-dialog/progress-dialog.service";
|
||||
import { ProgressDialogComponent } from "../shared/progress-dialog/progress-dialog.component";
|
||||
import { ToastyService } from "ng2-toasty";
|
||||
import {Drawing} from "../cartography/shared/models/drawing.model";
|
||||
|
||||
|
||||
@Component({
|
||||
@ -36,6 +37,7 @@ import { ToastyService } from "ng2-toasty";
|
||||
export class ProjectMapComponent implements OnInit {
|
||||
public nodes: Node[] = [];
|
||||
public links: Link[] = [];
|
||||
public drawings: Drawing[] = [];
|
||||
|
||||
project: Project;
|
||||
server: Server;
|
||||
@ -86,6 +88,10 @@ export class ProjectMapComponent implements OnInit {
|
||||
this.symbolService
|
||||
.load(this.server)
|
||||
.flatMap(() => {
|
||||
return this.projectService.drawings(this.server, project.project_id);
|
||||
})
|
||||
.flatMap((drawings: Drawing[]) => {
|
||||
this.drawings = drawings;
|
||||
return this.projectService.links(this.server, project.project_id);
|
||||
})
|
||||
.flatMap((links: Link[]) => {
|
||||
|
@ -7,6 +7,7 @@ import 'rxjs/add/operator/map';
|
||||
import { Link } from "../../cartography/shared/models/link.model";
|
||||
import { Server } from "../models/server";
|
||||
import { HttpServer } from "./http-server.service";
|
||||
import {Drawing} from "../../cartography/shared/models/drawing.model";
|
||||
|
||||
@Injectable()
|
||||
export class ProjectService {
|
||||
@ -43,6 +44,12 @@ export class ProjectService {
|
||||
.map(response => response.json() as Link[]);
|
||||
}
|
||||
|
||||
drawings(server: Server, project_id: string): Observable<Drawing[]> {
|
||||
return this.httpServer
|
||||
.get(server, `/projects/${project_id}/drawings`)
|
||||
.map(response => response.json() as Drawing[]);
|
||||
}
|
||||
|
||||
delete(server: Server, project_id: string): Observable<any> {
|
||||
return this.httpServer
|
||||
.delete(server, `/projects/${project_id}`);
|
||||
|
Loading…
Reference in New Issue
Block a user