This commit is contained in:
crusader 2018-09-14 19:06:58 +09:00
parent 5b3a12231d
commit fb6bf37906
3 changed files with 96 additions and 32 deletions

View File

@ -22,8 +22,7 @@
[attr.y1]="link.source.y" [attr.x2]="link.target.x" [attr.y2]="link.target.y"></line> [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 + ')'">
(click)="onTargetClick(node)">
<g *ngIf="node.group === 'zone'"> <g *ngIf="node.group === 'zone'">
<image [attr.x]="-node.r" [attr.y]="-node.r" [attr.width]="node.r * 2" [attr.height]="node.r * 2" <image [attr.x]="-node.r" [attr.y]="-node.r" [attr.width]="node.r * 2" [attr.height]="node.r * 2"
xlink:href="../../assets/image/icon/icon_overflow.svg"></image> xlink:href="../../assets/image/icon/icon_overflow.svg"></image>

View File

@ -66,3 +66,11 @@
stroke-width: .5; stroke-width: .5;
font-size: 14px; font-size: 14px;
} }
.unfocused {
opacity: 0.3;
}
.unselected {
opacity: 0.3;
}

View File

@ -45,6 +45,8 @@ export class HomePageComponent implements OnInit, OnDestroy {
private discoveryContainerHeight: number; private discoveryContainerHeight: number;
private discoveryStartDate: Date; private discoveryStartDate: Date;
private discoveryRequestID: string; private discoveryRequestID: string;
private readonly maxScale: number;
private readonly minScale: number;
hosts: Host[]; hosts: Host[];
ports: Port[]; ports: Port[];
@ -68,13 +70,6 @@ export class HomePageComponent implements OnInit, OnDestroy {
// event.returnValue = true; // event.returnValue = true;
} }
@HostListener('window:onunload', ['$event'])
onUnload(event) {
}
@ViewChild('discoveryTarget') set discoveryTarget(content: ElementRef) { @ViewChild('discoveryTarget') set discoveryTarget(content: ElementRef) {
this.discoveryTargetRef = content; this.discoveryTargetRef = content;
} }
@ -88,6 +83,9 @@ export class HomePageComponent implements OnInit, OnDestroy {
this.links = []; this.links = [];
this.hosts = []; this.hosts = [];
this.ports = []; this.ports = [];
this.maxScale = 1;
this.minScale = 0.7;
} }
ngOnInit() { ngOnInit() {
@ -328,11 +326,19 @@ export class HomePageComponent implements OnInit, OnDestroy {
return __this.getNode(nodeId); return __this.getNode(nodeId);
} }
nodeElements.on('click', function () {
const node = getNodeFromElement(this as Element);
__this.onTargetClick(node);
});
// drag // drag
nodeElements.call( nodeElements.call(
d3.drag() d3.drag()
.on('start', function () { .on('start', function () {
const node = getNodeFromElement(this); const node = getNodeFromElement(this);
if (null === node || 'zone' === node.group) {
return;
}
d3.event.sourceEvent.stopPropagation(); d3.event.sourceEvent.stopPropagation();
@ -358,44 +364,86 @@ export class HomePageComponent implements OnInit, OnDestroy {
}) })
); );
function isConnectedNode(node: Node, element: Element): boolean {
const _node = getNodeFromElement(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 true;
}
}
return false;
}
function isConnectedLink(node: Node, element: Element) {
const _linkElement = d3.select(element);
const sourceId = _linkElement.attr('sourceId');
const targetId = _linkElement.attr('targetId');
if (sourceId === node.id || targetId === node.id) {
return true;
}
return false;
}
// Highlight
const discoveryContainer = d3.select(this.discoveryTargetRef.nativeElement);
discoveryContainer.on('click', function () {
nodeElements.classed('unselected', function (): boolean {
return false;
});
linkElements.classed('unselected', function (): boolean {
return false;
});
});
nodeElements nodeElements
.on('mouseover', function () { .on('mouseover', function () {
const node = getNodeFromElement(this as Element); const node = getNodeFromElement(this as Element);
if ('zone' === node.group) { if ('zone' === node.group) {
return; return;
} }
nodeElements.style('opacity', function (): number { nodeElements.classed('unfocused', function (): boolean {
const _node = getNodeFromElement(this as Element); if (isConnectedNode(node, this as Element)) {
for (let i = 0; i < node.links.length; i++) { return false;
const link = node.links[i];
if (node === _node || link.source === _node || link.target === _node) {
return 1;
} }
} return true;
return 0.3;
}); });
linkElements.style('opacity', function (): number { linkElements.classed('unfocused', function (): boolean {
const linkElement = d3.select(this as Element); if (isConnectedLink(node, this as Element)) {
const sourceId = linkElement.attr('sourceId'); return false;
const targetId = linkElement.attr('targetId');
if (sourceId === node.id || targetId === node.id) {
return 1;
} }
return true;
return 0.3;
}); });
}) })
.on('mousedown', function () { .on('mousedown', function () {
const node = getNodeFromElement(this as Element);
if (null === node || 'zone' === node.group) {
return;
}
nodeElements.classed('unselected', function (): boolean {
if (isConnectedNode(node, this as Element)) {
return false;
}
return true;
});
linkElements.classed('unselected', function (): boolean {
if (isConnectedLink(node, this as Element)) {
return false;
}
return true;
});
}) })
.on('mouseout', function () { .on('mouseout', function () {
const node = getNodeFromElement(this as Element); const node = getNodeFromElement(this as Element);
nodeElements.style('opacity', function (): number {
return 1; nodeElements.classed('unfocused', function (): boolean {
return false;
}); });
linkElements.style('opacity', function (): number { linkElements.classed('unfocused', function (): boolean {
return 1; return false;
}); });
}) })
; ;
@ -418,7 +466,16 @@ export class HomePageComponent implements OnInit, OnDestroy {
if (width === 0 || height === 0) { return; } // nothing to fit if (width === 0 || height === 0) { return; } // nothing to fit
const scale = (paddingPercent || 0.75) / Math.max(width / fullWidth, height / fullHeight); let scale = (paddingPercent || 0.75) / Math.max(width / fullWidth, height / fullHeight);
console.log(`scale: ${scale}`);
if (this.maxScale < scale) {
scale = this.maxScale;
}
if (this.minScale > scale) {
scale = this.minScale;
}
const translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY]; const translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY];
root root