Connect objects without connecting line directly to shape?

Hi there,

I am new to using these forums but not new to Omnigraffle (although I’m still a novice).
I have a question regarding connections.

By default, connections fix themselves to the centre of object. I am aware that this can be modified using magnets, allowing me to connect lines to the outside edges of an object.

However, I am looking for a way to connect objects to one another WITHOUT the lines physically touching the object. I want the objects to have a relational connection, and I want there to be a connecting line between them, but I don’t want the line to physically touch the sides of the shape.

I have emulated what I mean here by using a white stroke on a white background (two screen grabs below):

The problem with this method is that it prohibits me from connecting objects that already have non-white strokes.

Is there a way around this? Is there a way to connect objects with a “buffer” between the connection line and the object themselves??

Any help would be greatly appreciated!

Thanks,

  • Alec

You can give shapes an invisible fringe or halo, with the same magnet pattern as the shape itself.

  • Create a shape without fill or stroke that is larger, by a margin, than the base shape
  • Give the invisible shape the same magnet pattern as the base shape
  • Place the base shape on the invisible shape, so that they share centres.
  • Group them into a compound shape, to produce a visible shape with a connectable halo.

If you are running a Yosemite onwards OS X, you can experiment with selecting one or more shapes, and automating the above by running the following JavaScript for Automation script in Script Editor.

(Copy the whole of the script below (last line is })(20);), paste it into Script Editor, and set the language selector at top left to ‘JavaScript’)

(This draft gives an invisible fringe / halo of 20 points – adjustable to some other value in the last line of the script)

// ver 001

// GIVE EACH SELECTED SHAPE AN INVISIBLE HALO, WITH THE SAME PATTERN OF MAGNETS.
// (CREATES A COMPOUND SHAPE BY GROUPING THE ORGINAL WITH ITS SLIGHTLY LARGER
// INVISIBLE COUNTERPART.

// ALLOWS CONNECTORS WHICH DO NOT ACTUALLY TOUCH THE VISIBLE PART OF THE CONNECTED SHAPES

//  TO USE:
//  0. Adjust (in points) the size of fringe required (last line of this script)
//  1. Select one or more shapes
//  2. Run this script in Script Editor (with language selector at top left set to JavaScript)

(function (marginPoints) {
    'use strict';

    var concatMap = function (xs, f) {
        return [].concat.apply([], xs.map(f));
    }

    // Because of a bug in the OmniGraffle 6 scripting interface
    // (the grouping function assemble() fails with arrays)
    // we unfortunately have to use a hack to convert the array of 
    // selected shapes into a reference to the subset of 
    // canvas graphics which have IDs matching those of the selection array
    
    // OG_graphics_collection -> [ og_graphic ] -> OG_graphics_collection
    function hackRef(graphics, lstGraphics) {
        var lng = lstGraphics.length;

        if (lng) {
            var matches = lstGraphics.map(function (g) {
                return {
                    id: g.id()
                }
            });

            return graphics.whose(lng > 1 ? {
                _or: matches
            } : matches[0]);
        } else return null;
    }

    var og = Application('OmniGraffle'),
        ws = og.windows,
        w = ws.length ? ws[0] : undefined;

    if (w) {
        var cnv = w.canvas,
            gs = cnv.graphics,
            m2 = marginPoints * 2;

            w.selection = concatMap(
                w.selection(),
                function (g) {
                    if (g.class() === 'shape') {
                        var xy = g.origin(),
                            wh = g.size();

                        var halo = og.Shape({
                            fill: 'no fill',
                            drawsStroke: false,
                            drawsShadow: false,
                            magnets: g.magnets(),
                            origin: [xy[0] - marginPoints, xy[1] - marginPoints],
                            size: [wh[0] + m2, wh[1] + m2]
                        });

                        gs.push(halo);
                        
                        return [og.assemble(
                            hackRef(gs, [g, halo])
                        )];

                    } else return [];
                }
            );
    }

})(20);

Hi there,
This is great; really helpful - thanks!

  • Alec
1 Like