nextspace
    Preparing search index...

    Function selectVisibleLabels

    • Chooses which labels can be drawn without overlapping each other, and where.

      A force layout puts nodes where the forces leave them, which in a dense graph is close enough together that their labels collide and the text becomes unreadable — several words printed over each other are worth less than one word printed clearly. So labels are placed greedily, best first: a candidate tries its own spot, then each of its alternates in turn, and takes the first one that fits rather than being dropped outright — the reader gets more names on screen for the same crowding, at no cost to legibility, since a chosen alternate is held to exactly the same rules as the primary spot would have been.

      This only works on labels of a fixed screen size. Labels that scale with the graph collide identically at every zoom, so dropping them would hide the same words however far in the reader zoomed; at a fixed size, zooming spreads the nodes apart on screen and the labels come back by themselves. That is what makes zoom worth having on a crowded graph.

      A spot that would land on a LabelCandidate.hardObstacle is ruled out outright, required or not — required only ever overrides a collision with another label, since focusing on a well-connected node makes every one of its neighbours required at once, and without this a tight focused view could paper an unrelated node's own circle with someone else's caption, hiding it and blocking its click target.

      Parameters

      • candidates: LabelCandidate[]

        Every label that wants to be drawn, in screen coordinates.

      • padding: number = 2

        Breathing room required between two labels.

      Returns Map<string, LabelPosition>

      Each visible id mapped to the position it was actually drawn at.