mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-24 07:06:38 +00:00
Draw interface labels
This commit is contained in:
parent
9fc90bb0eb
commit
a88d829f4d
9
src/app/cartography/shared/models/interface-label.ts
Normal file
9
src/app/cartography/shared/models/interface-label.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export class InterfaceLabel {
|
||||
constructor(
|
||||
public x: number,
|
||||
public y: number,
|
||||
public text: string,
|
||||
public style: string,
|
||||
public rotation = 0,
|
||||
) {}
|
||||
}
|
100
src/app/cartography/shared/widgets/interface-label.spec.ts
Normal file
100
src/app/cartography/shared/widgets/interface-label.spec.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { Selection } from "d3-selection";
|
||||
|
||||
import { TestSVGCanvas } from "../../testing";
|
||||
import { LayersWidget } from "./layers";
|
||||
import { Layer } from "../models/layer";
|
||||
import { Node } from "../models/node";
|
||||
import { Link } from "../models/link";
|
||||
import { InterfaceLabelWidget } from "./interface-label";
|
||||
import { LinkNode } from "../models/link-node";
|
||||
import { Label } from "../models/label";
|
||||
import { InterfaceLabel } from "../models/interface-label";
|
||||
|
||||
|
||||
describe('InterfaceLabelsWidget', () => {
|
||||
let svg: TestSVGCanvas;
|
||||
let widget: InterfaceLabelWidget;
|
||||
let linksEnter: Selection<SVGGElement, Link, SVGGElement, any>;
|
||||
let links: Link[];
|
||||
|
||||
beforeEach(() => {
|
||||
svg = new TestSVGCanvas();
|
||||
|
||||
const node_1 = new Node();
|
||||
node_1.node_id = "1";
|
||||
node_1.x = 100;
|
||||
node_1.y = 200;
|
||||
|
||||
const node_2 = new Node();
|
||||
node_2.node_id = "2";
|
||||
node_2.x = 300;
|
||||
node_2.y = 400;
|
||||
|
||||
const link_node_1 = new LinkNode();
|
||||
link_node_1.label = new Label();
|
||||
link_node_1.label.rotation = 5;
|
||||
link_node_1.label.text = "Interface 1";
|
||||
link_node_1.label.x = 10;
|
||||
link_node_1.label.y = 20;
|
||||
link_node_1.label.style = "font-size: 12px";
|
||||
|
||||
const link_node_2 = new LinkNode();
|
||||
link_node_2.label = new Label();
|
||||
link_node_2.label.rotation = 0;
|
||||
link_node_2.label.text = "Interface 2";
|
||||
link_node_2.label.x = -30;
|
||||
link_node_2.label.y = -40;
|
||||
link_node_1.label.style = "";
|
||||
|
||||
const link_1 = new Link();
|
||||
link_1.link_id = "link1";
|
||||
link_1.source = node_1;
|
||||
link_1.target = node_2;
|
||||
link_1.nodes = [ link_node_1, link_node_2];
|
||||
link_1.link_type = "ethernet";
|
||||
|
||||
links = [link_1];
|
||||
|
||||
const linksSelection = svg.canvas
|
||||
.selectAll<SVGGElement, Link>('g.link')
|
||||
.data(links);
|
||||
|
||||
linksEnter = linksSelection
|
||||
.enter()
|
||||
.append<SVGGElement>('g')
|
||||
.attr('class', 'link');
|
||||
|
||||
linksSelection
|
||||
.exit()
|
||||
.remove();
|
||||
|
||||
widget = new InterfaceLabelWidget();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
svg.destroy();
|
||||
});
|
||||
|
||||
it('should draw interface labels', () => {
|
||||
widget.draw(linksEnter);
|
||||
|
||||
const drew = svg.canvas.selectAll<SVGGElement, InterfaceLabel>('text.interface_label');
|
||||
|
||||
expect(drew.nodes().length).toEqual(2);
|
||||
|
||||
const sourceInterface = drew.nodes()[0];
|
||||
expect(sourceInterface.innerHTML).toEqual('Interface 1');
|
||||
expect(sourceInterface.getAttribute('x')).toEqual('110');
|
||||
expect(sourceInterface.getAttribute('y')).toEqual('220');
|
||||
expect(sourceInterface.getAttribute('transform')).toEqual('rotate(5, 110, 220)');
|
||||
expect(sourceInterface.getAttribute('style')).toEqual('font-size: 12px');
|
||||
|
||||
const targetInterface = drew.nodes()[1];
|
||||
expect(targetInterface.innerHTML).toEqual('Interface 2');
|
||||
expect(targetInterface.getAttribute('x')).toEqual('270');
|
||||
expect(targetInterface.getAttribute('y')).toEqual('360');
|
||||
expect(targetInterface.getAttribute('transform')).toEqual('rotate(0, 270, 360)');
|
||||
expect(sourceInterface.getAttribute('style')).toEqual('');
|
||||
});
|
||||
|
||||
});
|
@ -1,13 +1,32 @@
|
||||
import { SVGSelection } from "../models/types";
|
||||
import { Link } from "../models/link";
|
||||
import { InterfaceLabel } from "../models/interface-label";
|
||||
|
||||
|
||||
export class InterfaceLabelWidget {
|
||||
draw(selection: SVGSelection) {
|
||||
|
||||
const labels = selection
|
||||
.selectAll<SVGTextElement, Link>('text.interface_label')
|
||||
.data((l: Link) => [l]);
|
||||
.selectAll<SVGTextElement, InterfaceLabel>('text.interface_label')
|
||||
.data((l: Link) => {
|
||||
const sourceInterface = new InterfaceLabel(
|
||||
Math.round(l.source.x + l.nodes[0].label.x),
|
||||
Math.round(l.source.y + l.nodes[0].label.y),
|
||||
l.nodes[0].label.text,
|
||||
l.nodes[0].label.style,
|
||||
l.nodes[0].label.rotation
|
||||
);
|
||||
|
||||
const targetInterface = new InterfaceLabel(
|
||||
Math.round(l.target.x + l.nodes[1].label.x),
|
||||
Math.round(l.target.y + l.nodes[1].label.y),
|
||||
l.nodes[1].label.text,
|
||||
l.nodes[1].label.style,
|
||||
l.nodes[1].label.rotation
|
||||
);
|
||||
|
||||
return [sourceInterface, targetInterface];
|
||||
});
|
||||
|
||||
const enter = labels
|
||||
.enter()
|
||||
@ -18,9 +37,11 @@ export class InterfaceLabelWidget {
|
||||
.merge(enter);
|
||||
|
||||
merge
|
||||
.text((l: Link) => l.nodes[0].label.text)
|
||||
.attr('x', (l: Link) => Math.round(l.source.x + l.nodes[0].label.x))
|
||||
.attr('y', (l: Link) => Math.round(l.source.y + l.nodes[0].label.y));
|
||||
.text((l: InterfaceLabel) => l.text)
|
||||
.attr('x', (l: InterfaceLabel) => l.x)
|
||||
.attr('y', (l: InterfaceLabel) => l.y)
|
||||
.attr('style', (l: InterfaceLabel) => l.style)
|
||||
.attr('transform', (l: InterfaceLabel) => `rotate(${l.rotation}, ${l.x}, ${l.y})`);
|
||||
|
||||
labels
|
||||
.exit()
|
||||
|
Loading…
Reference in New Issue
Block a user