Class: RailroadDiagrams::Group

Inherits:
DiagramItem show all
Defined in:
lib/railroad_diagrams/group.rb,
sig/generated/railroad_diagrams/group.rbs

Overview

Encloses a path in a labeled or unlabeled box.

Examples:

Group.new('SELECT', label: 'keyword')

Instance Attribute Summary

Attributes inherited from DiagramItem

#attrs, #children, #down, #height, #needs_space, #up, #width

Instance Method Summary collapse

Methods inherited from DiagramItem

#==, #add, #apply_user_attributes, #container_element?, #determine_gaps, #each_node, #hash, inherited, #inspect, #structural_state, #to_str, #wrap_string, #write_children, #write_opening_tag, #write_standalone, #write_svg

Constructor Details

#initialize(item, legacy_label = Deprecation::UNSET, label: Deprecation::UNSET, id: nil, cls: nil, attrs: {}) ⇒ Group

Returns a new instance of Group.

Parameters:

  • item (DiagramItem, String)
  • legacy_label (Object) (defaults to: Deprecation::UNSET)
  • label: (DiagramItem, String, nil) (defaults to: Deprecation::UNSET)
  • id: (Object) (defaults to: nil)
  • cls: (Object) (defaults to: nil)
  • attrs: (Object) (defaults to: {})


12
13
14
15
16
17
18
19
20
# File 'lib/railroad_diagrams/group.rb', line 12

def initialize(item, legacy_label = Deprecation::UNSET, label: Deprecation::UNSET,
               id: nil, cls: nil, attrs: {})
  super('g', id: id, cls: cls, data_attrs: attrs)
  @item = wrap_string(item)
  @label = prepare_label(Deprecation.positional_argument('label', legacy_label, label))
  @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.

Parameters:

  • x (Numeric)
  • y (Numeric)
  • left_gap (Numeric)
  • right_gap (Numeric)


139
140
141
142
# File 'lib/railroad_diagrams/group.rb', line 139

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_group_box(x, y) ⇒ void

This method returns an undefined value.

Parameters:

  • x (Numeric)
  • y (Numeric)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/railroad_diagrams/group.rb', line 147

def add_group_box(x, y)
  DiagramItem.new(
    'rect',
    attrs: {
      'x' => x,
      'y' => y - @box_up,
      'width' => @width,
      'height' => @height + @box_up + @down,
      'rx' => AR,
      'ry' => AR,
      'class' => 'group-box'
    }
  ).add(self)
end

#calculate_dimensions ⇒ void

This method returns an undefined value.



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/railroad_diagrams/group.rb', line 120

def calculate_dimensions
  item_width = @item.width + (@item.needs_space ? 20 : 0)
  label_width = @label&.width || 0
  @width = [item_width, label_width, AR * 2].max

  @height = @item.height

  @box_up = [@item.up + VS, AR].max
  @up = @box_up
  @up += @label.up + @label.height + @label.down if @label

  @down = [@item.down + VS, AR].max
end

#child_nodes ⇒ Object

Returns:

  • (Object)


104
105
106
# File 'lib/railroad_diagrams/group.rb', line 104

def child_nodes
  @label ? [@item, @label] : [@item]
end

#format(x, y, width) ⇒ Group

Parameters:

  • x (Numeric)
  • y (Numeric)
  • width (Numeric)

Returns:



31
32
33
34
35
36
37
38
39
40
# File 'lib/railroad_diagrams/group.rb', line 31

def format(x, y, width)
  left_gap, right_gap = determine_gaps(width, @width)
  add_edge_paths(x, y, left_gap, right_gap)
  x += left_gap

  add_group_box(x, y)
  format_contents(x, y)

  self
end

#format_contents(x, y) ⇒ void

This method returns an undefined value.

Parameters:

  • x (Numeric)
  • y (Numeric)


165
166
167
168
# File 'lib/railroad_diagrams/group.rb', line 165

