private setVisualData()

in src/visual.ts [625:801]


    private setVisualData(
        svg: d3.Selection<any>,
        colorPalette: IColorPalette,
        colorHelper: ColorHelper,
    ): void {
        this.paths = svg.selectAll(ForceGraph.LinkSelector.selectorName)
            .data(this.forceLayout.links())
            .enter()
            .append("path")
            .attr("id", (d, i) => "linkid_" + this.uniqieId + i)
            .attr("stroke-width", (link: ForceGraphLink) => {
                return this.settings.links.thickenLink
                    ? this.scale1to10(link.weight)
                    : ForceGraph.DefaultLinkThickness;
            })
            .classed(ForceGraph.LinkSelector.className, true)
            .style("stroke", (link: ForceGraphLink) => {
                return this.getLinkColor(link, colorPalette, colorHelper);
            })
            .style("fill", (link: ForceGraphLink) => {
                if (this.settings.links.showArrow && link.source !== link.target) {
                    return this.getLinkColor(link, colorPalette, colorHelper);
                }
            })
            .on("mouseover", () => {

                return this.fadePath(
                    ForceGraph.HoverOpacity,
                    colorHelper.getHighContrastColor("foreground", ForceGraph.DefaultLinkHighlightColor),
                    colorHelper.getHighContrastColor("foreground", ForceGraph.DefaultLinkColor)
                );
            })
            .on("mouseout", () => {
                return this.fadePath(
                    ForceGraph.DefaultOpacity,
                    colorHelper.getHighContrastColor("foreground", ForceGraph.DefaultLinkColor),
                    colorHelper.getHighContrastColor("foreground", ForceGraph.DefaultLinkColor)
                );
            });

        this.tooltipServiceWrapper.addTooltip(this.paths, (eventArgs: TooltipEventArgs<ForceGraphLink>) => {
            return eventArgs.data.tooltipInfo;
        });

        if (this.settings.links.showLabel) {
            let linklabelholderUpdate: d3.selection.Update<ForceGraphLink> = svg
                .selectAll(ForceGraph.LinkLabelHolderSelector.selectorName)
                .data(this.forceLayout.links());

            linklabelholderUpdate.enter()
                .append("g")
                .classed(ForceGraph.LinkLabelHolderSelector.className, true)
                .append("text")
                .classed(ForceGraph.LinkLabelSelector.className, true)
                .attr("dy", (link: ForceGraphLink) => {
                    return this.settings.links.thickenLink
                        ? -this.scale1to10(link.weight) + this.defaultYOffset
                        : this.defaultYPosition;
                })
                .attr("text-anchor", ForceGraph.LinkTextAnchor)
                .style("fill", colorHelper.getHighContrastColor("foreground", ForceGraph.DefaultLinkFillColor))
                .append("textPath")
                .attr("xlink:href", (link: ForceGraphLink, index: number) => {
                    return ForceGraph.Href + "#linkid_" + this.uniqieId + index;
                })
                .attr("startOffset", ForceGraph.StartOffset)
                .text((link: ForceGraphLink) => {
                    return this.settings.links.colorLink === LinkColorType.ByLinkType
                        ? link.linkType
                        : link.formattedWeight;
                });

            linklabelholderUpdate
                .exit()
                .remove();
        }

        let nodesNum: number = Object.keys(this.data.nodes).length;
        let selectionManager = this.selectionManager;

        // define the nodes
        this.nodes = svg.selectAll(ForceGraph.NodeSelector.selectorName)
            .data(this.forceLayout.nodes())
            .enter()
            .append("g")
            .attr("drag-resize-disabled", true)
            .classed(ForceGraph.NodeSelector.className, true)
            .on("mouseover", (node: ForceGraphNode) => {
                node.isOver = true;
                this.fadeNode(node);
            })
            .on("mouseout", (node: ForceGraphNode) => {
                node.isOver = false;
                this.fadeNode(node);
            })
            .on("click", function (d) {
                selectionManager.select(d.identity);

                (<Event>d3.event).stopPropagation();
            });

        if (nodesNum <= ForceGraph.NoAnimationLimit) {
            this.nodes.call(this.forceLayout.drag);
        }

        // render without animation
        if (!this.settings.animation.show || nodesNum > ForceGraph.NoAnimationLimit) {
            const viewport: IViewport = this.viewportIn;

            let maxWidth: number = viewport.width * ForceGraph.ResolutionFactor,
                maxHeight: number = viewport.height * ForceGraph.ResolutionFactor,
                limitX = x => Math.max((viewport.width - maxWidth) / 2, Math.min((viewport.width + maxWidth) / 2, x)),
                limitY = y => Math.max((viewport.height - maxHeight) / 2, Math.min((viewport.height + maxHeight) / 2, y));

            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 this.settings && this.settings.links && this.settings.links.showArrow
                    ? this.getPathWithArrow(link)
                    : this.getPathWithoutArrow(link);
            });

            this.nodes.attr("transform", (node: ForceGraphNode) => translate(limitX(node.x), limitY(node.y)));
        }

        // add the nodes
        if (this.settings.nodes.displayImage) {
            this.nodes.append("image")
                .attr("x", PixelConverter.toString(ForceGraph.ImagePosition))
                .attr("y", PixelConverter.toString(ForceGraph.ImagePosition))
                .attr("width", PixelConverter.toString(ForceGraph.ImageViewport.width))
                .attr("height", PixelConverter.toString(ForceGraph.ImageViewport.height))
                .attr("xlink:href", (node: ForceGraphNode) => {
                    if (node.image) {
                        return this.getImage(node.image);
                    } else if (this.settings.nodes.defaultImage) {
                        return this.getImage(this.settings.nodes.defaultImage);
                    }

                    return ForceGraph.DefaultImage;
                })
                .attr("title", (node: ForceGraphNode) => node.name);
        } else {
            this.nodes
                .append("circle")
                .attr("r", (node: ForceGraphNode) => {
                    return isNaN(node.weight) || node.weight < ForceGraph.MinNodeWeight
                        ? ForceGraph.MinNodeWeight
                        : node.weight;
                })
                .style("fill", this.settings.nodes.fill)
                .style("stroke", this.settings.nodes.stroke);
        }

        // add the text
        if (this.settings.labels.show) {
            this.nodes.append("text")
                .attr("x", ForceGraph.DefaultLabelX)
                .attr("dy", ForceGraph.DefaultLabelDy)
                .style("fill", this.settings.labels.color)
                .style("font-size", PixelConverter.fromPoint(this.settings.labels.fontSize))
                .text((node: ForceGraphNode) => {
                    if (node.name) {
                        if (node.name.length > this.settings.nodes.nameMaxLength) {
                            return node.name.substr(0, this.settings.nodes.nameMaxLength);
                        } else {
                            return node.name;
                        }
                    } else {
                        return ForceGraph.DefaultLabelText;
                    }
                });
        }
    }