https://github.com/seuros/diagram-ruby
https://github.com/seuros/diagram-ruby
code-generation developer-tools diagram dsl framework graph ruby ruby-gem structure visualization
Last synced: 24 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/seuros/diagram-ruby
- Owner: seuros
- License: mit
- Created: 2024-01-27T20:52:23.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2025-06-15T12:33:44.000Z (10 months ago)
- Last Synced: 2026-01-18T00:22:19.581Z (2 months ago)
- Topics: code-generation, developer-tools, diagram, dsl, framework, graph, ruby, ruby-gem, structure, visualization
- Language: Ruby
- Size: 142 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Diagrams Gem
[](https://badge.fury.io/rb/diagram)
**Diagrams** provides Ruby objects for defining and manipulating various diagram types (Flowcharts, Class Diagrams, Gantt Charts, Pie Charts, State Diagrams). It focuses on the *data structure and logic*, allowing other tools or gems to handle rendering (e.g., to Mermaid, Graphviz, etc.).
**Key Goals:**
* **Developer Experience & Extensibility:** Clean API, easy to extend.
* **Modern Ruby (3.3+):** Uses modern practices like RBS type signatures and `dry-rb` gems.
* **Uniform Capabilities:** Consistent serialization (Hash/JSON), comparison, versioning, and checksums across all diagram types.
* **Separation of Concerns:** Core gem handles data only, not rendering or persistence.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'diagram', '~> 0.3.0' # Or appropriate version constraint
```
And then execute:
```bash
bundle install
```
Or install it yourself as:
```bash
gem install diagram
```
## Usage
### Creating Diagrams
Require the gem and instantiate specific diagram classes.
```ruby
require 'diagram'
# --- Flowchart Example ---
flowchart = Diagrams::FlowchartDiagram.new(version: '1.0')
# Create nodes (using Diagrams::Elements::Node)
node1 = Diagrams::Elements::Node.new(id: 'start', label: 'Start Process')
node2 = Diagrams::Elements::Node.new(id: 'step1', label: 'Do Something')
node3 = Diagrams::Elements::Node.new(id: 'end', label: 'End Process')
# Add nodes to the diagram
flowchart.add_node(node1)
flowchart.add_node(node2)
flowchart.add_node(node3)
# Create and add edges (using Diagrams::Elements::Edge)
edge1 = Diagrams::Elements::Edge.new(source_id: 'start', target_id: 'step1')
edge2 = Diagrams::Elements::Edge.new(source_id: 'step1', target_id: 'end', label: 'Finished')
flowchart.add_edge(edge1)
flowchart.add_edge(edge2)
puts "Flowchart Nodes: #{flowchart.nodes.map(&:id)}"
# => Flowchart Nodes: ["start", "step1", "end"]
# --- Class Diagram Example ---
class_diagram = Diagrams::ClassDiagram.new(version: 2)
# Create class entities (using Diagrams::Elements::ClassEntity)
user_class = Diagrams::Elements::ClassEntity.new(
name: 'User',
attributes: ['id: Integer', 'email: String'],
methods: ['authenticate(password: String): Boolean']
)
order_class = Diagrams::Elements::ClassEntity.new(
name: 'Order',
attributes: ['order_id: Integer', 'amount: Float']
)
# Add classes
class_diagram.add_class(user_class)
class_diagram.add_class(order_class)
# Create and add relationships (using Diagrams::Elements::Relationship)
rel = Diagrams::Elements::Relationship.new(
source_class_name: 'User',
target_class_name: 'Order',
type: 'has_many',
label: 'places'
)
class_diagram.add_relationship(rel)
puts "Class Diagram Classes: #{class_diagram.classes.map(&:name)}"
# => Class Diagram Classes: ["User", "Order"]
# --- Pie Chart Example ---
pie_chart = Diagrams::PieDiagram.new(title: 'Browser Share', version: '2024-Q1')
# Create and add slices (using Diagrams::Elements::Slice)
slice1 = Diagrams::Elements::Slice.new(label: 'Chrome', value: 65.5)
slice2 = Diagrams::Elements::Slice.new(label: 'Firefox', value: 15.0)
slice3 = Diagrams::Elements::Slice.new(label: 'Safari', value: 10.5)
slice4 = Diagrams::Elements::Slice.new(label: 'Edge', value: 5.0)
# slice5 = Diagrams::Elements::Slice.new(label: 'Other', value: 4.0) # Total must be <= 100
pie_chart.add_slice(slice1)
pie_chart.add_slice(slice2)
pie_chart.add_slice(slice3)
pie_chart.add_slice(slice4)
# pie_chart.add_slice(slice5)
puts "Pie Chart Total: #{pie_chart.total_value}%"
# => Pie Chart Total: 96.0%
# (Examples for Gantt and State diagrams can be added similarly)
```
### Serialization & Deserialization
All diagrams can be serialized to a Hash or JSON string, and deserialized back into objects.
```ruby
# Serialization
flowchart_hash = flowchart.to_h
flowchart_json = flowchart.to_json
puts flowchart_json
# => {"type":"FlowchartDiagram","version":"1.0","checksum":"...","data":{"nodes":[...],"edges":[...]}}
# Deserialization (using the Base class factory)
loaded_flowchart = Diagrams::Base.from_json(flowchart_json)
# or
# loaded_flowchart = Diagrams::Base.from_hash(flowchart_hash)
puts "Loaded diagram type: #{loaded_flowchart.class}"
# => Loaded diagram type: Diagrams::FlowchartDiagram
puts "Loaded diagram version: #{loaded_flowchart.version}"
# => Loaded diagram version: 1.0
# Verify content equality (ignores version)
original_flowchart = Diagrams::FlowchartDiagram.new(
nodes: [node1, node2, node3],
edges: [edge1, edge2],
version: 'Different Version' # Version doesn't affect equality check
)
puts "Diagrams have same content? #{loaded_flowchart == original_flowchart}"
# => Diagrams have same content? true
```
### Versioning and Checksums
Each diagram has:
* `#version`: A user-managed field (passed during initialization) for tracking revisions.
* `#checksum`: An automatically calculated SHA256 hash of the diagram's content (nodes, edges, etc.). This changes whenever the content is modified via methods like `add_node`, `add_slice`, etc.
You can use the checksum to quickly detect if a diagram's content has changed. The `==` operator compares diagrams based on their type and checksum (content), ignoring the `version` field.
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `lib/diagrams/version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/seuros/diagram-ruby.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).