Class: Diagrams::GanttDiagram
- Defined in:
- lib/diagrams/gantt_diagram.rb
Overview
Represents a Gantt Chart diagram consisting of tasks over time, grouped into sections.
Constant Summary collapse
- DEFAULT_SECTION_TITLE =
'Default Section'
Instance Attribute Summary collapse
-
#sections ⇒ Object
readonly
Returns the value of attribute sections.
-
#title ⇒ Object
readonly
Returns the value of attribute title.
Attributes inherited from Base
Class Method Summary collapse
-
.from_h(data_hash, version:, checksum:) ⇒ GanttDiagram
Class method to create a GanttDiagram from a hash.
Instance Method Summary collapse
-
#add_section(section_title) ⇒ Elements::GanttSection
Adds a new section to the diagram.
-
#add_task(id:, label:, start:, duration:, status: nil) ⇒ Elements::Task
Adds a task to the current (last) section of the diagram.
-
#find_section(section_title) ⇒ Elements::GanttSection?
Finds a section by its title.
-
#find_task(task_id) ⇒ Element::Task?
Finds a task by its ID across all sections.
-
#identifiable_elements ⇒ Hash{Symbol => Array<Diagrams::Elements::Task>}
Returns a hash mapping element types to their collections for diffing.
-
#initialize(title: '', sections: [], version: 1) ⇒ GanttDiagram
constructor
Initializes a new GanttDiagram.
-
#to_h_content ⇒ Hash{Symbol => String | Array<Hash>}
Returns the specific content of the Gantt diagram as a hash.
Methods inherited from Base
#diff, from_hash, from_json, #to_h, #to_json
Constructor Details
#initialize(title: '', sections: [], version: 1) ⇒ GanttDiagram
Initializes a new GanttDiagram.
15 16 17 18 19 20 21 22 |
# File 'lib/diagrams/gantt_diagram.rb', line 15 def initialize(title: '', sections: [], version: 1) super(version:) @title = title.is_a?(String) ? title : '' @sections = Array(sections) ensure_default_section if @sections.empty? validate_elements! update_checksum! end |
Instance Attribute Details
#sections ⇒ Object (readonly)
Returns the value of attribute sections.
8 9 10 |
# File 'lib/diagrams/gantt_diagram.rb', line 8 def sections @sections end |
#title ⇒ Object (readonly)
Returns the value of attribute title.
8 9 10 |
# File 'lib/diagrams/gantt_diagram.rb', line 8 def title @title end |
Class Method Details
.from_h(data_hash, version:, checksum:) ⇒ GanttDiagram
Class method to create a GanttDiagram from a hash.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/diagrams/gantt_diagram.rb', line 132 def self.from_h(data_hash, version:, checksum:) title = data_hash[:title] || data_hash['title'] || '' sections_data = data_hash[:sections] || data_hash['sections'] || [] sections = sections_data.map do |section_h| section_data = section_h.transform_keys(&:to_sym) tasks_data = section_data[:tasks] || [] # Expect 'tasks' key in hash # Map task data to Task objects tasks = tasks_data.map do |task_h| task_data = task_h.transform_keys(&:to_sym) # Convert status back to symbol if it's a string and present task_data[:status] = task_data[:status].to_sym if task_data[:status].is_a?(String) Elements::Task.new(task_data) end Elements::GanttSection.new(title: section_data[:title], tasks: tasks) end diagram = new(title:, sections:, version:) # Optional: Verify checksum if checksum && diagram.checksum != checksum warn "Checksum mismatch for loaded GanttDiagram (version: #{version}). Expected #{checksum}, got #{diagram.checksum}." end diagram end |
Instance Method Details
#add_section(section_title) ⇒ Elements::GanttSection
Adds a new section to the diagram. Subsequent tasks will be added to this section.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/diagrams/gantt_diagram.rb', line 30 def add_section(section_title) clean_title = section_title.strip raise ArgumentError, "Section title '#{clean_title}' cannot be empty" if clean_title.empty? raise ArgumentError, "Section with title '#{clean_title}' already exists" if find_section(clean_title) # Remove default section if it's empty and we're adding a real one if @sections.size == 1 && @sections.first.title == DEFAULT_SECTION_TITLE && @sections.first.tasks.empty? # Check tasks for GanttSection @sections.clear end # Use GanttSection new_section = Elements::GanttSection.new(title: clean_title, tasks: []) @sections << new_section update_checksum! new_section end |
#add_task(id:, label:, start:, duration:, status: nil) ⇒ Elements::Task
Adds a task to the current (last) section of the diagram.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/diagrams/gantt_diagram.rb', line 57 def add_task(id:, label:, start:, duration:, status: nil) raise ArgumentError, 'Task ID cannot be empty' if id.nil? || id.strip.empty? raise ArgumentError, "Task with ID '#{id}' already exists" if find_task(id) new_task = Elements::Task.new( id:, label:, status:, start:, duration: ) current_section = @sections.last raise StandardError, 'Cannot add task: No section available.' unless current_section # Add task to the current section's 'tasks' array updated_tasks = current_section.tasks + [new_task] updated_section = Elements::GanttSection.new(title: current_section.title, tasks: updated_tasks) # Update the section in the main array current_section_index = @sections.index { |s| s.title == current_section.title } unless current_section_index raise StandardError, "Could not find index for current section '#{current_section.title}'" end @sections[current_section_index] = updated_section update_checksum! new_task end |
#find_section(section_title) ⇒ Elements::GanttSection?
Finds a section by its title.
100 101 102 |
# File 'lib/diagrams/gantt_diagram.rb', line 100 def find_section(section_title) @sections.find { |s| s.title == section_title } end |
#find_task(task_id) ⇒ Element::Task?
Finds a task by its ID across all sections.
93 94 95 |
# File 'lib/diagrams/gantt_diagram.rb', line 93 def find_task(task_id) all_tasks.find { |t| t.id == task_id } end |
#identifiable_elements ⇒ Hash{Symbol => Array<Diagrams::Elements::Task>}
Returns a hash mapping element types to their collections for diffing.
118 119 120 121 122 123 124 |
# File 'lib/diagrams/gantt_diagram.rb', line 118 def identifiable_elements { # Diffing based on tasks directly might be more useful than sections here tasks: all_tasks # sections: @sections # Could also diff sections if needed } end |
#to_h_content ⇒ Hash{Symbol => String | Array<Hash>}
Returns the specific content of the Gantt diagram as a hash.
107 108 109 110 111 112 113 |
# File 'lib/diagrams/gantt_diagram.rb', line 107 def to_h_content { title: @title, # Serialize sections, renaming 'periods' back to 'tasks' for clarity sections: @sections.map(&:to_h) # Use GanttSection's to_h directly } end |