mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-30 05:54:17 +00:00
Draw node label selection
This commit is contained in:
parent
c68a332143
commit
f9d8f0db29
@ -26,7 +26,7 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
const selectedNodes = this.graphDataManager.getNodes().filter((node) => {
|
const selectedNodes = this.graphDataManager.getNodes().filter((node) => {
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y)
|
return this.inRectangleHelper.inRectangle(rectangle, node.x, node.y)
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectedLinks = this.graphDataManager.getLinks().filter((link) => {
|
const selectedLinks = this.graphDataManager.getLinks().filter((link) => {
|
||||||
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y)
|
return this.inRectangleHelper.inRectangle(rectangle, link.x, link.y)
|
||||||
});
|
});
|
||||||
@ -35,7 +35,18 @@ export class SelectionControlComponent implements OnInit, OnDestroy {
|
|||||||
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y)
|
return this.inRectangleHelper.inRectangle(rectangle, drawing.x, drawing.y)
|
||||||
});
|
});
|
||||||
|
|
||||||
const selected = [...selectedNodes, ...selectedLinks, ...selectedDrawings];
|
const selectedLabels = this.graphDataManager.getNodes().filter((node) => {
|
||||||
|
const labelX = node.x + node.label.x;
|
||||||
|
const labelY = node.y + node.label.y;
|
||||||
|
return this.inRectangleHelper.inRectangle(rectangle, labelX, labelY);
|
||||||
|
}).map((node) => node.label);
|
||||||
|
|
||||||
|
const selected = [
|
||||||
|
...selectedNodes,
|
||||||
|
...selectedLinks,
|
||||||
|
...selectedDrawings,
|
||||||
|
...selectedLabels
|
||||||
|
];
|
||||||
|
|
||||||
this.selectionManager.setSelected(selected);
|
this.selectionManager.setSelected(selected);
|
||||||
});
|
});
|
||||||
|
@ -7,13 +7,17 @@ import { MapLabel } from "../../models/map/map-label";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
export class LabelToMapLabelConverter implements Converter<Label, MapLabel> {
|
||||||
convert(label: Label) {
|
convert(label: Label, paramaters?: {[node_id: string]: string}) {
|
||||||
const mapLabel = new MapLabel();
|
const mapLabel = new MapLabel();
|
||||||
mapLabel.rotation = label.rotation;
|
mapLabel.rotation = label.rotation;
|
||||||
mapLabel.style = label.style;
|
mapLabel.style = label.style;
|
||||||
mapLabel.text = label.text;
|
mapLabel.text = label.text;
|
||||||
mapLabel.x = label.x;
|
mapLabel.x = label.x;
|
||||||
mapLabel.y = label.y;
|
mapLabel.y = label.y;
|
||||||
|
if (paramaters !== undefined) {
|
||||||
|
mapLabel.id = paramaters.node_id;
|
||||||
|
mapLabel.nodeId = paramaters.node_id;
|
||||||
|
}
|
||||||
return mapLabel;
|
return mapLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { MapLabel } from "../../models/map/map-label";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MapLabelToLabelConverter implements Converter<MapLabel, Label> {
|
export class MapLabelToLabelConverter implements Converter<MapLabel, Label> {
|
||||||
convert(mapLabel: MapLabel) {
|
convert(mapLabel: MapLabel, paramters?: any) {
|
||||||
const label = new Label();
|
const label = new Label();
|
||||||
label.rotation = mapLabel.rotation;
|
label.rotation = mapLabel.rotation;
|
||||||
label.style = mapLabel.style;
|
label.style = mapLabel.style;
|
||||||
|
@ -23,7 +23,7 @@ export class NodeToMapNodeConverter implements Converter<Node, MapNode> {
|
|||||||
mapNode.consoleHost = node.console_host;
|
mapNode.consoleHost = node.console_host;
|
||||||
mapNode.firstPortName = node.first_port_name;
|
mapNode.firstPortName = node.first_port_name;
|
||||||
mapNode.height = node.height;
|
mapNode.height = node.height;
|
||||||
mapNode.label = this.labelToMapLabel.convert(node.label);
|
mapNode.label = this.labelToMapLabel.convert(node.label, { node_id: node.node_id });
|
||||||
mapNode.name = node.name;
|
mapNode.name = node.name;
|
||||||
mapNode.nodeDirectory = node.node_directory;
|
mapNode.nodeDirectory = node.node_directory;
|
||||||
mapNode.nodeType = node.node_type;
|
mapNode.nodeType = node.node_type;
|
||||||
|
@ -23,8 +23,13 @@ export class SelectionManager {
|
|||||||
|
|
||||||
this.selection = dictItems;
|
this.selection = dictItems;
|
||||||
|
|
||||||
this.selected.emit(selected);
|
if (selected.length > 0) {
|
||||||
this.unselected.emit(unselected);
|
this.selected.emit(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unselected.length > 0) {
|
||||||
|
this.unselected.emit(unselected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSelected(): Indexed[] {
|
public getSelected(): Indexed[] {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
export class MapLabel {
|
import { Indexed } from "../../datasources/map-datasource";
|
||||||
rotation: number;
|
|
||||||
style: string;
|
export class MapLabel implements Indexed {
|
||||||
text: string;
|
id: string;
|
||||||
x: number;
|
rotation: number;
|
||||||
y: number;
|
style: string;
|
||||||
isSelected: boolean;
|
text: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
nodeId: string;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,10 @@ export class NodeWidget implements Widget {
|
|||||||
.append<SVGTextElement>('text')
|
.append<SVGTextElement>('text')
|
||||||
.attr('class', 'label');
|
.attr('class', 'label');
|
||||||
|
|
||||||
|
node_body_enter
|
||||||
|
.append<SVGRectElement>('rect')
|
||||||
|
.attr('class', 'label_selection');
|
||||||
|
|
||||||
const node_body_merge = node_body.merge(node_body_enter)
|
const node_body_merge = node_body.merge(node_body_enter)
|
||||||
.classed('selected', (n: MapNode) => this.selectionManager.isSelected(n))
|
.classed('selected', (n: MapNode) => this.selectionManager.isSelected(n))
|
||||||
.on("contextmenu", function (n: MapNode, i: number) {
|
.on("contextmenu", function (n: MapNode, i: number) {
|
||||||
@ -83,6 +87,7 @@ export class NodeWidget implements Widget {
|
|||||||
|
|
||||||
node_body_merge
|
node_body_merge
|
||||||
.select<SVGTextElement>('text.label')
|
.select<SVGTextElement>('text.label')
|
||||||
|
.attr('label_id', (n: MapNode) => n.label.id)
|
||||||
// .attr('y', (n: Node) => n.label.y - n.height / 2. + 10) // @todo: server computes y in auto way
|
// .attr('y', (n: Node) => n.label.y - n.height / 2. + 10) // @todo: server computes y in auto way
|
||||||
.attr('style', (n: MapNode) => {
|
.attr('style', (n: MapNode) => {
|
||||||
let styles = this.cssFixer.fix(n.label.style);
|
let styles = this.cssFixer.fix(n.label.style);
|
||||||
@ -107,6 +112,28 @@ export class NodeWidget implements Widget {
|
|||||||
return - n.height / 2. - bbox.height ;
|
return - n.height / 2. - bbox.height ;
|
||||||
}
|
}
|
||||||
return n.label.y + bbox.height - NodeWidget.NODE_LABEL_MARGIN;
|
return n.label.y + bbox.height - NodeWidget.NODE_LABEL_MARGIN;
|
||||||
|
})
|
||||||
|
.attr('transform', (node) => {
|
||||||
|
return `rotate(${node.label.rotation}, 0, 0)`;
|
||||||
|
})
|
||||||
|
|
||||||
|
node_body_merge
|
||||||
|
.select<SVGRectElement>('rect.label_selection')
|
||||||
|
.attr('visibility', (n: MapNode) => this.selectionManager.isSelected(n.label) ? 'visible' : 'hidden')
|
||||||
|
.attr('stroke', 'black')
|
||||||
|
.attr('stroke-dasharray', '3,3')
|
||||||
|
.attr('stroke-width', '0.5')
|
||||||
|
.attr('fill', 'none')
|
||||||
|
.each(function (this: SVGRectElement, node: MapNode) {
|
||||||
|
const current = select(this);
|
||||||
|
const textLabel = node_body_merge.select<SVGTextElement>(`text[label_id="${node.label.id}"]`);
|
||||||
|
const bbox = textLabel.node().getBBox();
|
||||||
|
const border = 2;
|
||||||
|
|
||||||
|
current.attr('width', bbox.width + border * 2);
|
||||||
|
current.attr('height', bbox.height + border * 2);
|
||||||
|
current.attr('x', bbox.x - border);
|
||||||
|
current.attr('y', bbox.y - border);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user