Evenly distributed horizontally



select multiple nodes and then make those nodes evenly distributed horizontally or vertically

Call one of these two commands defined in the DrawCommandHandler extension.
DrawCommandHandler | GoJS API
DrawCommandHandler | GoJS API

Maybe for v3 we should also define commands for arranging them with even spacing either horizontally or vertically while maintaining their original y or x position based on the original total width or height occupied by all of the selected nodes.

Here you go. These two new methods will be in the v3 DrawCommandHandler.

    /**
     * Position each selected non-Link horizontally so that each distance between them is the same,
     * given the total width of the area occupied by them.
     * Their Y positions are not modified.
     * It tries to maintain the same ordering of selected Parts by their X position.
     *
     * Note that if there is not enough room, the spacing might be negative -- the Parts might overlap.
     */
    spaceEvenlyHorizontally() {
        const diagram = this.diagram;
        const nonlinks = new go.List();
        diagram.selection.each(part => {
            if (part instanceof go.Link)
                return; // skips over links
            nonlinks.add(part); // maybe check for non-movable Parts??
        });
        if (nonlinks.count <= 1)
            return;
        const b = diagram.computePartsBounds(nonlinks);
        if (!b.isReal())
            return;
        nonlinks.sort((a, b) => a.actualBounds.x - b.actualBounds.x);
        let w = 0;
        nonlinks.each(part => w += part.actualBounds.width);
        const sp = (b.width - w) / (nonlinks.count - 1); // calculate available space between nodes; might be negative
        diagram.startTransaction("space evenly horizontally");
        let x = b.x;
        nonlinks.each(part => {
            part.moveTo(x, part.actualBounds.y);
            x += part.actualBounds.width + sp;
        });
        diagram.commitTransaction("space evenly horizontally");
    }
    /**
     * Position each selected non-Link vertically so that each distance between them is the same,
     * given the total height of the area occupied by them.
     * Their X positions are not modified.
     * It tries to maintain the same ordering of selected Parts by their Y position.
     *
     * Note that if there is not enough room, the spacing might be negative -- the Parts might overlap.
     */
    spaceEvenlyVertically() {
        const diagram = this.diagram;
        const nonlinks = new go.List();
        diagram.selection.each(part => {
            if (part instanceof go.Link)
                return; // skips over links
            nonlinks.add(part); // maybe check for non-movable Parts??
        });
        if (nonlinks.count <= 1)
            return;
        const b = diagram.computePartsBounds(nonlinks);
        if (!b.isReal())
            return;
        nonlinks.sort((a, b) => a.actualBounds.y - b.actualBounds.y);
        let h = 0;
        nonlinks.each(part => h += part.actualBounds.height);
        const sp = (b.height - h) / (nonlinks.count - 1); // calculate available space between nodes; might be negative
        diagram.startTransaction("space evenly vertically");
        let y = b.y;
        nonlinks.each(part => {
            part.moveTo(part.actualBounds.x, y);
            y += part.actualBounds.height + sp;
        });
        diagram.commitTransaction("space evenly vertically");
    }
1 Like