elkrb 1.0.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +364 -0
- data/LICENSE +25 -0
- data/README.adoc +695 -557
- data/exe/elkrb +36 -2
- data/lib/elkrb/atomic_destination.rb +53 -0
- data/lib/elkrb/best_effort_write.rb +49 -0
- data/lib/elkrb/cli/layout_flag_options.rb +54 -0
- data/lib/elkrb/cli.rb +155 -82
- data/lib/elkrb/command_resolver.rb +186 -0
- data/lib/elkrb/commands/batch_command.rb +28 -5
- data/lib/elkrb/commands/convert_command.rb +22 -52
- data/lib/elkrb/commands/diagram_command.rb +234 -102
- data/lib/elkrb/commands/options_command.rb +87 -0
- data/lib/elkrb/commands/render_command.rb +6 -1
- data/lib/elkrb/commands/validate_command.rb +146 -91
- data/lib/elkrb/errors.rb +20 -1
- data/lib/elkrb/format_sniffer.rb +362 -0
- data/lib/elkrb/geometry/bezier.rb +14 -4
- data/lib/elkrb/geometry/point.rb +5 -6
- data/lib/elkrb/geometry/rectangle.rb +2 -2
- data/lib/elkrb/graph/deep_stringify_keys.rb +30 -0
- data/lib/elkrb/graph/edge.rb +89 -3
- data/lib/elkrb/graph/graph.rb +43 -15
- data/lib/elkrb/graph/label.rb +16 -2
- data/lib/elkrb/graph/node.rb +13 -2
- data/lib/elkrb/graph/node_constraints.rb +139 -8
- data/lib/elkrb/graph/normalize_option_keys.rb +39 -0
- data/lib/elkrb/graph/port.rb +29 -21
- data/lib/elkrb/graph/read_only_mapping.rb +21 -0
- data/lib/elkrb/graphviz_wrapper.rb +152 -44
- data/lib/elkrb/layout/algorithm_registry.rb +65 -8
- data/lib/elkrb/layout/algorithms/base_algorithm.rb +74 -74
- data/lib/elkrb/layout/algorithms/box.rb +47 -20
- data/lib/elkrb/layout/algorithms/disco.rb +150 -61
- data/lib/elkrb/layout/algorithms/fixed.rb +70 -10
- data/lib/elkrb/layout/algorithms/force.rb +145 -86
- data/lib/elkrb/layout/algorithms/layered/bk/aligner.rb +104 -0
- data/lib/elkrb/layout/algorithms/layered/bk/compactor.rb +87 -0
- data/lib/elkrb/layout/algorithms/layered/bk/view.rb +103 -0
- data/lib/elkrb/layout/algorithms/layered/bk_node_placer.rb +170 -0
- data/lib/elkrb/layout/algorithms/layered/components.rb +170 -0
- data/lib/elkrb/layout/algorithms/layered/crossing_minimizer.rb +306 -0
- data/lib/elkrb/layout/algorithms/layered/cycle_breaker.rb +118 -49
- data/lib/elkrb/layout/algorithms/layered/discovery_order.rb +75 -0
- data/lib/elkrb/layout/algorithms/layered/dummy_slot.rb +31 -0
- data/lib/elkrb/layout/algorithms/layered/layer_assigner.rb +188 -48
- data/lib/elkrb/layout/algorithms/layered/layer_constraints.rb +82 -0
- data/lib/elkrb/layout/algorithms/layered/layer_sweep.rb +195 -0
- data/lib/elkrb/layout/algorithms/layered/node_placer.rb +214 -36
- data/lib/elkrb/layout/algorithms/layered/orthogonal/gap_solver.rb +219 -0
- data/lib/elkrb/layout/algorithms/layered/orthogonal/hyper_edge_segment.rb +152 -0
- data/lib/elkrb/layout/algorithms/layered/orthogonal/junction_points.rb +58 -0
- data/lib/elkrb/layout/algorithms/layered/orthogonal/segment_order.rb +134 -0
- data/lib/elkrb/layout/algorithms/layered/orthogonal_router.rb +253 -0
- data/lib/elkrb/layout/algorithms/layered/port_order.rb +188 -0
- data/lib/elkrb/layout/algorithms/layered/port_spread.rb +42 -0
- data/lib/elkrb/layout/algorithms/layered.rb +548 -13
- data/lib/elkrb/layout/algorithms/libavoid.rb +951 -187
- data/lib/elkrb/layout/algorithms/mrtree.rb +585 -65
- data/lib/elkrb/layout/algorithms/radial.rb +188 -29
- data/lib/elkrb/layout/algorithms/random.rb +131 -17
- data/lib/elkrb/layout/algorithms/rectpacking.rb +28 -40
- data/lib/elkrb/layout/algorithms/spore_compaction.rb +57 -100
- data/lib/elkrb/layout/algorithms/spore_overlap.rb +78 -84
- data/lib/elkrb/layout/algorithms/stress.rb +391 -84
- data/lib/elkrb/layout/algorithms/topdown_packing.rb +95 -31
- data/lib/elkrb/layout/algorithms/vertiflex.rb +12 -47
- data/lib/elkrb/layout/constraints/alignment_constraint.rb +49 -12
- data/lib/elkrb/layout/constraints/base_constraint.rb +3 -15
- data/lib/elkrb/layout/constraints/constraint_processor.rb +9 -23
- data/lib/elkrb/layout/constraints/fixed_position_constraint.rb +22 -13
- data/lib/elkrb/layout/constraints/layer_constraint.rb +10 -33
- data/lib/elkrb/layout/constraints/relative_position_constraint.rb +94 -50
- data/lib/elkrb/layout/edge_router.rb +533 -337
- data/lib/elkrb/layout/hierarchical_processor.rb +19 -276
- data/lib/elkrb/layout/java_random.rb +59 -0
- data/lib/elkrb/layout/label_placer.rb +165 -157
- data/lib/elkrb/layout/layout_engine.rb +46 -23
- data/lib/elkrb/layout/node_index.rb +149 -0
- data/lib/elkrb/layout/polyomino/component_compactor.rb +138 -0
- data/lib/elkrb/layout/polyomino/footprint.rb +94 -0
- data/lib/elkrb/layout/polyomino/grid.rb +106 -0
- data/lib/elkrb/layout/polyomino/packer.rb +95 -0
- data/lib/elkrb/layout/polyomino/piece.rb +52 -0
- data/lib/elkrb/layout/port_constraint_processor.rb +131 -44
- data/lib/elkrb/layout/spore/body.rb +65 -0
- data/lib/elkrb/layout/spore/depth_first_compaction.rb +127 -0
- data/lib/elkrb/layout/spore/edge_cost.rb +69 -0
- data/lib/elkrb/layout/spore/gap.rb +76 -0
- data/lib/elkrb/layout/spore/geometry.rb +104 -0
- data/lib/elkrb/layout/spore/overlap_sweep.rb +90 -0
- data/lib/elkrb/layout/spore/placement.rb +57 -0
- data/lib/elkrb/layout/spore/rays.rb +119 -0
- data/lib/elkrb/layout/spore/spanning_tree.rb +53 -0
- data/lib/elkrb/layout/spore/triangulation.rb +159 -0
- data/lib/elkrb/layout_flags.rb +69 -0
- data/lib/elkrb/options/decimal.rb +50 -0
- data/lib/elkrb/options/element_options.rb +43 -0
- data/lib/elkrb/options/elk_padding.rb +20 -14
- data/lib/elkrb/options/k_vector.rb +6 -7
- data/lib/elkrb/options/k_vector_chain.rb +12 -20
- data/lib/elkrb/options/option_map.rb +85 -0
- data/lib/elkrb/options/registry.rb +335 -0
- data/lib/elkrb/options/resolver.rb +151 -0
- data/lib/elkrb/options/spellings.rb +62 -0
- data/lib/elkrb/options/unhonoured_report.rb +194 -0
- data/lib/elkrb/parsers/elkt/lexer.rb +309 -0
- data/lib/elkrb/parsers/elkt/parser.rb +424 -0
- data/lib/elkrb/parsers/elkt/resolver.rb +142 -0
- data/lib/elkrb/parsers/elkt/token.rb +40 -0
- data/lib/elkrb/parsers/elkt_parser.rb +32 -230
- data/lib/elkrb/serializers/dot_serializer.rb +342 -54
- data/lib/elkrb/serializers/elkt_serializer.rb +386 -155
- data/lib/elkrb/version.rb +1 -1
- data/lib/elkrb.rb +60 -61
- metadata +71 -49
- data/.rspec +0 -3
- data/.rubocop.yml +0 -11
- data/Gemfile +0 -13
- data/Rakefile +0 -64
- data/benchmarks/README.md +0 -172
- data/benchmarks/elkjs_benchmark.js +0 -140
- data/benchmarks/elkrb_benchmark.rb +0 -145
- data/benchmarks/fixtures/graphs.json +0 -10777
- data/benchmarks/generate_report.rb +0 -241
- data/benchmarks/generate_test_graphs.rb +0 -154
- data/benchmarks/results/elkrb_results.json +0 -280
- data/benchmarks/results/elkrb_summary.json +0 -285
- data/elkrb.gemspec +0 -39
- data/examples/dot_export_demo.rb +0 -133
- data/examples/hierarchical_graph.rb +0 -19
- data/examples/layout_constraints_demo.rb +0 -272
- data/examples/port_constraints_demo.rb +0 -291
- data/examples/self_loop_demo.rb +0 -391
- data/examples/simple_graph.rb +0 -50
- data/examples/spline_routing_demo.rb +0 -235
- data/lib/elkrb/graph/layout_options.rb +0 -247
- data/sig/elkrb/constraints.rbs +0 -114
- data/sig/elkrb/geometry.rbs +0 -61
- data/sig/elkrb/graph.rbs +0 -112
- data/sig/elkrb/layout.rbs +0 -107
- data/sig/elkrb/options.rbs +0 -81
- data/sig/elkrb.rbs +0 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8699f197aff817a1de6a193b1fb421d59e5df023ed0bbb39f7cfa75cedefcf82
|
|
4
|
+
data.tar.gz: cfa580618758f94d81542c86cf4bb87014375057c3271ee00031b962f2faa598
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 19b997af148da717eae04d0c30274276a654999f8d3bac9254bf3e7098f9f0fedfaba00744961e734f54f8dfa0db009620be9c3cd7d7891b5886400af1c4ee6c
|
|
7
|
+
data.tar.gz: c7ec92a9b09af0c7797fac7c567b869a0fe0faeacdcae1ad5d7c2312c0051c5f91272f22beba34789b0856ac3bb656c3ceeb10eebd08831855de9e0fb90e113f
|
data/CHANGELOG.adoc
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
= Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Elkrb are recorded here.
|
|
4
|
+
|
|
5
|
+
== 2.0.0 (2026-10-10)
|
|
6
|
+
|
|
7
|
+
=== Breaking changes
|
|
8
|
+
|
|
9
|
+
* `NodeConstraints` now writes YAML in snake_case, like every other model in
|
|
10
|
+
the gem. `fixedPosition`, `alignGroup`, `alignDirection`, `relativeTo`,
|
|
11
|
+
`relativeOffset` and `positionPriority` are still read, so old documents keep
|
|
12
|
+
parsing, but they are no longer produced. Code that reads the camelCase keys
|
|
13
|
+
out of generated YAML must be updated. JSON and the other key-value formats
|
|
14
|
+
are unchanged and stay camelCase.
|
|
15
|
+
|
|
16
|
+
* `Elkrb.layout` and `Elkrb::Layout::LayoutEngine.layout` now raise
|
|
17
|
+
`ArgumentError` when the graph is neither a `Hash` nor an
|
|
18
|
+
`Elkrb::Graph::Graph`. Before, other objects were accepted and failed later
|
|
19
|
+
with a `NoMethodError`, or silently did nothing. Anything passing a wrapper
|
|
20
|
+
or a duck-typed graph has to pass a real `Graph` now.
|
|
21
|
+
|
|
22
|
+
* Ruby 3.3 or newer is required. Older Rubies cannot load `lutaml-model` 0.8.
|
|
23
|
+
|
|
24
|
+
* `Elkrb::Graph::LayoutOptions` and its typed getters are gone. `layoutOptions`
|
|
25
|
+
is an open map read by id, so pass a plain String-keyed Hash. Writing a
|
|
26
|
+
Symbol key into the returned map in place now stores the Symbol as given;
|
|
27
|
+
use String keys, or assign the whole map through the setter, which still
|
|
28
|
+
normalises. (#4, #10)
|
|
29
|
+
+
|
|
30
|
+
[source,ruby]
|
|
31
|
+
----
|
|
32
|
+
# before
|
|
33
|
+
Elkrb::Graph::LayoutOptions.new(algorithm: "layered")
|
|
34
|
+
# after
|
|
35
|
+
{ "elk.algorithm" => "layered" }
|
|
36
|
+
----
|
|
37
|
+
|
|
38
|
+
* Unparseable ELKT raises `Elkrb::ParseError` with a line and column. It used
|
|
39
|
+
to return an empty graph. Rescue `Elkrb::ParseError` where you relied on
|
|
40
|
+
the empty graph. (#17)
|
|
41
|
+
+
|
|
42
|
+
[source,ruby]
|
|
43
|
+
----
|
|
44
|
+
Elkrb::Parsers::ElktParser.parse("<html><body>not elkt</body></html>")
|
|
45
|
+
# before: {"id":"root","layoutOptions":{},"children":[],"edges":[]}
|
|
46
|
+
# after: Elkrb::ParseError: Unexpected character "<" at line 1, column 1
|
|
47
|
+
----
|
|
48
|
+
|
|
49
|
+
* Layered defaults to direction `RIGHT` with a 20px gap between layers, and
|
|
50
|
+
cross-axis positions are centred. Set `"elk.direction": "DOWN"` and
|
|
51
|
+
`"elk.layered.spacing.nodeNodeBetweenLayers": 60` to approximate 1.x.
|
|
52
|
+
Layered reads the direction from `elk.direction` and, as a registered alias,
|
|
53
|
+
from the bare `direction` key. (#58)
|
|
54
|
+
+
|
|
55
|
+
Two nodes joined by one edge, default options:
|
|
56
|
+
+
|
|
57
|
+
[source,text]
|
|
58
|
+
----
|
|
59
|
+
before: a (12, 12) b (12, 102)
|
|
60
|
+
after: a (12, 12) b (62, 12)
|
|
61
|
+
----
|
|
62
|
+
|
|
63
|
+
* Edge sections start and end on node borders instead of node centres, section
|
|
64
|
+
ids change from `<edge>_section_0` to `<edge>_s0`, and sections gain
|
|
65
|
+
`incomingShape` and `outgoingShape`. Renderers that clipped centre-based
|
|
66
|
+
lines themselves should stop doing so. (#67)
|
|
67
|
+
+
|
|
68
|
+
[source,text]
|
|
69
|
+
----
|
|
70
|
+
before: {"id":"e_section_0","startPoint":{"x":27.0,"y":27.0},"endPoint":{"x":27.0,"y":117.0}}
|
|
71
|
+
after: {"id":"e_s0","startPoint":{"x":42.0,"y":27.0},"endPoint":{"x":62.0,"y":27.0},
|
|
72
|
+
"incomingShape":"a","outgoingShape":"b"}
|
|
73
|
+
----
|
|
74
|
+
|
|
75
|
+
* Label `x` and `y` are relative to their owner (node, port or edge) instead of
|
|
76
|
+
absolute, so add the owner's position when drawing. A node label with no
|
|
77
|
+
`elk.nodeLabels.placement` stays at (0, 0); set
|
|
78
|
+
`"elk.nodeLabels.placement": "[H_CENTER,V_CENTER,INSIDE]"` to keep it
|
|
79
|
+
centred. (#65)
|
|
80
|
+
+
|
|
81
|
+
A 60x40 node at (12,12) with a 10x10 label:
|
|
82
|
+
+
|
|
83
|
+
[source,text]
|
|
84
|
+
----
|
|
85
|
+
before: {"text":"A","x":37.0,"y":27.0}
|
|
86
|
+
after, no placement option: {"text":"A","x":0.0,"y":0.0}
|
|
87
|
+
after, placement as above: {"text":"A","x":25.0,"y":15.0}
|
|
88
|
+
----
|
|
89
|
+
|
|
90
|
+
* The `_constraint_*` and `_assigned_layer` scratch keys no longer appear in
|
|
91
|
+
output `properties`, and constraint violations go through `Elkrb.logger`
|
|
92
|
+
instead of `Kernel#warn`. `ConstraintProcessor.new` takes `spacing:` and
|
|
93
|
+
`BaseConstraint#applies_to?` is removed. Stop reading the scratch keys.
|
|
94
|
+
(#66)
|
|
95
|
+
+
|
|
96
|
+
[source,text]
|
|
97
|
+
----
|
|
98
|
+
before: {"id":"a","constraints":{"fixedPosition":false,"layer":1,"positionPriority":0},
|
|
99
|
+
"properties":{"_constraint_layer":1}}
|
|
100
|
+
after: {"id":"a","constraints":{"fixedPosition":false,"layer":1,"positionPriority":0}}
|
|
101
|
+
----
|
|
102
|
+
|
|
103
|
+
* mrtree and radial coordinates follow ELK's geometry. mrtree honours
|
|
104
|
+
`elk.direction`, and radial reads the graph's edges and centres the root.
|
|
105
|
+
There is nothing to migrate; the old coordinates did not match ELK. (#55)
|
|
106
|
+
+
|
|
107
|
+
Root `r` with children `c1` and `c2`, 30x30 nodes, mrtree:
|
|
108
|
+
+
|
|
109
|
+
[source,text]
|
|
110
|
+
----
|
|
111
|
+
before: r (12, 12) c1 (12, 102) c2 (62, 102)
|
|
112
|
+
after: r (45, 20) c1 (20, 70) c2 (70, 70)
|
|
113
|
+
----
|
|
114
|
+
|
|
115
|
+
* Force layout runs a deterministic Fruchterman-Reingold simulation using node
|
|
116
|
+
sizes, with ELK's 50px default padding; explicit padding still wins. Every
|
|
117
|
+
force coordinate changes. (#69)
|
|
118
|
+
+
|
|
119
|
+
The same graph with `"elk.algorithm": "force"`:
|
|
120
|
+
+
|
|
121
|
+
[source,text]
|
|
122
|
+
----
|
|
123
|
+
before: r (12, 12) c1 (12, 102) c2 (62, 102)
|
|
124
|
+
after: r (115.648, 106.874) c1 (50, 163.785) c2 (181.253, 50)
|
|
125
|
+
----
|
|
126
|
+
|
|
127
|
+
* libavoid keeps nodes that already have a position and places only the
|
|
128
|
+
unplaced ones, in a grid to the right of the placed nodes. To get a full
|
|
129
|
+
re-layout, position every node or none. (#60)
|
|
130
|
+
+
|
|
131
|
+
`a` at (5, 7), `b` at (200, 9) and an unplaced `c`:
|
|
132
|
+
+
|
|
133
|
+
[source,text]
|
|
134
|
+
----
|
|
135
|
+
before: a (12, 12) b (62, 12) c (112, 12)
|
|
136
|
+
after: a (12, 12) b (207, 14) c (257, 12)
|
|
137
|
+
----
|
|
138
|
+
|
|
139
|
+
* An edge written with the elkjs primitive keys `source` and `target` is now a
|
|
140
|
+
real edge, so the graph lays out differently. (#16)
|
|
141
|
+
+
|
|
142
|
+
[source,text]
|
|
143
|
+
----
|
|
144
|
+
before: {"id":"e"}
|
|
145
|
+
after: {"id":"e","sources":["a"],"targets":["b"],
|
|
146
|
+
"sections":[{"id":"e_s0","startPoint":{"x":42.0,"y":27.0},
|
|
147
|
+
"endPoint":{"x":62.0,"y":27.0},
|
|
148
|
+
"incomingShape":"a","outgoingShape":"b"}]}
|
|
149
|
+
----
|
|
150
|
+
|
|
151
|
+
* Ports are placed on their node's border. Each port now carries `x`, `y` and
|
|
152
|
+
`side`, and `offset` is filled in, where before a port had only `index` and
|
|
153
|
+
`offset: 0`. Edge sections that start or end at a port move to match. Code
|
|
154
|
+
that computed port positions itself should read these fields. (#70)
|
|
155
|
+
+
|
|
156
|
+
Node `a` with a 6x6 port `p`, edge `p` to `b`:
|
|
157
|
+
+
|
|
158
|
+
[source,text]
|
|
159
|
+
----
|
|
160
|
+
before: port {"id":"p","index":0,"offset":0.0}
|
|
161
|
+
section start (12.0, 12.0)
|
|
162
|
+
after: port {"id":"p","x":30.0,"y":12.0,"side":"EAST","index":0,"offset":12.0}
|
|
163
|
+
section start (48.0, 27.0)
|
|
164
|
+
----
|
|
165
|
+
|
|
166
|
+
* Layered orders the nodes within a layer by a barycenter sweep, so cross-axis
|
|
167
|
+
coordinates move whenever a layer holds more than one node.
|
|
168
|
+
`elk.layered.crossingMinimization.strategy` and
|
|
169
|
+
`elk.layered.considerModelOrder.strategy` are now honoured. Set
|
|
170
|
+
`elk.layered.crossingMinimization.strategy` to `NONE` to get insertion order
|
|
171
|
+
back. (#72)
|
|
172
|
+
+
|
|
173
|
+
Edges `a` to `d` and `b` to `c`, default options:
|
|
174
|
+
+
|
|
175
|
+
[source,text]
|
|
176
|
+
----
|
|
177
|
+
before: a (12, 12) b (12, 62) c (62, 12) d (62, 62)
|
|
178
|
+
after: a (12, 12) b (12, 62) c (62, 62) d (62, 12)
|
|
179
|
+
after, NONE: a (12, 12) b (12, 62) c (62, 12) d (62, 62)
|
|
180
|
+
----
|
|
181
|
+
|
|
182
|
+
* Self-loops leave and enter the node border and are routed outside the node
|
|
183
|
+
instead of retracing themselves, and their section id changes from
|
|
184
|
+
`<edge>_section_0` to `<edge>_s0`. An edge between two ports of the same node
|
|
185
|
+
is now routed as a loop too. Code that matches the old section id or the old
|
|
186
|
+
geometry must accept the new one. (#74)
|
|
187
|
+
+
|
|
188
|
+
Node `a` (30x30) with an edge from `a` to `a`:
|
|
189
|
+
+
|
|
190
|
+
[source,text]
|
|
191
|
+
----
|
|
192
|
+
before: {"id":"e_section_0","startPoint":{"x":42.0,"y":27.0},"endPoint":{"x":42.0,"y":37.0},
|
|
193
|
+
"bendPoints":[{"x":74.0,"y":27.0},{"x":74.0,"y":-5.0},{"x":74.0,"y":59.0},{"x":42.0,"y":32.0}]}
|
|
194
|
+
after: {"id":"e_s0","startPoint":{"x":42.0,"y":22.0},"endPoint":{"x":42.0,"y":32.0},
|
|
195
|
+
"bendPoints":[{"x":74.0,"y":22.0},{"x":74.0,"y":32.0}],
|
|
196
|
+
"incomingShape":"a","outgoingShape":"a"}
|
|
197
|
+
----
|
|
198
|
+
|
|
199
|
+
* `elkrb layout` rejects an unknown switch with `Unknown switches "--bogus"`
|
|
200
|
+
and a `Try: elkrb help layout` line. It used to read the switch as the input
|
|
201
|
+
file and fail with "no such file". `layout --output out.yml` now writes YAML,
|
|
202
|
+
where it wrote JSON; pass `--format json` to keep JSON. (#62)
|
|
203
|
+
+
|
|
204
|
+
`elkrb layout --bogus graph.json`:
|
|
205
|
+
+
|
|
206
|
+
[source,text]
|
|
207
|
+
----
|
|
208
|
+
before: ERROR: "elkrb layout" was called with arguments ["--bogus", "graph.json"]
|
|
209
|
+
after: Unknown switches "--bogus"
|
|
210
|
+
Try: elkrb help layout
|
|
211
|
+
----
|
|
212
|
+
|
|
213
|
+
* `sig/` is deleted and `rbs` is no longer a runtime dependency; the
|
|
214
|
+
signatures did not load. The gem ships an explicit file list (`lib`, `exe`,
|
|
215
|
+
`README.adoc`, `LICENSE`, `CHANGELOG.adoc`) instead of every tracked file,
|
|
216
|
+
so benchmarks, examples, docs and dotfiles are no longer packaged. (#77, #84)
|
|
217
|
+
|
|
218
|
+
* Layered routes an edge that spans more than one layer around the nodes in
|
|
219
|
+
between, through a dummy lane with bend points. Nodes in the spanned layers
|
|
220
|
+
can move on the cross axis to make room. Nothing to migrate: the old route
|
|
221
|
+
could cross straight through a node. (#76)
|
|
222
|
+
+
|
|
223
|
+
Edges a->b, b->c and a->c, default options:
|
|
224
|
+
+
|
|
225
|
+
[source,text]
|
|
226
|
+
----
|
|
227
|
+
before: b (62, 12) a->c bends []
|
|
228
|
+
after: b (62, 37) a->c bends [(77, 2)]
|
|
229
|
+
----
|
|
230
|
+
|
|
231
|
+
* A graph's own `elk.algorithm` now wins over the `algorithm:` keyword of
|
|
232
|
+
`Elkrb.layout`. Before, the keyword won and the graph's value was ignored.
|
|
233
|
+
The keyword is now the fallback for graphs that name no algorithm. To force
|
|
234
|
+
an algorithm on a graph that already names one, set `elk.algorithm` on the
|
|
235
|
+
graph. (#50)
|
|
236
|
+
+
|
|
237
|
+
A graph with `"elk.algorithm": "box"`, two 30x30 nodes, called with
|
|
238
|
+
`algorithm: "force"`:
|
|
239
|
+
+
|
|
240
|
+
[source,text]
|
|
241
|
+
----
|
|
242
|
+
before: runs force a (12, 12) b (23.09, 14.34)
|
|
243
|
+
after: runs box a (15, 15) b (60, 15)
|
|
244
|
+
----
|
|
245
|
+
|
|
246
|
+
* A duplicate node id, or a duplicate port id, within one level raises
|
|
247
|
+
`Elkrb::ValidationError` (`duplicate id: a`). Before, a duplicate node
|
|
248
|
+
failed with a `NoMethodError` and a duplicate port was silently accepted.
|
|
249
|
+
The same id may still appear at different levels. Duplicate edge ids are
|
|
250
|
+
not checked. (#5)
|
|
251
|
+
|
|
252
|
+
* Layered raises `Elkrb::UnsupportedConfigurationException` for an edge with
|
|
253
|
+
more than one source or more than one target (`layered does not support
|
|
254
|
+
hyperedges (edge e)`); it used to lay the graph out.
|
|
255
|
+
Layered also no longer rewrites your edges to break cycles, so a back edge
|
|
256
|
+
keeps its source and target and `properties["reversed"]` is never written.
|
|
257
|
+
Stop reading that key.
|
|
258
|
+
+
|
|
259
|
+
[source,text]
|
|
260
|
+
----
|
|
261
|
+
cycle a->b, b->c, c->a
|
|
262
|
+
before: e3 {"sources":["a"],"targets":["c"],"properties":{"reversed":true}}
|
|
263
|
+
after: e3 {"sources":["c"],"targets":["a"]}
|
|
264
|
+
----
|
|
265
|
+
|
|
266
|
+
* The `hierarchical` option does nothing. Hierarchy is detected from nodes that
|
|
267
|
+
have `children`, as before when the option was unset, and `hierarchical`
|
|
268
|
+
is now reported as an unknown option under `strict: true`. A compound node
|
|
269
|
+
is laid out before its parent level, so the parent level places its siblings
|
|
270
|
+
against the compound's computed size instead of the `width` and `height` it
|
|
271
|
+
declared. A compound that names its own `elk.algorithm` is still laid out by
|
|
272
|
+
it, but an unknown name now raises `Elkrb::AlgorithmNotFoundError` where
|
|
273
|
+
the parent's algorithm used to be used quietly. (#63)
|
|
274
|
+
+
|
|
275
|
+
Compound `c` declaring 500x500 and holding two 20x20 nodes, with a sibling
|
|
276
|
+
`z` linked from `c`:
|
|
277
|
+
+
|
|
278
|
+
[source,text]
|
|
279
|
+
----
|
|
280
|
+
before: c 84x44 z (532, 252)
|
|
281
|
+
after: c 84x44 z (116, 24)
|
|
282
|
+
----
|
|
283
|
+
|
|
284
|
+
* `fixed` keeps each node where its `x` and `y` put it, and reads
|
|
285
|
+
`elk.position`. It used to move the nodes so the top-left one sat at the
|
|
286
|
+
padding origin and to ignore `elk.position`. `box` uses a different packing,
|
|
287
|
+
so box coordinates and the graph size change. (#59)
|
|
288
|
+
+
|
|
289
|
+
[source,text]
|
|
290
|
+
----
|
|
291
|
+
fixed, a at (100, 50) and b at (200, 80):
|
|
292
|
+
before: a (12, 12) b (112, 42)
|
|
293
|
+
after: a (100, 50) b (200, 80)
|
|
294
|
+
|
|
295
|
+
box, four 30x30 nodes:
|
|
296
|
+
before: 154x104 n0 (12, 12) n1 (62, 12) n2 (112, 12) n3 (12, 62)
|
|
297
|
+
after: 105x105 n0 (15, 15) n1 (60, 15) n2 (15, 60) n3 (60, 60)
|
|
298
|
+
----
|
|
299
|
+
|
|
300
|
+
=== Added
|
|
301
|
+
|
|
302
|
+
* Edges read the elkjs primitive endpoint keys `source`, `target`,
|
|
303
|
+
`sourcePort` and `targetPort` in every format, YAML included. A blank port
|
|
304
|
+
value is ignored, so a real `source` or `target` still wins. Output stays
|
|
305
|
+
`sources` and `targets` only.
|
|
306
|
+
|
|
307
|
+
* `junctionPoints`, `container`, `incomingSections` and `outgoingSections` on
|
|
308
|
+
edges, and `properties` on labels, are no longer dropped when parsing.
|
|
309
|
+
|
|
310
|
+
* `elkrb options [ALGORITHM]` lists every layout option with its type,
|
|
311
|
+
default, status, aliases and the algorithms that read it; `--json` prints
|
|
312
|
+
the same as JSON. `elkrb algorithms --json` is new. `batch` and `diagram`
|
|
313
|
+
accept the same layout flags as `layout`, including `--spacing`
|
|
314
|
+
and `--layer-spacing`. (#62)
|
|
315
|
+
|
|
316
|
+
* A `LICENSE` file (BSD-2-Clause, as the gemspec already declared) ships with
|
|
317
|
+
the gem. (#77)
|
|
318
|
+
|
|
319
|
+
=== Fixed
|
|
320
|
+
|
|
321
|
+
* `Rectangle#position` and `Rectangle#center` no longer raise.
|
|
322
|
+
|
|
323
|
+
* `Bezier.calculate_curve` with fewer than two sample points returns copies of
|
|
324
|
+
the two endpoints instead of the caller's own `Point` objects. Its fifth
|
|
325
|
+
parameter is now named `sample_count`, which is what it always counted.
|
|
326
|
+
|
|
327
|
+
* Validation now checks nested container scopes, collection shapes, finite
|
|
328
|
+
dimensions and option enum values. It rejects ambiguous hierarchical edge
|
|
329
|
+
endpoints, and the `HORIZONTAL` and `VERTICAL` direction aliases produce
|
|
330
|
+
valid layouts. Validation output remains readable on US-ASCII terminals.
|
|
331
|
+
|
|
332
|
+
* Failed conversions and Graphviz renders preserve an existing destination
|
|
333
|
+
instead of replacing it with a partial result.
|
|
334
|
+
|
|
335
|
+
* ELKT output preserves representable graph geometry, edge sections, ports and
|
|
336
|
+
hierarchy. DOT output keeps same-named nodes in different hierarchy scopes
|
|
337
|
+
distinct and routes scoped and hierarchical port endpoints without creating
|
|
338
|
+
phantom nodes.
|
|
339
|
+
|
|
340
|
+
* `elk.selfLoopOffset` is honoured when it is carried by an edge or its node.
|
|
341
|
+
|
|
342
|
+
=== Changed
|
|
343
|
+
|
|
344
|
+
* `lutaml-model` is now capped below 0.9.
|
|
345
|
+
|
|
346
|
+
* Layered layout uses ELK-style Brandes-Kopf placement, layer sweeps, discovery
|
|
347
|
+
and port ordering, per-gap orthogonal routing with junction points, and
|
|
348
|
+
connected-component packing. Node coordinates and edge routes can differ
|
|
349
|
+
from earlier releases.
|
|
350
|
+
|
|
351
|
+
* DisCo defaults to ELK's polyomino component compaction. Set the component
|
|
352
|
+
arrangement or compaction strategy to `ROW` to retain row arrangement.
|
|
353
|
+
|
|
354
|
+
* SPOrE overlap removal and compaction follow Java ELK's triangulation and tree
|
|
355
|
+
algorithms and honour their registered processing options.
|
|
356
|
+
|
|
357
|
+
* Stress layout uses ELK-compatible deterministic seeding and the weighted
|
|
358
|
+
stress objective. Large line-metric graphs with the default iteration limit
|
|
359
|
+
use an exact projection, avoiding the previous quadratic timeout.
|
|
360
|
+
|
|
361
|
+
=== Security
|
|
362
|
+
|
|
363
|
+
* Release automation uses SHA-pinned actions, least-privilege jobs and
|
|
364
|
+
RubyGems OIDC trusted publishing instead of a long-lived API key.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Ribose Inc.
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|