Class: RailroadDiagrams::Sequence
- Inherits:
-
DiagramMultiContainer
- Object
- DiagramMultiContainer
- RailroadDiagrams::Sequence
- Defined in:
- lib/railroad_diagrams/sequence.rb,
sig/generated/railroad_diagrams/sequence.rbs
Overview
Draws items in reading order along one path.
Instance Method Summary collapse
- #add_edge_paths(x, y, left_gap, right_gap) ⇒ void
- #add_leading_space(x, y, item, index) ⇒ Numeric
- #add_trailing_space(x, y, item, index) ⇒ Numeric
- #calculate_dimensions ⇒ void
- #child_nodes ⇒ Array[DiagramItem]
- #format(x, y, width) ⇒ Sequence
- #format_items(x, y) ⇒ void
- #format_single_item(item, index, x, y) ⇒ [ Numeric, Numeric ]
-
#initialize(*items, id: nil, cls: nil, attrs: {}) ⇒ Sequence
constructor
A new instance of Sequence.
- #measure(context) ⇒ Metrics
- #render_svg(context, x, y, width) ⇒ Svg::Element
- #render_text(context) ⇒ TextDiagram
- #svg_path(x, y, length) ⇒ Svg::Element
- #text_diagram ⇒ TextDiagram
- #to_s ⇒ String
Constructor Details
#initialize(*items, id: nil, cls: nil, attrs: {}) ⇒ Sequence
Returns a new instance of Sequence.
11 12 13 14 15 |
# File 'lib/railroad_diagrams/sequence.rb', line 11 def initialize(*items, id: nil, cls: nil, attrs: {}) super('g', items, nil, nil, id: id, cls: cls, data_attrs: attrs) @needs_space = true calculate_dimensions end |
Instance Method Details
#add_edge_paths(x, y, left_gap, right_gap) ⇒ void
This method returns an undefined value.
149 150 151 152 |
# File 'lib/railroad_diagrams/sequence.rb', line 149 def add_edge_paths(x, y, left_gap, right_gap) Path.new(x, y).h(left_gap).add(self) Path.new(x + left_gap + @width, y + @height).h(right_gap).add(self) end |
#add_leading_space(x, y, item, index) ⇒ Numeric
182 183 184 185 186 187 |
# File 'lib/railroad_diagrams/sequence.rb', line 182 def add_leading_space(x, y, item, index) return x unless item.needs_space && index.positive? Path.new(x, y).h(10).add(self) x + 10 end |
#add_trailing_space(x, y, item, index) ⇒ Numeric
194 195 196 197 198 199 |
# File 'lib/railroad_diagrams/sequence.rb', line 194 def add_trailing_space(x, y, item, index) return x unless item.needs_space && index < @items.length - 1 Path.new(x, y).h(10).add(self) x + 10 end |
#calculate_dimensions ⇒ void
This method returns an undefined value.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/railroad_diagrams/sequence.rb', line 127 def calculate_dimensions @up = 0 @down = 0 @height = 0 @width = 0 @items.each do |item| @width += item.width + (item.needs_space ? 20 : 0) @up = [@up, item.up - @height].max @height += item.height @down = [@down - item.height, item.down].max end @width -= 10 if @items.first&.needs_space @width -= 10 if @items.last&.needs_space end |
#child_nodes ⇒ Array[DiagramItem]
112 113 114 |
# File 'lib/railroad_diagrams/sequence.rb', line 112 def child_nodes @items.dup end |
#format(x, y, width) ⇒ Sequence
27 28 29 30 31 32 |
# File 'lib/railroad_diagrams/sequence.rb', line 27 def format(x, y, width) left_gap, right_gap = determine_gaps(width, @width) add_edge_paths(x, y, left_gap, right_gap) format_items(x + left_gap, y) self end |
#format_items(x, y) ⇒ void
This method returns an undefined value.
157 158 159 160 161 |
# File 'lib/railroad_diagrams/sequence.rb', line 157 def format_items(x, y) @items.each_with_index do |item, i| x, y = format_single_item(item, i, x, y) end end |
#format_single_item(item, index, x, y) ⇒ [ Numeric, Numeric ]
168 169 170 171 172 173 174 175 |
# File 'lib/railroad_diagrams/sequence.rb', line 168 def format_single_item(item, index, x, y) x = add_leading_space(x, y, item, index) item.format(x, y, item.width).add(self) x += item.width y += item.height x = add_trailing_space(x, y, item, index) [x, y] end |
#measure(context) ⇒ Metrics
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/railroad_diagrams/sequence.rb', line 46 def measure(context) up = 0 down = 0 height = 0 width = 0 metrics = @items.map { |item| context.metrics(item) } metrics.each do |child| width += child.width + (child.needs_space ? 20 : 0) up = [up, child.up - height].max height += child.height down = [down - child.height, child.down].max end width -= 10 if metrics.first&.needs_space width -= 10 if metrics.last&.needs_space Metrics.new(width: width, up: up, height: height, down: down, needs_space: true) end |
#render_svg(context, x, y, width) ⇒ Svg::Element
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/railroad_diagrams/sequence.rb', line 70 def render_svg(context, x, y, width) metrics = context.metrics(self) left_gap, right_gap = context.gaps(width, metrics.width) group = Svg::Element.new('g', @attrs.dup) group << svg_path(x, y, left_gap) group << svg_path(x + left_gap + metrics.width, y + metrics.height, right_gap) x += left_gap @items.each_with_index do |item, index| child = context.metrics(item) if child.needs_space && index.positive? group << svg_path(x, y, 10) x += 10 end group << context.render_svg(item, x, y, child.width) x += child.width y += child.height if child.needs_space && index < @items.length - 1 group << svg_path(x, y, 10) x += 10 end end group end |
#render_text(context) ⇒ TextDiagram
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/railroad_diagrams/sequence.rb', line 97 def render_text(context) line = context.parts.fetch('line') diagrams = @items.map do |item| diagram = item.render_text(context) next diagram unless context.metrics(item).needs_space spaced_lines = diagram.lines.each_with_index.map do |text, index| "#{index == diagram.entry ? line : ' '}#{text}#{index == diagram.exit ? line : ' '}" end TextDiagram.new(diagram.entry, diagram.exit, spaced_lines) end Text::Builder.row([TextDiagram.new(0, 0, ['']), *diagrams], context.parts.fetch('separator')) end |
#svg_path(x, y, length) ⇒ Svg::Element
122 123 124 |
# File 'lib/railroad_diagrams/sequence.rb', line 122 def svg_path(x, y, length) Svg::Element.new('path', { 'd' => Svg::PathData.new(x, y).h(length) }, self_closing: true) end |
#text_diagram ⇒ TextDiagram
35 36 37 38 39 40 41 42 |
# File 'lib/railroad_diagrams/sequence.rb', line 35 def text_diagram separator, = TextDiagram.get_parts(['separator']) @items.reduce(TextDiagram.new(0, 0, [''])) do |diagram_td, item| item_td = item.text_diagram item_td = item_td.(1, 1, 0, 0) if item.needs_space diagram_td.append_right(item_td, separator) end end |
#to_s ⇒ String
18 19 20 21 |
# File 'lib/railroad_diagrams/sequence.rb', line 18 def to_s items = @items.map(&:to_s).join(', ') "Sequence(#{items})" end |