Serial Link, fixes: #4

This commit is contained in:
ziajka 2017-11-28 10:30:14 +01:00
parent d32c1b6112
commit 5690db42cd
3 changed files with 129 additions and 45 deletions

View File

@ -0,0 +1,32 @@
import {Widget} from "./widget";
import {SVGSelection} from "../../../map/models/types";
import { line } from "d3-shape";
import {Link} from "../models/link.model";
export class EthernetLinkWidget implements Widget {
public draw(view: SVGSelection, link: Link) {
const link_data = [[
[link.source.x, link.source.y],
[link.target.x, link.target.y]
]];
const value_line = line();
let link_path = view.select<SVGPathElement>('path');
if (!link_path.node()) {
link_path = view.append<SVGPathElement>('path');
}
const link_path_data = link_path.data(link_data);
link_path_data
.attr('d', value_line)
.attr('stroke', '#000')
.attr('stroke-width', '2');
}
}

View File

@ -6,11 +6,20 @@ import { SVGSelection } from "../../../map/models/types";
import { Link } from "../models/link.model";
import { LinkStatus } from "../models/link-status.model";
import { MultiLinkCalculatorHelper } from "../../map/helpers/multi-link-calculator-helper";
import {SerialLinkWidget} from "./serial-link.widget";
import {EthernetLinkWidget} from "./ethernet-link.widget";
export class LinksWidget implements Widget {
private multiLinkCalculatorHelper = new MultiLinkCalculatorHelper();
private getLinkWidget(link: Link) {
if (link.link_type === 'serial') {
return new SerialLinkWidget();
}
return new EthernetLinkWidget();
}
public draw(view: SVGSelection, links: Link[]) {
const self = this;
@ -31,64 +40,50 @@ export class LinksWidget implements Widget {
link.merge(link_enter)
.each(function (this: SVGGElement, l: Link) {
const link_data = [[
[l.source.x, l.source.y],
[l.target.x, l.target.y]
]];
const link_group = select<SVGGElement, Link>(this);
const value_line = line();
const link_widget = self.getLinkWidget(l);
let link_path = link_group.select<SVGPathElement>('path');
link_widget.draw(link_group, l);
if (!link_path.node()) {
link_path = link_group.append<SVGPathElement>('path');
}
const link_path = link_group.select<SVGPathElement>('path');
const link_path_data = link_path.data(link_data);
const start_point: SVGPoint = link_path.node().getPointAtLength(50);
const end_point: SVGPoint = link_path.node().getPointAtLength(link_path.node().getTotalLength() - 50);
link_path_data
.attr('d', value_line)
.attr('stroke', '#000')
.attr('stroke-width', '1');
const statuses = [
new LinkStatus(start_point.x, start_point.y, l.source.status),
new LinkStatus(end_point.x, end_point.y, l.target.status)
];
const start_point: SVGPoint = link_path.node().getPointAtLength(50);
const end_point: SVGPoint = link_path.node().getPointAtLength(link_path.node().getTotalLength() - 50);
const status_started = link_group.selectAll<SVGCircleElement, LinkStatus>('circle.status_started')
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started'));
const statuses = [
new LinkStatus(start_point.x, start_point.y, l.source.status),
new LinkStatus(end_point.x, end_point.y, l.target.status)
];
const status_started_enter = status_started.enter().append<SVGCircleElement>('circle');
const status_started = link_group.selectAll<SVGCircleElement, LinkStatus>('circle.status_started')
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'started'));
status_started.merge(status_started_enter)
.attr('class', 'status_started')
.attr('cx', (ls: LinkStatus) => ls.x)
.attr('cy', (ls: LinkStatus) => ls.y)
.attr('r', 4)
.attr('fill', '#2ecc71');
const status_started_enter = status_started.enter().append<SVGCircleElement>('circle');
status_started.exit().remove();
status_started.merge(status_started_enter)
.attr('class', 'status_started')
.attr('cx', (ls: LinkStatus) => ls.x)
.attr('cy', (ls: LinkStatus) => ls.y)
.attr('r', 4)
.attr('fill', '#2ecc71');
const status_stopped = link_group.selectAll<SVGRectElement, LinkStatus>('rect.status_stopped')
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped'));
status_started.exit().remove();
const status_stopped_enter = status_stopped.enter().append<SVGRectElement>('rect');
const STOPPED_STATUS_RECT_WIDTH = 6;
const status_stopped = link_group.selectAll<SVGRectElement, LinkStatus>('rect.status_stopped')
.data(statuses.filter((link_status: LinkStatus) => link_status.status === 'stopped'));
status_stopped.merge(status_stopped_enter)
.attr('class', 'status_stopped')
.attr('x', (ls: LinkStatus) => ls.x - STOPPED_STATUS_RECT_WIDTH / 2.)
.attr('y', (ls: LinkStatus) => ls.y - STOPPED_STATUS_RECT_WIDTH / 2.)
.attr('width', STOPPED_STATUS_RECT_WIDTH)
.attr('height', STOPPED_STATUS_RECT_WIDTH)
.attr('fill', 'red');
const status_stopped_enter = status_stopped.enter().append<SVGRectElement>('rect');
const STOPPED_STATUS_RECT_WIDTH = 6;
status_stopped.merge(status_stopped_enter)
.attr('class', 'status_stopped')
.attr('x', (ls: LinkStatus) => ls.x - STOPPED_STATUS_RECT_WIDTH / 2.)
.attr('y', (ls: LinkStatus) => ls.y - STOPPED_STATUS_RECT_WIDTH / 2.)
.attr('width', STOPPED_STATUS_RECT_WIDTH)
.attr('height', STOPPED_STATUS_RECT_WIDTH)
.attr('fill', 'red');
status_stopped.exit().remove();
status_stopped.exit().remove();
})
.attr('transform', function(l) {

View File

@ -0,0 +1,57 @@
import {Widget} from "./widget";
import {SVGSelection} from "../../../map/models/types";
import {Link} from "../models/link.model";
import { path } from "d3-path";
export class SerialLinkWidget implements Widget {
public draw(view: SVGSelection, link: Link) {
const dx = link.target.x - link.source.x;
const dy = link.target.y - link.source.y;
const vector_angle = Math.atan2(dy, dx);
const rot_angle = -Math.PI / 4.0;
const vect_rot = [
Math.cos(vector_angle + rot_angle),
Math.sin(vector_angle + rot_angle)
];
const angle_source = [
link.source.x + dx / 2.0 + 15 * vect_rot[0],
link.source.y + dy / 2.0 + 15 * vect_rot[1]
];
const angle_target = [
link.target.x - dx / 2.0 - 15 * vect_rot[0],
link.target.y - dy / 2.0 - 15 * vect_rot[1]
];
const line_data = [
[link.source.x, link.source.y],
angle_source,
angle_target,
[link.target.x, link.target.y]
];
let link_path = view.select<SVGPathElement>('path');
if (!link_path.node()) {
link_path = view.append<SVGPathElement>('path');
}
const line_generator = path();
line_generator.moveTo(line_data[0][0], line_data[0][1]);
line_generator.lineTo(line_data[1][0], line_data[1][1]);
line_generator.lineTo(line_data[2][0], line_data[2][1]);
line_generator.lineTo(line_data[3][0], line_data[3][1]);
link_path
.attr('d', line_generator.toString())
.attr('stroke', '#B22222')
.attr('fill', 'none')
.attr('stroke-width', '2');
}
}