Different layers, Ref: #11

This commit is contained in:
ziajka 2018-03-27 16:57:22 +02:00
parent bdbbc0a3f4
commit f03abfe761
8 changed files with 192 additions and 39 deletions

View File

@ -0,0 +1,10 @@
import {Drawing} from "./drawing";
import {Link} from "./link";
import {Node} from "./node";
export class Layer {
index: number;
nodes: Node[];
drawings: Drawing[];
links: Link[];
}

View File

@ -2,6 +2,7 @@ import {Label} from "./label";
import {Port} from "../../../shared/models/port";
import {Selectable} from "../managers/selection-manager";
export class Node implements Selectable {
command_line: string;
compute_id: string;

View File

@ -1,14 +1,20 @@
import {Widget} from "./widget";
import {Drawing} from "../models/drawing";
import {SVGSelection} from "../models/types";
import {Layer} from "../models/layer";
export class DrawingsWidget implements Widget {
constructor() {}
public draw(view: SVGSelection, drawings: Drawing[]) {
const drawing = view.selectAll<SVGGElement, Drawing>('g.drawing')
.data(drawings);
public draw(view: SVGSelection, drawings?: Drawing[]) {
const drawing = view
.selectAll<SVGGElement, Drawing>('g.drawing')
.data((l: Layer) => {
return l.drawings;
}, (d: Drawing) => {
return d.drawing_id;
});
const drawing_enter = drawing.enter()
.append<SVGGElement>('g')
@ -53,8 +59,4 @@ export class DrawingsWidget implements Widget {
drawing.exit().remove();
}
private appendSVG(svg: string) {
}
}

View File

@ -10,6 +10,9 @@ import { DrawingsWidget } from "./drawings.widget";
import { DrawingLineWidget } from "./drawing-line.widget";
import {SelectionTool} from "../tools/selection-tool";
import {MovingTool} from "../tools/moving-tool";
import {LayersWidget} from "./layers.widget";
import {Layer} from "../models/layer";
export class GraphLayout implements Widget {
private nodes: Node[] = [];
@ -22,6 +25,7 @@ export class GraphLayout implements Widget {
private drawingLineTool: DrawingLineWidget;
private selectionTool: SelectionTool;
private movingTool: MovingTool;
private layersWidget: LayersWidget;
private centerZeroZeroPoint = true;
@ -32,6 +36,7 @@ export class GraphLayout implements Widget {
this.drawingLineTool = new DrawingLineWidget();
this.selectionTool = new SelectionTool();
this.movingTool = new MovingTool();
this.layersWidget = new LayersWidget();
}
public setNodes(nodes: Node[]) {
@ -54,6 +59,10 @@ export class GraphLayout implements Widget {
return this.linksWidget;
}
public getDrawingsWidget() {
return this.drawingsWidget;
}
public getDrawingLineTool() {
return this.drawingLineTool;
}
@ -89,9 +98,56 @@ export class GraphLayout implements Widget {
(ctx: Context) => `translate(${ctx.getSize().width / 2}, ${ctx.getSize().height / 2})`);
}
this.linksWidget.draw(canvas, this.links);
this.nodesWidget.draw(canvas, this.nodes);
this.drawingsWidget.draw(canvas, this.drawings);
const layers = {};
this.nodes.forEach((n: Node) => {
const key = n.z.toString();
if (!(key in layers)) {
layers[key] = new Layer();
layers[key].nodes = [];
layers[key].drawings = [];
layers[key].links = [];
}
layers[key].nodes.push(n);
});
this.drawings.forEach((d: Drawing) => {
const key = d.z.toString();
if (!(key in layers)) {
layers[key] = new Layer();
layers[key].nodes = [];
layers[key].drawings = [];
layers[key].links = [];
}
layers[key].drawings.push(d);
});
this.links.forEach((l: Link) => {
if (!l.source || !l.target) {
return;
}
const key = Math.min(l.source.z, l.target.z).toString();
if (!(key in layers)) {
layers[key] = new Layer();
layers[key].nodes = [];
layers[key].drawings = [];
layers[key].links = [];
}
layers[key].links.push(l);
});
const layers_list: Layer[] = Object.keys(layers).sort((a: string, b: string) => {
return Number(a) - Number(b);
}).map((key: string) => {
return layers[key];
});
this.layersWidget.graphLayout = this;
this.layersWidget.draw(canvas, layers_list);
this.drawingLineTool.draw(view, context);
this.selectionTool.draw(view, context);

View File

@ -0,0 +1,38 @@
import { Widget } from "./widget";
import { SVGSelection } from "../models/types";
import { GraphLayout } from "./graph.widget";
import { Layer } from "../models/layer";
export class LayersWidget implements Widget {
public graphLayout: GraphLayout;
public draw(view: SVGSelection, layers: Layer[]) {
const layers_selection = view
.selectAll<SVGGElement, Layer>('g.layer')
.data(layers);
layers_selection
.enter()
.append<SVGGElement>('g')
.attr('class', 'layer')
.attr('data-index', (layer: Layer) => layer.index);
layers_selection
.exit()
.remove();
this.graphLayout
.getNodesWidget()
.draw(layers_selection);
this.graphLayout
.getDrawingsWidget()
.draw(layers_selection);
this.graphLayout
.getLinksWidget()
.draw(layers_selection);
}
}

View File

@ -1,12 +1,13 @@
import {BaseType, select, Selection} from "d3-selection";
import { select } from "d3-selection";
import { Widget } from "./widget";
import { SVGSelection } from "../models/types";
import { Link } from "../models/link";
import { LinkStatus } from "../models/link-status";
import { MultiLinkCalculatorHelper } from "../../map/helpers/multi-link-calculator-helper";
import {SerialLinkWidget} from "./serial-link.widget";
import {EthernetLinkWidget} from "./ethernet-link.widget";
import { SerialLinkWidget } from "./serial-link.widget";
import { EthernetLinkWidget } from "./ethernet-link.widget";
import { Layer } from "../models/layer";
export class LinksWidget implements Widget {
@ -96,29 +97,30 @@ export class LinksWidget implements Widget {
});
}
public draw(view: SVGSelection, links: Link[]) {
const self = this;
this.multiLinkCalculatorHelper.assignDataToLinks(links);
const linksLayer = view.selectAll("g.links").data([{}]);
linksLayer
.enter()
.append<SVGGElement>('g')
.attr("class", "links");
const link = linksLayer
public draw(view: SVGSelection, links?: Link[]) {
const link = view
.selectAll<SVGGElement, Link>("g.link")
.data(links.filter((l: Link) => {
return l.target && l.source;
}));
.data((layer: Layer) => {
console.log(layer.links);
if (layer.links) {
const layer_links = layer.links.filter((l: Link) => {
return l.target && l.source;
});
this.multiLinkCalculatorHelper.assignDataToLinks(layer_links);
return layer_links;
}
return [];
}, (l: Link) => {
return l.link_id;
});
const link_enter = link.enter()
.append<SVGGElement>('g')
.attr('class', 'link')
.attr('link_id', (l: Link) => l.link_id)
.attr('map-source', (l: Link) => l.source.node_id)
.attr('map-target', (l: Link) => l.target.node_id)
.attr('map-target', (l: Link) => l.target.node_id);
const merge = link.merge(link_enter);

View File

@ -1,9 +1,10 @@
import { Widget } from "./widget";
import { Node } from "../models/node";
import { SVGSelection } from "../models/types";
import {event, select} from "d3-selection";
import {event, select, Selection} from "d3-selection";
import {D3DragEvent, drag} from "d3-drag";
import {Symbol} from "../models/symbol";
import {Layer} from "../models/layer";
export class NodesWidget implements Widget {
@ -78,16 +79,23 @@ export class NodesWidget implements Widget {
}
public draw(view: SVGSelection, nodes: Node[]) {
public draw(view: SVGSelection, nodes?: Node[]) {
const self = this;
const node = view
.selectAll<SVGGElement, any>('g.node')
.data(nodes, (n: Node) => {
return n.node_id;
});
let nodes_selection: Selection<SVGGElement, Node, any, any> = view
.selectAll<SVGGElement, Node>('g.node');
const node_enter = node
if (nodes) {
nodes_selection = nodes_selection.data(nodes);
} else {
nodes_selection = nodes_selection.data((l: Layer) => {
return l.nodes;
}, (n: Node) => {
return n.node_id;
});
}
const node_enter = nodes_selection
.enter()
.append<SVGGElement>('g')
.attr('class', 'node');
@ -134,7 +142,7 @@ export class NodesWidget implements Widget {
.attr('y', '0');
}
const node_merge = node
const node_merge = nodes_selection
.merge(node_enter)
.classed('selected', (n: Node) => n.is_selected)
.on("contextmenu", function (n: Node, i: number) {
@ -175,7 +183,7 @@ export class NodesWidget implements Widget {
node_merge.call(dragging());
node
nodes_selection
.exit()
.remove();
}

View File

@ -6,6 +6,11 @@ import { Server } from '../models/server';
import { HttpServer } from './http-server.service';
class MyType {
id: number;
}
describe('HttpServer', () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
@ -44,6 +49,37 @@ describe('HttpServer', () => {
expect(req.request.responseType).toEqual("json");
});
it('should make GET query for get method and return instance of type', () => {
const testData: MyType = {id: 3};
service.get<MyType>(server, '/test').subscribe(data => {
expect(data instanceof MyType).toBeFalsy();
expect(data).toEqual(testData);
});
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v2/test');
expect(req.request.method).toEqual("GET");
expect(req.request.responseType).toEqual("json");
req.flush({id: 3});
});
it('HttpClient should make GET query for get method and return instance of type', () => {
const testData: MyType = {id: 3};
httpClient.get<MyType>('http://localhost/test').subscribe(data => {
// when this condition is true, it would be great
expect(data instanceof MyType).toBeFalsy();
expect(data).toEqual(testData);
});
const req = httpTestingController.expectOne('http://localhost/test');
expect(req.request.method).toEqual("GET");
expect(req.request.responseType).toEqual("json");
req.flush(testData);
});
it('should make GET query for getText method', () => {
service.getText(server, '/test').subscribe();