LayersManager

This commit is contained in:
ziajka 2018-03-28 16:20:00 +02:00
parent e2779620d3
commit c75f8ce459
8 changed files with 155 additions and 52 deletions

View File

@ -6,7 +6,7 @@ import {select, Selection} from 'd3-selection';
import { Node } from "../shared/models/node";
import { Link } from "../shared/models/link";
import { GraphLayout } from "../shared/widgets/graph";
import { GraphLayout } from "../shared/widgets/graph-layout";
import { Context } from "../shared/models/context";
import { Size } from "../shared/models/size";
import { Drawing } from "../shared/models/drawing";

View File

@ -0,0 +1,76 @@
import { LayersManager } from "./layers-manager";
import { Node } from "../models/node";
import { Drawing } from "../models/drawing";
import { Link } from "../models/link";
describe('LayersManager', () => {
let manager: LayersManager;
beforeEach(() => {
manager = new LayersManager();
});
it('nodes should be added', () => {
const node_1 = new Node();
node_1.z = 1;
const node_2 = new Node();
node_2.z = 2;
manager.setNodes([node_1, node_2]);
const layers = manager.getLayersList();
expect(layers.length).toEqual(2);
expect(layers[0].nodes.length).toEqual(1);
expect(layers[0].index).toEqual(1);
expect(layers[1].nodes.length).toEqual(1);
expect(layers[1].index).toEqual(2);
});
it('drawings should be added', () => {
const drawing_1 = new Drawing();
drawing_1.z = 1;
const drawing_2 = new Drawing();
drawing_2.z = 2;
manager.setDrawings([drawing_1, drawing_2]);
const layers = manager.getLayersList();
expect(layers.length).toEqual(2);
expect(layers[0].drawings.length).toEqual(1);
expect(layers[0].index).toEqual(1);
expect(layers[1].drawings.length).toEqual(1);
expect(layers[1].index).toEqual(2);
});
it('links should be added', () => {
const node_1 = new Node();
node_1.z = 1;
const node_2 = new Node();
node_2.z = 2;
const link_1 = new Link();
link_1.source = node_1;
link_1.target = node_1;
const link_2 = new Link();
link_2.source = node_1;
link_2.target = node_1;
manager.setLinks([link_1, link_2]);
const layers = manager.getLayersList();
expect(layers.length).toEqual(1);
expect(layers[0].links.length).toEqual(2);
expect(layers[0].index).toEqual(1);
});
it('layers should be cleared', () => {
const node_1 = new Node();
node_1.z = 1;
const node_2 = new Node();
node_2.z = 2;
manager.setNodes([node_1, node_2]);
manager.clear();
expect(manager.getLayersList().length).toEqual(0);
});
});

View File

@ -0,0 +1,60 @@
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";
export class LayersManager {
private layers: Dictionary<Layer>;
constructor() {
this.layers = {};
}
public getLayersList(): Layer[] {
return Object.keys(this.layers).sort((a: string, b: string) => {
return Number(a) - Number(b);
}).map((key: string) => {
return this.layers[key];
});
}
public setNodes(nodes: Node[]) {
nodes
.forEach((node: Node) => {
const layer = this.getLayerForKey(node.z.toString());
layer.nodes.push(node);
});
}
public setDrawings(drawings: Drawing[]) {
drawings
.forEach((drawing: Drawing) => {
const layer = this.getLayerForKey(drawing.z.toString());
layer.drawings.push(drawing);
});
}
public setLinks(links: Link[]) {
links
.filter((link: Link) => link.source && link.target)
.forEach((link: Link) => {
const key = Math.min(link.source.z, link.target.z).toString();
const layer = this.getLayerForKey(key);
layer.links.push(link);
});
}
public clear() {
this.layers = {};
}
public getLayerForKey(key: string): Layer {
if (!(key in this.layers)) {
this.layers[key] = new Layer();
this.layers[key].index = Number(key);
}
return this.layers[key];
}
}

View File

@ -7,4 +7,10 @@ export class Layer {
nodes: Node[];
drawings: Drawing[];
links: Link[];
constructor() {
this.nodes = [];
this.drawings = [];
this.links = [];
}
}

View File

@ -1,3 +1,7 @@
import {BaseType, Selection} from "d3-selection";
export type SVGSelection = Selection<SVGElement, any, BaseType, any>;
export interface Dictionary<T> {
[Key: string]: T;
}

View File

@ -11,7 +11,7 @@ import { DrawingLineWidget } from "./drawing-line";
import { SelectionTool } from "../tools/selection-tool";
import { MovingTool } from "../tools/moving-tool";
import { LayersWidget } from "./layers";
import { Layer } from "../models/layer";
import { LayersManager } from "../managers/layers-manager";
export class GraphLayout implements Widget {
@ -98,56 +98,13 @@ export class GraphLayout implements Widget {
(ctx: Context) => `translate(${ctx.getSize().width / 2}, ${ctx.getSize().height / 2})`);
}
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];
});
const layersManager = new LayersManager();
layersManager.setNodes(this.nodes);
layersManager.setDrawings(this.drawings);
layersManager.setLinks(this.links);
this.layersWidget.graphLayout = this;
this.layersWidget.draw(canvas, layers_list);
this.layersWidget.draw(canvas, layersManager.getLayersList());
this.drawingLineTool.draw(view, context);
this.selectionTool.draw(view, context);

View File

@ -6,7 +6,7 @@ import { Layer } from "../models/layer";
import { LinksWidget } from "./links";
import { NodesWidget } from "./nodes";
import { DrawingsWidget } from "./drawings";
import { GraphLayout } from "./graph";
import { GraphLayout } from "./graph-layout";
describe('LayersWidget', () => {

View File

@ -1,6 +1,6 @@
import { Widget } from "./widget";
import { SVGSelection } from "../models/types";
import { GraphLayout } from "./graph";
import { GraphLayout } from "./graph-layout";
import { Layer } from "../models/layer";