flowink 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -92,12 +92,8 @@ flowchart TB
92
92
  │ │
93
93
  ╲────────╱
94
94
  ┌┘ │
95
- │ └─────┐
96
- no
97
- yes │ │
98
- │ │
99
- │ │
100
- ▼ ▼
95
+ yes │ └─────┐
96
+ no
101
97
  ┌───────┐┌───────┐
102
98
  │ Ship ││ Wait │
103
99
  └───────┘└───────┘
@@ -190,8 +186,6 @@ flowchart TB
190
186
  | +--------+ |
191
187
  | | |
192
188
  +-----|------+
193
- |
194
- |
195
189
  v
196
190
  +------+
197
191
  | Text |
package/dist/index.js CHANGED
@@ -2274,19 +2274,49 @@ async function layout(graph) {
2274
2274
  });
2275
2275
  }
2276
2276
  const result = fromElkGraph(context, laidOut);
2277
- if (needsWireClearance(context.graph, result)) expandGrid(result);
2277
+ compactVerticalChannels(result);
2278
+ separateAdjacentRoutes(result);
2278
2279
  return placeLabels(result);
2279
2280
  }
2280
- function needsWireClearance(graph, layoutGraph) {
2281
- const pairs = /* @__PURE__ */ new Set();
2282
- const reverse = /* @__PURE__ */ new Set();
2283
- for (const edge of graph.edges) {
2284
- const pair = pairKey(edge.source, edge.target);
2285
- if (pairs.has(pair) || reverse.has(pairKey(edge.target, edge.source))) return true;
2286
- pairs.add(pair);
2287
- reverse.add(pair);
2281
+ function compactVerticalChannels(layoutGraph) {
2282
+ const fixed = /* @__PURE__ */ new Set();
2283
+ for (const box of layoutGraph.boxes) {
2284
+ fixed.add(box.y);
2285
+ fixed.add(box.y + box.height - 1);
2286
+ const end = box.kind === "subgraph" ? box.y + 1 + box.lines.length : box.y + box.height;
2287
+ for (let y = box.y; y < end; y += 1) fixed.add(y);
2288
+ }
2289
+ for (const edge of layoutGraph.edges) {
2290
+ for (const point of edge.points) fixed.add(point.y);
2291
+ if (edge.arrowStart !== "none" && edge.arrowEnd !== "none") {
2292
+ const first = edge.points[0];
2293
+ const last = edge.points.at(-1);
2294
+ const next = edge.points.find((point) => point.x !== first.x || point.y !== first.y);
2295
+ const previous = [...edge.points].reverse().find((point) => point.x !== last.x || point.y !== last.y);
2296
+ if (next) fixed.add(first.y + Math.sign(next.y - first.y));
2297
+ if (previous) fixed.add(last.y + Math.sign(previous.y - last.y));
2298
+ }
2299
+ }
2300
+ const rows = [...fixed].sort((a, b) => a - b);
2301
+ const removed = [];
2302
+ for (let i = 1; i < rows.length; i += 1) {
2303
+ for (let y = rows[i - 1] + 2; y < rows[i]; y += 1) removed.push(y);
2304
+ }
2305
+ const map = (value) => value - removed.filter((y) => y < value).length;
2306
+ for (const box of layoutGraph.boxes) {
2307
+ const bottom = map(box.y + box.height - 1);
2308
+ box.y = map(box.y);
2309
+ box.height = bottom - box.y + 1;
2288
2310
  }
2289
- const segments = layoutGraph.edges.flatMap((edge) => edge.points.slice(1).map((b, index) => ({
2311
+ for (const edge of layoutGraph.edges) {
2312
+ for (const point of edge.points) point.y = map(point.y);
2313
+ if (edge.label) edge.label.y = map(edge.label.y);
2314
+ }
2315
+ layoutGraph.height = map(layoutGraph.height);
2316
+ }
2317
+ function separateAdjacentRoutes(layoutGraph) {
2318
+ const gaps = { x: /* @__PURE__ */ new Set(), y: /* @__PURE__ */ new Set() };
2319
+ const segments = layoutGraph.edges.filter((edge) => edge.stroke !== "invisible").flatMap((edge) => edge.points.slice(1).map((b, index) => ({
2290
2320
  id: edge.id,
2291
2321
  a: edge.points[index],
2292
2322
  b,
@@ -2300,31 +2330,29 @@ function needsWireClearance(graph, layoutGraph) {
2300
2330
  const varying = a.horizontal ? "x" : "y";
2301
2331
  const distance = Math.abs(a.a[fixed] - b.a[fixed]);
2302
2332
  const overlap = Math.min(Math.max(a.a[varying], a.b[varying]), Math.max(b.a[varying], b.b[varying])) - Math.max(Math.min(a.a[varying], a.b[varying]), Math.min(b.a[varying], b.b[varying]));
2303
- if (distance === 1 && overlap >= 1) return true;
2333
+ if (distance === 1 && overlap >= 1) gaps[fixed].add(Math.min(a.a[fixed], b.a[fixed]));
2304
2334
  }
2305
- return false;
2306
- }
2307
- function expandGrid(layoutGraph) {
2335
+ const map = (axis, value) => value + [...gaps[axis]].filter((gap) => gap < value).length;
2308
2336
  for (const box of layoutGraph.boxes) {
2309
- box.x *= 2;
2310
- box.y *= 2;
2311
- box.width = Math.max(1, (box.width - 1) * 2 + 1);
2312
- box.height = Math.max(1, (box.height - 1) * 2 + 1);
2337
+ const right = map("x", box.x + box.width - 1);
2338
+ const bottom = map("y", box.y + box.height - 1);
2339
+ box.x = map("x", box.x);
2340
+ box.y = map("y", box.y);
2341
+ box.width = right - box.x + 1;
2342
+ box.height = bottom - box.y + 1;
2313
2343
  }
2314
2344
  for (const edge of layoutGraph.edges) {
2315
2345
  for (const point of edge.points) {
2316
- point.x *= 2;
2317
- point.y *= 2;
2346
+ point.x = map("x", point.x);
2347
+ point.y = map("y", point.y);
2318
2348
  }
2319
2349
  if (edge.label) {
2320
- edge.label.x *= 2;
2321
- edge.label.y *= 2;
2322
- edge.label.width = Math.max(1, (edge.label.width - 1) * 2 + 1);
2323
- edge.label.height = Math.max(1, (edge.label.height - 1) * 2 + 1);
2350
+ edge.label.x = map("x", edge.label.x);
2351
+ edge.label.y = map("y", edge.label.y);
2324
2352
  }
2325
2353
  }
2326
- layoutGraph.width = Math.max(1, layoutGraph.width * 2);
2327
- layoutGraph.height = Math.max(1, layoutGraph.height * 2);
2354
+ layoutGraph.width = map("x", layoutGraph.width);
2355
+ layoutGraph.height = map("y", layoutGraph.height);
2328
2356
  }
2329
2357
  function makeContext(graph) {
2330
2358
  if (!graph || typeof graph !== "object") invalid("A FlowGraph object is required.");