in src/visual.ts [839:901]
private getForceTick(): () => void {
const viewport: IViewport = this.viewportIn;
const properties: TextProperties = {
fontFamily: ForceGraph.LabelsFontFamily,
fontSize: PixelConverter.fromPoint(this.settings.labels.fontSize),
text: this.data.formatter.format("")
};
const showArrow: boolean = this.settings && this.settings.links && this.settings.links.showArrow;
let resolutionFactor: number = ForceGraph.ResolutionFactor;
if (this.settings.size.boundedByBox) {
resolutionFactor = ForceGraph.ResolutionFactorBoundByBox;
}
// limitX and limitY is necessary when you minimize the graph and then resize it to normal.
// "width/height * 20" seems enough to move nodes freely by force layout.
const maxWidth: number = viewport.width * resolutionFactor,
maxHeight: number = viewport.height * resolutionFactor,
viewPortWidthDownLimit: number = (viewport.width - maxWidth) / 2,
viewPortHeightDownLimit: number = (viewport.height - maxHeight) / 2,
viewPortHeightUpLimit: number = (viewport.height + maxHeight) / 2,
viewPortWidthUpLimit: number = (viewport.height + maxHeight) / 2,
limitX: (x: number) => number = x => Math.max(viewPortWidthDownLimit, Math.min(viewPortWidthUpLimit, x)),
limitY: (y: number) => number = y => Math.max(viewPortHeightDownLimit, Math.min(viewPortWidthUpLimit, y));
return () => {
this.paths.attr("d", (link: ForceGraphLink) => {
link.source.x = limitX(link.source.x);
link.source.y = limitY(link.source.y);
link.target.x = limitX(link.target.x);
link.target.y = limitY(link.target.y);
return showArrow
? this.getPathWithArrow(link)
: this.getPathWithoutArrow(link);
});
this.nodes.attr("transform", (node: ForceGraphNode) => translate(limitX(node.x), limitY(node.y)));
if (!this.settings.labels.allowIntersection
&& this.settings.labels.show
&& Object.keys(this.data.nodes).length <= ForceGraph.NoAnimationLimit) {
this.nodes
.classed("hiddenLabel", (node: ForceGraphNode) => {
properties.text = this.data.formatter.format(node.name);
let curNodeTextRect: ITextRect = this.getTextRect(properties, node.x, node.y);
node.hideLabel = false;
this.nodes.each((otherNode: ForceGraphNode) => {
properties.text = this.data.formatter.format(otherNode.name);
let otherNodeTextRect: ITextRect = this.getTextRect(properties, otherNode.x, otherNode.y);
if (!otherNode.hideLabel && node.name !== otherNode.name && this.isIntersect(curNodeTextRect, otherNodeTextRect)) {
node.hideLabel = true;
return;
}
});
return node.hideLabel;
});
}
};
}