def format_contents(x, y)
  @item.format(x, y, @width).add(self)
  @label&.format(x, y - (@box_up + @label.down + @label.height), @label.width)&.add(self)
end

#measure(context) ⇒ Object

Parameters:

  • context (Object)

Returns:

  • (Object)


60
61
62
63
64
65
66
67
68
69
70
# File 'lib/railroad_diagrams/group.rb', line 60

def measure(context)
  item = context.metrics(@item)
  label = context.metrics(@label) if @label
  arc = context.options.arc_radius
  separation = context.options.vertical_separation
  item_width = item.width + (item.needs_space ? 20 : 0)
  box_up = [item.up + separation, arc].max
  Metrics.new(width: [item_width, label ? label.width : 0, arc * 2].max,
              up: box_up + (label ? label.up + label.height + label.down : 0),
              height: item.height, down: [item.down + separation, arc].max, needs_space: true)
end

#prepare_label(label) ⇒ DiagramItem?

Parameters:

Returns:



112
113
114
115
116
117
# File 'lib/railroad_diagrams/group.rb', line 112

def prepare_label(label)
  return nil unless label
  return label if label.is_a?(DiagramItem)

  Comment.new(label)
end

#render_svg(context, x, y, width) ⇒ Object

Parameters:

  • context (Object)
  • x (Object)
  • y (Object)
  • width (Object)

Returns:

  • (Object)


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/group.rb', line 72

def render_svg(context, x, y, width)
  metrics = context.metrics(self)
  item = context.metrics(@item)
  left_gap, right_gap = context.gaps(width, metrics.width)
  group = Svg::Element.new('g', @attrs.dup)
  group << Svg::Element.new('path', { 'd' => Svg::PathData.new(x, y).h(left_gap) }, self_closing: true)
  group << Svg::Element.new('path', { 'd' => Svg::PathData.new(x + left_gap + metrics.width, y + metrics.height).h(right_gap) }, self_closing: true)
  x += left_gap

  arc = context.options.arc_radius
  box_up = [item.up + context.options.vertical_separation, arc].max
  box = { 'x' => x, 'y' => y - box_up, 'width' => metrics.width,
          'height' => metrics.height + box_up + metrics.down,
          'rx' => arc, 'ry' => arc, 'class' => 'group-box' }
  group << Svg::Element.new('rect', box)
  group << context.render_svg(@item, x, y, metrics.width)
  if @label
    label = context.metrics(@label)
    group << context.render_svg(@label, x, y - (box_up + label.down + label.height), label.width)
  end
  group
end

#render_text(context) ⇒ Object

Parameters:

  • context (Object)

Returns:

  • (Object)


95
96
97
98
99
100
101
102
# File 'lib/railroad_diagrams/group.rb', line 95

def render_text(context)
  diagram = TextDiagram.round_rect(@item.render_text(context), dashed: true, parts: context.parts)
  if @label
    label = @label.render_text(context)
    diagram = label.append_below(diagram, [], move_entry: true, move_exit: true).expand(0, 0, 1, 0)
  end
  diagram
end

#text_diagram ⇒ TextDiagram

Returns:

  • (TextDiagram)


51
52
53
54
55
56
57
58
# File 'lib/railroad_diagrams/group.rb', line 51

def text_diagram
  diagram_td = TextDiagram.round_rect(@item.text_diagram, dashed: true)
  if @label
    label_td = @label.text_diagram
    diagram_td = label_td.append_below(diagram_td, [], move_entry: true, move_exit: true).expand(0, 0, 1, 0)
  end
  diagram_td
end

#to_s ⇒ String

Returns:

  • (String)


23
24
25
# File 'lib/railroad_diagrams/group.rb', line 23

def to_s
  "Group(#{@item}, label=#{@label})"
end

#walk(callback) ⇒ void

This method returns an undefined value.



44
45
46
47
48
# File 'lib/railroad_diagrams/group.rb', line 44

def walk(callback)
  callback.call(self)
  @item.walk(callback)
  @label&.walk(callback)
end