This commit is contained in:
crusader 2018-09-13 15:08:16 +09:00
parent 3743509b7a
commit bca899db76
4 changed files with 187 additions and 79 deletions

View File

@ -18,7 +18,8 @@
<svg #discoveryTarget width="100%" height="100%"> <svg #discoveryTarget width="100%" height="100%">
<g> <g>
<g *ngFor="let link of links"> <g *ngFor="let link of links">
<line class="link" [attr.x1]="link.source.x" [attr.y1]="link.source.y" [attr.x2]="link.target.x" [attr.y2]="link.target.y"></line> <line class="link" [attr.sourceId]="link.source.id" [attr.targetId]="link.target.id" [attr.x1]="link.source.x"
[attr.y1]="link.source.y" [attr.x2]="link.target.x" [attr.y2]="link.target.y"></line>
</g> </g>
<g *ngFor="let node of nodes"> <g *ngFor="let node of nodes">
<g class="node-container" [attr.nodeId]="node.id" [attr.transform]="'translate(' + node.x + ',' + node.y + ')'" <g class="node-container" [attr.nodeId]="node.id" [attr.transform]="'translate(' + node.x + ',' + node.y + ')'"

View File

@ -14,6 +14,7 @@ import { Node } from '../../../commons/model/node';
import { Link } from '../../../commons/model/link'; import { Link } from '../../../commons/model/link';
import { RPCError } from '@overflow/rpc-js'; import { RPCError } from '@overflow/rpc-js';
import { toMetaIPType, MetaIPTypeEnum, toMetaCryptoType, MetaCryptoTypeEnum } from '@overflow/model/meta';
@Component({ @Component({
selector: 'app-pages-home', selector: 'app-pages-home',
@ -39,6 +40,7 @@ export class HomePageComponent implements OnInit, OnDestroy {
showIntro = true; showIntro = true;
selectedNode = null; selectedNode = null;
private zoneNode: Node;
private nodes: Node[]; private nodes: Node[];
private links: Link[]; private links: Link[];
public simulation: d3.Simulation<Node, Link> | undefined; public simulation: d3.Simulation<Node, Link> | undefined;
@ -125,28 +127,120 @@ export class HomePageComponent implements OnInit, OnDestroy {
this.nodes = []; this.nodes = [];
this.links = []; this.links = [];
this.zoneNode = new Node('192.168.1.0/24');
this.zoneNode.group = 'zone';
this.zoneNode.target = this.zone;
this.zoneNode.fx = width / 2;
this.zoneNode.fy = height / 2;
this.zoneNode.r = 60;
// const hostNode = new Node('192.168.1.1');
// hostNode.group = 'host';
// hostNode.target = {
// metaIPType: toMetaIPType(MetaIPTypeEnum.V4),
// name: 'Host1',
// address: '192.168.1.1',
// mac: '44:8a:5b:f1:f1:f3',
// osType: 'UNKNOWN',
// hostType: 'HOST',
// hostVendor: 'UNKNOWN',
// hostModel: 'UNKNOWN',
// zone: this.zone,
// };
// hostNode.r = 40;
// const hostNode2 = new Node('192.168.1.2');
// hostNode2.group = 'host';
// hostNode2.target = {
// metaIPType: toMetaIPType(MetaIPTypeEnum.V4),
// name: 'Host2',
// address: '192.168.1.2',
// mac: '44:8a:5b:f1:f1:f3',
// osType: 'UNKNOWN',
// hostType: 'HOST',
// hostVendor: 'UNKNOWN',
// hostModel: 'UNKNOWN',
// zone: this.zone,
// };
// hostNode2.r = 40;
// const hostNode3 = new Node('192.168.1.3');
// hostNode3.group = 'host';
// hostNode3.target = {
// metaIPType: toMetaIPType(MetaIPTypeEnum.V4),
// name: 'Host2',
// address: '192.168.1.3',
// mac: '44:8a:5b:f1:f1:f3',
// osType: 'UNKNOWN',
// hostType: 'HOST',
// hostVendor: 'UNKNOWN',
// hostModel: 'UNKNOWN',
// zone: this.zone,
// };
// hostNode3.r = 40;
// const serviceNode1 = new Node('192.168.1.1-10-HTTP');
// serviceNode1.target = {
// metaCryptoType: toMetaCryptoType(MetaCryptoTypeEnum.NONE),
// key: 'HTTP',
// name: 'Apache',
// serviceType: 'WEB',
// serviceVendor: 'Apache',
// serviceVersion: 'UNKNOWN',
// };
// serviceNode1.group = 'service';
// serviceNode1.r = 30;
// const serviceNode2 = new Node('192.168.1.1-20-HTTP');
// serviceNode2.target = {
// metaCryptoType: toMetaCryptoType(MetaCryptoTypeEnum.NONE),
// key: 'HTTP',
// name: 'Apache',
// serviceType: 'WEB',
// serviceVendor: 'Apache',
// serviceVersion: 'UNKNOWN',
// };
// serviceNode2.group = 'service';
// serviceNode2.r = 30;
// const serviceNode3 = new Node('192.168.1.1-30-HTTP');
// serviceNode3.target = {
// metaCryptoType: toMetaCryptoType(MetaCryptoTypeEnum.NONE),
// key: 'HTTP',
// name: 'Apache',
// serviceType: 'WEB',
// serviceVendor: 'Apache',
// serviceVersion: 'UNKNOWN',
// };
// serviceNode3.group = 'service';
// serviceNode3.r = 30;
this.nodes.push( this.nodes.push(
{ id: '192.168.1.0/24', group: 'zone', target: this.zone, fx: width / 2, fy: height / 2, r: 60 }, this.zoneNode,
// { id: '192.168.1.1', group: 'host', target: { address: '192.168.1.1', zone: this.zone, hostType: 'NAS' }, r: 40 }, // hostNode,
// { id: '192.168.1.1' }, // hostNode2,
// { id: '192.168.1.2' }, // hostNode3,
// serviceNode1,
// serviceNode2,
// serviceNode3,
); );
this.links.push( this.links.push(
// { source: this.getNode('192.168.1.0/24'), target: this.getNode('192.168.1.1') }, // new Link(this.zoneNode, hostNode),
// { source: this.getNode('192.168.1.0/24'), target: this.getNode('192.168.1.2') } // new Link(this.zoneNode, hostNode2),
// new Link(this.zoneNode, hostNode3),
// new Link(hostNode, serviceNode1),
// new Link(hostNode, serviceNode2),
// new Link(hostNode, serviceNode3),
); );
this.simulationRestart(); this.simulationRestart(true);
this.probeService.send('DiscoveryService.DiscoverHost', requesterID, this.zone, this.discoverHost); this.probeService.send('DiscoveryService.DiscoverHost', requesterID, this.zone, this.discoverHost);
// this.probeService.send(
// 'DiscoveryService.DiscoverHost',
// requesterID,
// this.discoveryConfigService.getZone(),
// this.discoveryConfigService.getDiscoverHost()
// );
} }
simulationInit() { simulationInit() {
@ -183,66 +277,31 @@ export class HomePageComponent implements OnInit, OnDestroy {
simulationRestart(attachEvent: boolean = false) { simulationRestart(attachEvent: boolean = false) {
// Update and restart the simulation. // Update and restart the simulation.
this.simulation
.nodes(this.nodes)
.force('link', d3.forceLink(this.links).distance(150))
.alpha(1)
.restart()
;
this.changeDetector.detectChanges();
if (attachEvent) { if (attachEvent) {
const __this = this; const __this = this;
// function started(node: Node) { const nodeElements = d3.select(this.discoveryTargetRef.nativeElement).selectAll('.node-container');
// /** Preventing propagation of dragstart to parent elements */ const linkElements = d3.select(this.discoveryTargetRef.nativeElement).selectAll('.link');
// d3.event.sourceEvent.stopPropagation();
// if (!d3.event.active) { function getNodeFromElement(element: Element): Node | null {
// __this.simulation.alphaTarget(0.3).restart(); const container = d3.select(element);
// } const nodeId = container.attr('nodeId');
return __this.getNode(nodeId);
}
// d3.event.on('drag', dragged).on('end', ended); // drag
nodeElements.call(
// function dragged() {
// if (undefined === node) {
// return;
// }
// node.fx = d3.event.x;
// node.fy = d3.event.y;
// }
// function ended() {
// if (!d3.event.active) {
// __this.simulation.alphaTarget(0);
// }
// if (undefined === node) {
// return;
// }
// node.fx = null;
// node.fy = null;
// }
// }
// d3.select(this.discoveryTargetRef.nativeElement).selectAll('.node-container').call(d3.drag().on('start', started));
// d3.select(this.discoveryTargetRef.nativeElement).selectAll('.node-container').call(
// d3.drag()
// .on('start', (node: Node, i: number) => {
// __this.simulation.stop();
// })
// .on('drag', (node: Node, i: number) => {
// node.fx += d3.event.dx;
// node.fy += d3.event.dy;
// node.x += d3.event.dx;
// node.y += d3.event.dy;
// })
// .on('end', (node: Node, i: number) => {
// __this.simulation.stop();
// })
// );
d3.select(this.discoveryTargetRef.nativeElement).selectAll('.node-container').call(
d3.drag() d3.drag()
.on('start', function () { .on('start', function () {
const container = d3.select(this); const node = getNodeFromElement(this);
const nodeId = container.attr('nodeId');
const node = __this.getNode(nodeId);
d3.event.sourceEvent.stopPropagation(); d3.event.sourceEvent.stopPropagation();
@ -268,14 +327,49 @@ export class HomePageComponent implements OnInit, OnDestroy {
}) })
); );
} nodeElements
.on('mouseover', function () {
const node = getNodeFromElement(this as Element);
if ('zone' === node.group) {
return;
}
nodeElements.style('opacity', function (): number {
const _node = getNodeFromElement(this as Element);
for (let i = 0; i < node.links.length; i++) {
const link = node.links[i];
if (node === _node || link.source === _node || link.target === _node) {
return 1;
}
}
return 0.3;
});
linkElements.style('opacity', function (): number {
const linkElement = d3.select(this as Element);
const sourceId = linkElement.attr('sourceId');
const targetId = linkElement.attr('targetId');
this.simulation if (sourceId === node.id || targetId === node.id) {
.nodes(this.nodes) return 1;
.force('link', d3.forceLink(this.links).distance(150)) }
.alpha(1)
.restart() return 0.3;
; });
})
.on('mousedown', function () {
})
.on('mouseout', function () {
const node = getNodeFromElement(this as Element);
nodeElements.style('opacity', function (): number {
return 1;
});
linkElements.style('opacity', function (): number {
return 1;
});
})
;
}
} }
onTargetClick(node: Node) { onTargetClick(node: Node) {
@ -376,7 +470,6 @@ export class HomePageComponent implements OnInit, OnDestroy {
} }
const hostId = `${host.address}`; const hostId = `${host.address}`;
const zoneNode = this.getNode('192.168.1.0/24');
let hostNode = this.getNode(hostId); let hostNode = this.getNode(hostId);
if (null !== hostNode) { if (null !== hostNode) {
@ -386,11 +479,11 @@ export class HomePageComponent implements OnInit, OnDestroy {
hostNode.target = host; hostNode.target = host;
hostNode.group = 'host'; hostNode.group = 'host';
hostNode.r = 40; hostNode.r = 40;
hostNode.x = zoneNode.x; hostNode.x = this.zoneNode.x;
hostNode.y = zoneNode.y; hostNode.y = this.zoneNode.y;
this.nodes.push(hostNode); this.nodes.push(hostNode);
this.links.push(new Link(zoneNode, hostNode)); this.links.push(new Link(this.zoneNode, hostNode));
} }
this.simulationRestart(); this.simulationRestart();

View File

@ -8,7 +8,13 @@ export class Link implements d3.SimulationLinkDatum<Node> {
index?: number; index?: number;
constructor(source, target) { constructor(source: Node, target: Node) {
target.addLink(this);
if ('zone' !== source.group) {
source.addLink(this);
}
this.source = source; this.source = source;
this.target = target; this.target = target;
} }

View File

@ -1,4 +1,5 @@
import * as d3 from 'd3'; import * as d3 from 'd3';
import { Link } from './link';
export class Node implements d3.SimulationNodeDatum { export class Node implements d3.SimulationNodeDatum {
/** /**
@ -40,8 +41,15 @@ export class Node implements d3.SimulationNodeDatum {
image?: string; image?: string;
links?: Link[];
constructor(id) { constructor(id) {
this.id = id; this.id = id;
this.links = [];
}
addLink(link: Link) {
this.links.push(link);
} }
} }