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):
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);