etassia 0.1.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 +7 -0
- data/CHANGELOG.md +140 -0
- data/LICENSE +25 -0
- data/README.adoc +436 -0
- data/exe/etassia +7 -0
- data/lib/etassia/cli.rb +187 -0
- data/lib/etassia/commands/batch.rb +210 -0
- data/lib/etassia/commands/notation_loader.rb +22 -0
- data/lib/etassia/commands/render.rb +98 -0
- data/lib/etassia/commands/types.rb +33 -0
- data/lib/etassia/commands/version.rb +24 -0
- data/lib/etassia/corpus_type_names.rb +52 -0
- data/lib/etassia/diagram/architecture.rb +108 -0
- data/lib/etassia/diagram/base.rb +61 -0
- data/lib/etassia/diagram/block.rb +102 -0
- data/lib/etassia/diagram/c4.rb +337 -0
- data/lib/etassia/diagram/class_diagram.rb +466 -0
- data/lib/etassia/diagram/class_namespace.rb +17 -0
- data/lib/etassia/diagram/class_note.rb +17 -0
- data/lib/etassia/diagram/containment.rb +107 -0
- data/lib/etassia/diagram/er_diagram.rb +317 -0
- data/lib/etassia/diagram/error.rb +38 -0
- data/lib/etassia/diagram/flowchart.rb +419 -0
- data/lib/etassia/diagram/flowchart_label_text.rb +63 -0
- data/lib/etassia/diagram/gantt.rb +94 -0
- data/lib/etassia/diagram/generic_text.rb +30 -0
- data/lib/etassia/diagram/git_graph.rb +57 -0
- data/lib/etassia/diagram/info.rb +38 -0
- data/lib/etassia/diagram/kanban.rb +198 -0
- data/lib/etassia/diagram/mindmap.rb +71 -0
- data/lib/etassia/diagram/packet.rb +93 -0
- data/lib/etassia/diagram/pie.rb +115 -0
- data/lib/etassia/diagram/quadrant.rb +135 -0
- data/lib/etassia/diagram/radar.rb +65 -0
- data/lib/etassia/diagram/requirement.rb +168 -0
- data/lib/etassia/diagram/sankey.rb +217 -0
- data/lib/etassia/diagram/sequence.rb +299 -0
- data/lib/etassia/diagram/sequence_box.rb +18 -0
- data/lib/etassia/diagram/sequence_frame.rb +37 -0
- data/lib/etassia/diagram/sequence_frame_section.rb +23 -0
- data/lib/etassia/diagram/sequence_text.rb +69 -0
- data/lib/etassia/diagram/sequence_wrap.rb +23 -0
- data/lib/etassia/diagram/state_diagram.rb +282 -0
- data/lib/etassia/diagram/timeline.rb +183 -0
- data/lib/etassia/diagram/treemap.rb +95 -0
- data/lib/etassia/diagram/user_journey.rb +153 -0
- data/lib/etassia/diagram/xy_chart.rb +90 -0
- data/lib/etassia/diagram.rb +8 -0
- data/lib/etassia/diagram_registry.rb +34 -0
- data/lib/etassia/engine.rb +334 -0
- data/lib/etassia/error/diagram_type_error.rb +10 -0
- data/lib/etassia/error/layout_error.rb +12 -0
- data/lib/etassia/error/notation_registration_error.rb +10 -0
- data/lib/etassia/error/parse_error.rb +11 -0
- data/lib/etassia/error/pipeline_error.rb +10 -0
- data/lib/etassia/error/render_error.rb +12 -0
- data/lib/etassia/error/score_error.rb +12 -0
- data/lib/etassia/error.rb +10 -0
- data/lib/etassia/error_report.rb +69 -0
- data/lib/etassia/ir/data.rb +39 -0
- data/lib/etassia/ir/data_value.rb +35 -0
- data/lib/etassia/ir/dimension.rb +10 -0
- data/lib/etassia/ir/edge.rb +34 -0
- data/lib/etassia/ir/graph.rb +28 -0
- data/lib/etassia/ir/integrity.rb +80 -0
- data/lib/etassia/ir/item.rb +46 -0
- data/lib/etassia/ir/model.rb +56 -0
- data/lib/etassia/ir/node.rb +10 -0
- data/lib/etassia/ir/placement.rb +47 -0
- data/lib/etassia/ir/prepositioned.rb +25 -0
- data/lib/etassia/ir/prepositioned_item.rb +26 -0
- data/lib/etassia/ir/property_set.rb +43 -0
- data/lib/etassia/ir/scalar.rb +25 -0
- data/lib/etassia/ir/series.rb +10 -0
- data/lib/etassia/ir.rb +17 -0
- data/lib/etassia/js_math.rb +511 -0
- data/lib/etassia/js_number.rb +64 -0
- data/lib/etassia/layout/architecture.rb +1472 -0
- data/lib/etassia/layout/base.rb +276 -0
- data/lib/etassia/layout/block.rb +738 -0
- data/lib/etassia/layout/c4.rb +876 -0
- data/lib/etassia/layout/c4_boundary_metrics.rb +35 -0
- data/lib/etassia/layout/c4_bounds.rb +106 -0
- data/lib/etassia/layout/c4_intersection.rb +77 -0
- data/lib/etassia/layout/c4_placement.rb +135 -0
- data/lib/etassia/layout/c4_shape_metrics.rb +97 -0
- data/lib/etassia/layout/c4_shape_outline.rb +67 -0
- data/lib/etassia/layout/c4_stereotype.rb +30 -0
- data/lib/etassia/layout/c4_text.rb +54 -0
- data/lib/etassia/layout/class_cell_placement.rb +148 -0
- data/lib/etassia/layout/class_diagram.rb +1116 -0
- data/lib/etassia/layout/class_diagram_namespaces.rb +26 -0
- data/lib/etassia/layout/class_diagram_notes.rb +26 -0
- data/lib/etassia/layout/class_name_advances.rb +31 -0
- data/lib/etassia/layout/class_namespace_box.rb +21 -0
- data/lib/etassia/layout/class_namespace_nodes.rb +197 -0
- data/lib/etassia/layout/class_namespace_placement.rb +71 -0
- data/lib/etassia/layout/class_note.rb +44 -0
- data/lib/etassia/layout/class_note_nodes.rb +84 -0
- data/lib/etassia/layout/elk_notices.rb +48 -0
- data/lib/etassia/layout/elk_placement.rb +197 -0
- data/lib/etassia/layout/er_diagram.rb +1002 -0
- data/lib/etassia/layout/er_diagram_adjacency.rb +20 -0
- data/lib/etassia/layout/er_diagram_alignment.rb +72 -0
- data/lib/etassia/layout/er_diagram_compaction.rb +85 -0
- data/lib/etassia/layout/er_diagram_conflicts.rb +70 -0
- data/lib/etassia/layout/er_diagram_coordinates.rb +104 -0
- data/lib/etassia/layout/er_diagram_entity_size.rb +82 -0
- data/lib/etassia/layout/er_diagram_layering.rb +109 -0
- data/lib/etassia/layout/er_diagram_ordering.rb +143 -0
- data/lib/etassia/layout/er_diagram_placement.rb +163 -0
- data/lib/etassia/layout/er_diagram_placement_node.rb +22 -0
- data/lib/etassia/layout/error.rb +133 -0
- data/lib/etassia/layout/flowchart/brandes_koepf.rb +208 -0
- data/lib/etassia/layout/flowchart/cluster_reach.rb +70 -0
- data/lib/etassia/layout/flowchart/component_packing.rb +129 -0
- data/lib/etassia/layout/flowchart/directed_placement.rb +428 -0
- data/lib/etassia/layout/flowchart/edge_chains.rb +111 -0
- data/lib/etassia/layout/flowchart/edge_order.rb +34 -0
- data/lib/etassia/layout/flowchart/edge_router.rb +533 -0
- data/lib/etassia/layout/flowchart/label_backdrop_geometry.rb +62 -0
- data/lib/etassia/layout/flowchart/layer_spacing.rb +85 -0
- data/lib/etassia/layout/flowchart/level_edges.rb +74 -0
- data/lib/etassia/layout/flowchart/level_frame.rb +47 -0
- data/lib/etassia/layout/flowchart/minimum_rank_spacing.rb +74 -0
- data/lib/etassia/layout/flowchart/row_centering.rb +229 -0
- data/lib/etassia/layout/flowchart.rb +1290 -0
- data/lib/etassia/layout/gantt.rb +814 -0
- data/lib/etassia/layout/gantt_duration.rb +49 -0
- data/lib/etassia/layout/gantt_exclusions.rb +74 -0
- data/lib/etassia/layout/gantt_ticks.rb +165 -0
- data/lib/etassia/layout/git_graph.rb +1075 -0
- data/lib/etassia/layout/grid.rb +165 -0
- data/lib/etassia/layout/info.rb +113 -0
- data/lib/etassia/layout/kanban.rb +452 -0
- data/lib/etassia/layout/kanban_card_text.rb +95 -0
- data/lib/etassia/layout/mindmap.rb +425 -0
- data/lib/etassia/layout/mindmap_cose.rb +81 -0
- data/lib/etassia/layout/mindmap_cose_body.rb +93 -0
- data/lib/etassia/layout/mindmap_cose_geometry.rb +190 -0
- data/lib/etassia/layout/mindmap_cose_grid.rb +96 -0
- data/lib/etassia/layout/mindmap_cose_link.rb +42 -0
- data/lib/etassia/layout/mindmap_cose_relaxation.rb +166 -0
- data/lib/etassia/layout/mindmap_cose_seed.rb +93 -0
- data/lib/etassia/layout/mindmap_cose_wedge.rb +37 -0
- data/lib/etassia/layout/mindmap_node_size.rb +130 -0
- data/lib/etassia/layout/packet.rb +285 -0
- data/lib/etassia/layout/pie.rb +305 -0
- data/lib/etassia/layout/pie_legend.rb +64 -0
- data/lib/etassia/layout/pie_legend_entry.rb +21 -0
- data/lib/etassia/layout/quadrant.rb +402 -0
- data/lib/etassia/layout/radar.rb +442 -0
- data/lib/etassia/layout/requirement.rb +765 -0
- data/lib/etassia/layout/sankey.rb +501 -0
- data/lib/etassia/layout/scene.rb +18 -0
- data/lib/etassia/layout/sequence/actor_gaps.rb +151 -0
- data/lib/etassia/layout/sequence/box_shape.rb +23 -0
- data/lib/etassia/layout/sequence/creations.rb +73 -0
- data/lib/etassia/layout/sequence/frame_divider.rb +22 -0
- data/lib/etassia/layout/sequence/frame_placement.rb +424 -0
- data/lib/etassia/layout/sequence/frame_reader.rb +75 -0
- data/lib/etassia/layout/sequence/frame_shape.rb +45 -0
- data/lib/etassia/layout/sequence/geometry.rb +24 -0
- data/lib/etassia/layout/sequence/message_rows.rb +165 -0
- data/lib/etassia/layout/sequence/note.rb +16 -0
- data/lib/etassia/layout/sequence/note_box.rb +114 -0
- data/lib/etassia/layout/sequence/note_placement.rb +223 -0
- data/lib/etassia/layout/sequence/text_width.rb +69 -0
- data/lib/etassia/layout/sequence/text_wrap.rb +93 -0
- data/lib/etassia/layout/sequence.rb +936 -0
- data/lib/etassia/layout/state_diagram.rb +1277 -0
- data/lib/etassia/layout/timeline.rb +165 -0
- data/lib/etassia/layout/timeline_card.rb +142 -0
- data/lib/etassia/layout/timeline_flow.rb +164 -0
- data/lib/etassia/layout/timeline_line.rb +33 -0
- data/lib/etassia/layout/timeline_rounding.rb +19 -0
- data/lib/etassia/layout/timeline_text.rb +105 -0
- data/lib/etassia/layout/treemap.rb +303 -0
- data/lib/etassia/layout/treemap_placement.rb +52 -0
- data/lib/etassia/layout/treemap_squarify.rb +108 -0
- data/lib/etassia/layout/user_journey.rb +300 -0
- data/lib/etassia/layout/user_journey_face.rb +33 -0
- data/lib/etassia/layout/user_journey_face_geometry.rb +80 -0
- data/lib/etassia/layout/user_journey_geometry.rb +336 -0
- data/lib/etassia/layout/user_journey_legend.rb +84 -0
- data/lib/etassia/layout/xy_chart.rb +620 -0
- data/lib/etassia/layout.rb +19 -0
- data/lib/etassia/lint_debt_scoreboard.rb +219 -0
- data/lib/etassia/markdown_text/emphasis_simulator.rb +373 -0
- data/lib/etassia/markdown_text.rb +393 -0
- data/lib/etassia/notation/builtin.rb +39 -0
- data/lib/etassia/notation/entry.rb +15 -0
- data/lib/etassia/notation/mermaid/class_diagram_config.rb +42 -0
- data/lib/etassia/notation/mermaid/git_graph_config.rb +46 -0
- data/lib/etassia/notation/mermaid/ir_adapter.rb +27 -0
- data/lib/etassia/notation/mermaid/ir_adapters/architecture.rb +196 -0
- data/lib/etassia/notation/mermaid/ir_adapters/block.rb +138 -0
- data/lib/etassia/notation/mermaid/ir_adapters/c4.rb +258 -0
- data/lib/etassia/notation/mermaid/ir_adapters/class_diagram.rb +257 -0
- data/lib/etassia/notation/mermaid/ir_adapters/er_diagram.rb +220 -0
- data/lib/etassia/notation/mermaid/ir_adapters/error.rb +32 -0
- data/lib/etassia/notation/mermaid/ir_adapters/flowchart.rb +208 -0
- data/lib/etassia/notation/mermaid/ir_adapters/gantt.rb +236 -0
- data/lib/etassia/notation/mermaid/ir_adapters/git_graph.rb +186 -0
- data/lib/etassia/notation/mermaid/ir_adapters/info.rb +34 -0
- data/lib/etassia/notation/mermaid/ir_adapters/kanban.rb +110 -0
- data/lib/etassia/notation/mermaid/ir_adapters/mindmap.rb +76 -0
- data/lib/etassia/notation/mermaid/ir_adapters/packet.rb +51 -0
- data/lib/etassia/notation/mermaid/ir_adapters/pie.rb +71 -0
- data/lib/etassia/notation/mermaid/ir_adapters/quadrant.rb +116 -0
- data/lib/etassia/notation/mermaid/ir_adapters/radar.rb +142 -0
- data/lib/etassia/notation/mermaid/ir_adapters/requirement.rb +237 -0
- data/lib/etassia/notation/mermaid/ir_adapters/sankey.rb +74 -0
- data/lib/etassia/notation/mermaid/ir_adapters/sequence.rb +304 -0
- data/lib/etassia/notation/mermaid/ir_adapters/state_diagram.rb +225 -0
- data/lib/etassia/notation/mermaid/ir_adapters/timeline.rb +93 -0
- data/lib/etassia/notation/mermaid/ir_adapters/treemap.rb +143 -0
- data/lib/etassia/notation/mermaid/ir_adapters/user_journey.rb +127 -0
- data/lib/etassia/notation/mermaid/ir_adapters/xychart.rb +131 -0
- data/lib/etassia/notation/mermaid.rb +399 -0
- data/lib/etassia/notation/parsed.rb +31 -0
- data/lib/etassia/notation/plantuml/activity/arrow_head.rb +45 -0
- data/lib/etassia/notation/plantuml/activity/arrow_style.rb +53 -0
- data/lib/etassia/notation/plantuml/activity/bar_columns.rb +75 -0
- data/lib/etassia/notation/plantuml/activity/box.rb +60 -0
- data/lib/etassia/notation/plantuml/activity/builder.rb +77 -0
- data/lib/etassia/notation/plantuml/activity/canvas.rb +117 -0
- data/lib/etassia/notation/plantuml/activity/column_centres.rb +151 -0
- data/lib/etassia/notation/plantuml/activity/columns.rb +224 -0
- data/lib/etassia/notation/plantuml/activity/diagram.rb +35 -0
- data/lib/etassia/notation/plantuml/activity/edge.rb +35 -0
- data/lib/etassia/notation/plantuml/activity/edge_marks.rb +68 -0
- data/lib/etassia/notation/plantuml/activity/exits.rb +61 -0
- data/lib/etassia/notation/plantuml/activity/frame_marks.rb +116 -0
- data/lib/etassia/notation/plantuml/activity/lane_steps.rb +82 -0
- data/lib/etassia/notation/plantuml/activity/lane_titles.rb +46 -0
- data/lib/etassia/notation/plantuml/activity/layout.rb +50 -0
- data/lib/etassia/notation/plantuml/activity/legacy_parser.rb +181 -0
- data/lib/etassia/notation/plantuml/activity/legacy_row_gaps.rb +65 -0
- data/lib/etassia/notation/plantuml/activity/mark.rb +23 -0
- data/lib/etassia/notation/plantuml/activity/marks.rb +62 -0
- data/lib/etassia/notation/plantuml/activity/metrics.rb +169 -0
- data/lib/etassia/notation/plantuml/activity/new_parser/blocks.rb +166 -0
- data/lib/etassia/notation/plantuml/activity/new_parser.rb +177 -0
- data/lib/etassia/notation/plantuml/activity/node.rb +50 -0
- data/lib/etassia/notation/plantuml/activity/node_marks.rb +174 -0
- data/lib/etassia/notation/plantuml/activity/note.rb +27 -0
- data/lib/etassia/notation/plantuml/activity/parser.rb +51 -0
- data/lib/etassia/notation/plantuml/activity/placement.rb +327 -0
- data/lib/etassia/notation/plantuml/activity/ranking.rb +142 -0
- data/lib/etassia/notation/plantuml/activity/reach.rb +58 -0
- data/lib/etassia/notation/plantuml/activity/renderer.rb +220 -0
- data/lib/etassia/notation/plantuml/activity/route.rb +22 -0
- data/lib/etassia/notation/plantuml/activity/router.rb +308 -0
- data/lib/etassia/notation/plantuml/activity/row_gaps.rb +105 -0
- data/lib/etassia/notation/plantuml/activity/row_spread.rb +59 -0
- data/lib/etassia/notation/plantuml/activity/scene.rb +20 -0
- data/lib/etassia/notation/plantuml/activity/text.rb +36 -0
- data/lib/etassia/notation/plantuml/activity.rb +50 -0
- data/lib/etassia/notation/plantuml/arrow.rb +135 -0
- data/lib/etassia/notation/plantuml/caption.rb +50 -0
- data/lib/etassia/notation/plantuml/caption_layout.rb +97 -0
- data/lib/etassia/notation/plantuml/caption_rows.rb +67 -0
- data/lib/etassia/notation/plantuml/class_header.rb +178 -0
- data/lib/etassia/notation/plantuml/class_name.rb +51 -0
- data/lib/etassia/notation/plantuml/component.rb +37 -0
- data/lib/etassia/notation/plantuml/creole.rb +278 -0
- data/lib/etassia/notation/plantuml/creole_icons.rb +33 -0
- data/lib/etassia/notation/plantuml/diagram.rb +60 -0
- data/lib/etassia/notation/plantuml/diagram_builder.rb +442 -0
- data/lib/etassia/notation/plantuml/diagram_name.rb +51 -0
- data/lib/etassia/notation/plantuml/directives.rb +33 -0
- data/lib/etassia/notation/plantuml/drawing/box.rb +28 -0
- data/lib/etassia/notation/plantuml/drawing/face.rb +39 -0
- data/lib/etassia/notation/plantuml/drawing/pen.rb +105 -0
- data/lib/etassia/notation/plantuml/drawing/renderer.rb +36 -0
- data/lib/etassia/notation/plantuml/drawing/scene.rb +28 -0
- data/lib/etassia/notation/plantuml/drawing.rb +19 -0
- data/lib/etassia/notation/plantuml/ebnf/blocks.rb +272 -0
- data/lib/etassia/notation/plantuml/ebnf/layout.rb +117 -0
- data/lib/etassia/notation/plantuml/ebnf/model.rb +22 -0
- data/lib/etassia/notation/plantuml/ebnf/reader.rb +131 -0
- data/lib/etassia/notation/plantuml/ebnf.rb +34 -0
- data/lib/etassia/notation/plantuml/end_texts.rb +78 -0
- data/lib/etassia/notation/plantuml/entity.rb +54 -0
- data/lib/etassia/notation/plantuml/further.rb +38 -0
- data/lib/etassia/notation/plantuml/gantt/layout.rb +269 -0
- data/lib/etassia/notation/plantuml/gantt/reader.rb +210 -0
- data/lib/etassia/notation/plantuml/gantt/renderer.rb +81 -0
- data/lib/etassia/notation/plantuml/gantt.rb +34 -0
- data/lib/etassia/notation/plantuml/include/blocks.rb +66 -0
- data/lib/etassia/notation/plantuml/include/finder.rb +61 -0
- data/lib/etassia/notation/plantuml/include.rb +78 -0
- data/lib/etassia/notation/plantuml/ir_adapter/annotations.rb +40 -0
- data/lib/etassia/notation/plantuml/ir_adapter/links.rb +91 -0
- data/lib/etassia/notation/plantuml/ir_adapter/sink.rb +49 -0
- data/lib/etassia/notation/plantuml/ir_adapter/structure.rb +86 -0
- data/lib/etassia/notation/plantuml/ir_adapter.rb +32 -0
- data/lib/etassia/notation/plantuml/ir_reader/annotations.rb +51 -0
- data/lib/etassia/notation/plantuml/ir_reader/index.rb +49 -0
- data/lib/etassia/notation/plantuml/ir_reader/links.rb +133 -0
- data/lib/etassia/notation/plantuml/ir_reader/structure.rb +83 -0
- data/lib/etassia/notation/plantuml/ir_reader.rb +42 -0
- data/lib/etassia/notation/plantuml/junction.rb +20 -0
- data/lib/etassia/notation/plantuml/klass.rb +41 -0
- data/lib/etassia/notation/plantuml/label_clearance.rb +67 -0
- data/lib/etassia/notation/plantuml/layout.rb +2806 -0
- data/lib/etassia/notation/plantuml/member.rb +37 -0
- data/lib/etassia/notation/plantuml/member_icon.rb +87 -0
- data/lib/etassia/notation/plantuml/member_icon_elements.rb +91 -0
- data/lib/etassia/notation/plantuml/member_pitch.rb +76 -0
- data/lib/etassia/notation/plantuml/member_rule.rb +48 -0
- data/lib/etassia/notation/plantuml/network/grid.rb +170 -0
- data/lib/etassia/notation/plantuml/network/layout.rb +158 -0
- data/lib/etassia/notation/plantuml/network/model.rb +22 -0
- data/lib/etassia/notation/plantuml/network/placement.rb +64 -0
- data/lib/etassia/notation/plantuml/network/reader.rb +126 -0
- data/lib/etassia/notation/plantuml/network/shapes.rb +109 -0
- data/lib/etassia/notation/plantuml/network.rb +37 -0
- data/lib/etassia/notation/plantuml/node_graph/archimate.rb +49 -0
- data/lib/etassia/notation/plantuml/node_graph/box_reader.rb +86 -0
- data/lib/etassia/notation/plantuml/node_graph/cloud.rb +73 -0
- data/lib/etassia/notation/plantuml/node_graph/crows_foot.rb +85 -0
- data/lib/etassia/notation/plantuml/node_graph/curve.rb +66 -0
- data/lib/etassia/notation/plantuml/node_graph/data_reader.rb +77 -0
- data/lib/etassia/notation/plantuml/node_graph/data_shape.rb +39 -0
- data/lib/etassia/notation/plantuml/node_graph/detour.rb +98 -0
- data/lib/etassia/notation/plantuml/node_graph/edge.rb +26 -0
- data/lib/etassia/notation/plantuml/node_graph/entity_metrics.rb +49 -0
- data/lib/etassia/notation/plantuml/node_graph/entity_reader.rb +65 -0
- data/lib/etassia/notation/plantuml/node_graph/entity_shape.rb +111 -0
- data/lib/etassia/notation/plantuml/node_graph/figures.rb +92 -0
- data/lib/etassia/notation/plantuml/node_graph/frame_ports.rb +73 -0
- data/lib/etassia/notation/plantuml/node_graph/graph.rb +40 -0
- data/lib/etassia/notation/plantuml/node_graph/heads.rb +89 -0
- data/lib/etassia/notation/plantuml/node_graph/label_fan.rb +76 -0
- data/lib/etassia/notation/plantuml/node_graph/label_placer.rb +310 -0
- data/lib/etassia/notation/plantuml/node_graph/label_waypoint.rb +47 -0
- data/lib/etassia/notation/plantuml/node_graph/layout.rb +293 -0
- data/lib/etassia/notation/plantuml/node_graph/link.rb +78 -0
- data/lib/etassia/notation/plantuml/node_graph/macros.rb +39 -0
- data/lib/etassia/notation/plantuml/node_graph/metrics.rb +113 -0
- data/lib/etassia/notation/plantuml/node_graph/node.rb +44 -0
- data/lib/etassia/notation/plantuml/node_graph/note_tail.rb +58 -0
- data/lib/etassia/notation/plantuml/node_graph/packer.rb +126 -0
- data/lib/etassia/notation/plantuml/node_graph/parser.rb +309 -0
- data/lib/etassia/notation/plantuml/node_graph/paths.rb +48 -0
- data/lib/etassia/notation/plantuml/node_graph/ranking.rb +231 -0
- data/lib/etassia/notation/plantuml/node_graph/reader.rb +53 -0
- data/lib/etassia/notation/plantuml/node_graph/references.rb +38 -0
- data/lib/etassia/notation/plantuml/node_graph/renderer.rb +160 -0
- data/lib/etassia/notation/plantuml/node_graph/scene.rb +22 -0
- data/lib/etassia/notation/plantuml/node_graph/shapes.rb +302 -0
- data/lib/etassia/notation/plantuml/node_graph/skipped_ranks.rb +61 -0
- data/lib/etassia/notation/plantuml/node_graph/tab.rb +68 -0
- data/lib/etassia/notation/plantuml/node_graph/usecase_ellipse.rb +100 -0
- data/lib/etassia/notation/plantuml/node_graph.rb +38 -0
- data/lib/etassia/notation/plantuml/note.rb +27 -0
- data/lib/etassia/notation/plantuml/note_layout.rb +257 -0
- data/lib/etassia/notation/plantuml/note_outline.rb +68 -0
- data/lib/etassia/notation/plantuml/objects/map_rows.rb +46 -0
- data/lib/etassia/notation/plantuml/objects/reader.rb +208 -0
- data/lib/etassia/notation/plantuml/objects.rb +39 -0
- data/lib/etassia/notation/plantuml/package.rb +45 -0
- data/lib/etassia/notation/plantuml/package_color.rb +32 -0
- data/lib/etassia/notation/plantuml/package_frames.rb +178 -0
- data/lib/etassia/notation/plantuml/parser.rb +622 -0
- data/lib/etassia/notation/plantuml/portion_visibility.rb +91 -0
- data/lib/etassia/notation/plantuml/qualified_association_layout.rb +332 -0
- data/lib/etassia/notation/plantuml/qualifier_box.rb +78 -0
- data/lib/etassia/notation/plantuml/rank_chain.rb +527 -0
- data/lib/etassia/notation/plantuml/rank_hierarchy.rb +347 -0
- data/lib/etassia/notation/plantuml/relation.rb +103 -0
- data/lib/etassia/notation/plantuml/relation_label_separator.rb +199 -0
- data/lib/etassia/notation/plantuml/relation_path_points.rb +84 -0
- data/lib/etassia/notation/plantuml/renderer.rb +490 -0
- data/lib/etassia/notation/plantuml/scene.rb +134 -0
- data/lib/etassia/notation/plantuml/segment_box.rb +85 -0
- data/lib/etassia/notation/plantuml/sequence/activation.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/appearance.rb +71 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_end.rb +23 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_marks.rb +111 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_style.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_syntax.rb +122 -0
- data/lib/etassia/notation/plantuml/sequence/bar_tracker.rb +59 -0
- data/lib/etassia/notation/plantuml/sequence/box.rb +23 -0
- data/lib/etassia/notation/plantuml/sequence/chrome.rb +60 -0
- data/lib/etassia/notation/plantuml/sequence/chrome_rows.rb +184 -0
- data/lib/etassia/notation/plantuml/sequence/create.rb +34 -0
- data/lib/etassia/notation/plantuml/sequence/delay.rb +19 -0
- data/lib/etassia/notation/plantuml/sequence/destroy.rb +20 -0
- data/lib/etassia/notation/plantuml/sequence/diagram.rb +86 -0
- data/lib/etassia/notation/plantuml/sequence/divider.rb +19 -0
- data/lib/etassia/notation/plantuml/sequence/edge.rb +53 -0
- data/lib/etassia/notation/plantuml/sequence/embedded.rb +77 -0
- data/lib/etassia/notation/plantuml/sequence/fill.rb +56 -0
- data/lib/etassia/notation/plantuml/sequence/fragment.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/fragment_shape.rb +138 -0
- data/lib/etassia/notation/plantuml/sequence/head_style.rb +43 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/blocks.rb +73 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/fills.rb +24 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/items.rb +48 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/messages.rb +62 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/participants.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/settings.rb +54 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter.rb +38 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/blocks.rb +77 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/fills.rb +27 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/index.rb +36 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/items.rb +35 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/messages.rb +70 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/participants.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/settings.rb +74 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader.rb +38 -0
- data/lib/etassia/notation/plantuml/sequence/keyword_defaults.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/layout.rb +1567 -0
- data/lib/etassia/notation/plantuml/sequence/message.rb +97 -0
- data/lib/etassia/notation/plantuml/sequence/message_wrap.rb +77 -0
- data/lib/etassia/notation/plantuml/sequence/note.rb +61 -0
- data/lib/etassia/notation/plantuml/sequence/note_fill.rb +35 -0
- data/lib/etassia/notation/plantuml/sequence/note_geometry.rb +126 -0
- data/lib/etassia/notation/plantuml/sequence/note_shape.rb +51 -0
- data/lib/etassia/notation/plantuml/sequence/numbered_label.rb +57 -0
- data/lib/etassia/notation/plantuml/sequence/numbering.rb +49 -0
- data/lib/etassia/notation/plantuml/sequence/outline.rb +204 -0
- data/lib/etassia/notation/plantuml/sequence/page_break.rb +17 -0
- data/lib/etassia/notation/plantuml/sequence/paint.rb +79 -0
- data/lib/etassia/notation/plantuml/sequence/parallel_message.rb +19 -0
- data/lib/etassia/notation/plantuml/sequence/parser.rb +844 -0
- data/lib/etassia/notation/plantuml/sequence/participant.rb +27 -0
- data/lib/etassia/notation/plantuml/sequence/picture.rb +29 -0
- data/lib/etassia/notation/plantuml/sequence/ref.rb +24 -0
- data/lib/etassia/notation/plantuml/sequence/ref_shape.rb +74 -0
- data/lib/etassia/notation/plantuml/sequence/refusals.rb +47 -0
- data/lib/etassia/notation/plantuml/sequence/renderer.rb +501 -0
- data/lib/etassia/notation/plantuml/sequence/scene.rb +200 -0
- data/lib/etassia/notation/plantuml/sequence/skin.rb +76 -0
- data/lib/etassia/notation/plantuml/sequence/spacing.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/style.rb +151 -0
- data/lib/etassia/notation/plantuml/sequence/tab_size.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/walker.rb +1190 -0
- data/lib/etassia/notation/plantuml/sequence.rb +47 -0
- data/lib/etassia/notation/plantuml/source_lines.rb +33 -0
- data/lib/etassia/notation/plantuml/state/axis_solver.rb +272 -0
- data/lib/etassia/notation/plantuml/state/cluster_padding.rb +75 -0
- data/lib/etassia/notation/plantuml/state/curve.rb +73 -0
- data/lib/etassia/notation/plantuml/state/dot_axis.rb +248 -0
- data/lib/etassia/notation/plantuml/state/extent.rb +42 -0
- data/lib/etassia/notation/plantuml/state/hierarchy.rb +355 -0
- data/lib/etassia/notation/plantuml/state/label_clearance.rb +148 -0
- data/lib/etassia/notation/plantuml/state/label_reach.rb +139 -0
- data/lib/etassia/notation/plantuml/state/layout.rb +173 -0
- data/lib/etassia/notation/plantuml/state/level_edges.rb +113 -0
- data/lib/etassia/notation/plantuml/state/look.rb +36 -0
- data/lib/etassia/notation/plantuml/state/note_shape.rb +73 -0
- data/lib/etassia/notation/plantuml/state/plane.rb +85 -0
- data/lib/etassia/notation/plantuml/state/ranking.rb +181 -0
- data/lib/etassia/notation/plantuml/state/reader.rb +310 -0
- data/lib/etassia/notation/plantuml/state/renderer.rb +253 -0
- data/lib/etassia/notation/plantuml/state/route_detour.rb +115 -0
- data/lib/etassia/notation/plantuml/state/route_geometry.rb +186 -0
- data/lib/etassia/notation/plantuml/state/routes.rb +196 -0
- data/lib/etassia/notation/plantuml/state/row.rb +88 -0
- data/lib/etassia/notation/plantuml/state/rows.rb +50 -0
- data/lib/etassia/notation/plantuml/state/stretch.rb +71 -0
- data/lib/etassia/notation/plantuml/state.rb +62 -0
- data/lib/etassia/notation/plantuml/stereotype_head.rb +58 -0
- data/lib/etassia/notation/plantuml/style/bound.rb +34 -0
- data/lib/etassia/notation/plantuml/style/colour.rb +41 -0
- data/lib/etassia/notation/plantuml/style/colour_names.rb +89 -0
- data/lib/etassia/notation/plantuml/style/defaults.rb +33 -0
- data/lib/etassia/notation/plantuml/style/inline.rb +56 -0
- data/lib/etassia/notation/plantuml/style/reader.rb +242 -0
- data/lib/etassia/notation/plantuml/style/sheet.rb +103 -0
- data/lib/etassia/notation/plantuml/style.rb +32 -0
- data/lib/etassia/notation/plantuml/style_reader.rb +160 -0
- data/lib/etassia/notation/plantuml/style_sheet.rb +27 -0
- data/lib/etassia/notation/plantuml/styled_relation_curve.rb +71 -0
- data/lib/etassia/notation/plantuml/timing/arrows.rb +81 -0
- data/lib/etassia/notation/plantuml/timing/axis.rb +100 -0
- data/lib/etassia/notation/plantuml/timing/layout.rb +172 -0
- data/lib/etassia/notation/plantuml/timing/model.rb +34 -0
- data/lib/etassia/notation/plantuml/timing/reader.rb +173 -0
- data/lib/etassia/notation/plantuml/timing/signals.rb +328 -0
- data/lib/etassia/notation/plantuml/timing.rb +38 -0
- data/lib/etassia/notation/plantuml/tree/layout.rb +276 -0
- data/lib/etassia/notation/plantuml/tree/mindmap_layout.rb +157 -0
- data/lib/etassia/notation/plantuml/tree/reader.rb +186 -0
- data/lib/etassia/notation/plantuml/tree/renderer.rb +67 -0
- data/lib/etassia/notation/plantuml/tree/role.rb +57 -0
- data/lib/etassia/notation/plantuml/tree/rules.rb +156 -0
- data/lib/etassia/notation/plantuml/tree/wbs_layout.rb +164 -0
- data/lib/etassia/notation/plantuml/tree.rb +41 -0
- data/lib/etassia/notation/plantuml/unsupported_construct_error.rb +39 -0
- data/lib/etassia/notation/plantuml/unsupported_constructs.rb +103 -0
- data/lib/etassia/notation/plantuml/usecase.rb +36 -0
- data/lib/etassia/notation/plantuml.rb +132 -0
- data/lib/etassia/notation/plantuml_data/boxes/frames.rb +101 -0
- data/lib/etassia/notation/plantuml_data/boxes/graph_layout.rb +348 -0
- data/lib/etassia/notation/plantuml_data/boxes/heads.rb +65 -0
- data/lib/etassia/notation/plantuml_data/boxes/highlights.rb +70 -0
- data/lib/etassia/notation/plantuml_data/boxes/inline_rows.rb +99 -0
- data/lib/etassia/notation/plantuml_data/boxes/json_reader.rb +24 -0
- data/lib/etassia/notation/plantuml_data/boxes/link_text.rb +94 -0
- data/lib/etassia/notation/plantuml_data/boxes/marks.rb +76 -0
- data/lib/etassia/notation/plantuml_data/boxes/ornaments.rb +130 -0
- data/lib/etassia/notation/plantuml_data/boxes/renderer.rb +95 -0
- data/lib/etassia/notation/plantuml_data/boxes/row_alignment.rb +58 -0
- data/lib/etassia/notation/plantuml_data/boxes/row_bend.rb +43 -0
- data/lib/etassia/notation/plantuml_data/boxes/scene.rb +27 -0
- data/lib/etassia/notation/plantuml_data/boxes/table.rb +56 -0
- data/lib/etassia/notation/plantuml_data/boxes/table_box.rb +355 -0
- data/lib/etassia/notation/plantuml_data/boxes/text.rb +101 -0
- data/lib/etassia/notation/plantuml_data/boxes/tree_builder.rb +82 -0
- data/lib/etassia/notation/plantuml_data/boxes/tree_layout.rb +82 -0
- data/lib/etassia/notation/plantuml_data/boxes/yaml_reader.rb +105 -0
- data/lib/etassia/notation/plantuml_data/openiconic.LICENSE +6 -0
- data/lib/etassia/notation/plantuml_data/openiconic.json +1 -0
- data/lib/etassia/notation/plantuml_data.rb +84 -0
- data/lib/etassia/notation/plantuml_salt/block.rb +80 -0
- data/lib/etassia/notation/plantuml_salt/box.rb +30 -0
- data/lib/etassia/notation/plantuml_salt/font_metrics.rb +28 -0
- data/lib/etassia/notation/plantuml_salt/grid_marks.rb +66 -0
- data/lib/etassia/notation/plantuml_salt/group_marks.rb +77 -0
- data/lib/etassia/notation/plantuml_salt/layout.rb +206 -0
- data/lib/etassia/notation/plantuml_salt/mark.rb +36 -0
- data/lib/etassia/notation/plantuml_salt/markup.rb +57 -0
- data/lib/etassia/notation/plantuml_salt/parser.rb +239 -0
- data/lib/etassia/notation/plantuml_salt/renderer.rb +138 -0
- data/lib/etassia/notation/plantuml_salt/row.rb +19 -0
- data/lib/etassia/notation/plantuml_salt/run.rb +34 -0
- data/lib/etassia/notation/plantuml_salt/scene.rb +23 -0
- data/lib/etassia/notation/plantuml_salt/scroll_marks.rb +94 -0
- data/lib/etassia/notation/plantuml_salt/tab_marks.rb +74 -0
- data/lib/etassia/notation/plantuml_salt/tree_marks.rb +127 -0
- data/lib/etassia/notation/plantuml_salt/widget.rb +40 -0
- data/lib/etassia/notation/plantuml_salt/widget_marks.rb +319 -0
- data/lib/etassia/notation/plantuml_salt.rb +66 -0
- data/lib/etassia/notation/plugin_failure.rb +42 -0
- data/lib/etassia/notation.rb +289 -0
- data/lib/etassia/parser/architecture.rb +25 -0
- data/lib/etassia/parser/atoms/delimited_run.rb +82 -0
- data/lib/etassia/parser/atoms/greedy_run.rb +116 -0
- data/lib/etassia/parser/atoms/joined.rb +47 -0
- data/lib/etassia/parser/atoms/trimmed_run.rb +47 -0
- data/lib/etassia/parser/base.rb +258 -0
- data/lib/etassia/parser/block.rb +32 -0
- data/lib/etassia/parser/builders/architecture.rb +135 -0
- data/lib/etassia/parser/builders/block.rb +288 -0
- data/lib/etassia/parser/builders/c4.rb +275 -0
- data/lib/etassia/parser/builders/capture_string.rb +17 -0
- data/lib/etassia/parser/builders/class_diagram.rb +539 -0
- data/lib/etassia/parser/builders/er_diagram.rb +308 -0
- data/lib/etassia/parser/builders/error.rb +51 -0
- data/lib/etassia/parser/builders/flowchart.rb +1150 -0
- data/lib/etassia/parser/builders/gantt.rb +267 -0
- data/lib/etassia/parser/builders/git_graph.rb +301 -0
- data/lib/etassia/parser/builders/info.rb +57 -0
- data/lib/etassia/parser/builders/kanban.rb +411 -0
- data/lib/etassia/parser/builders/mindmap.rb +271 -0
- data/lib/etassia/parser/builders/packet.rb +85 -0
- data/lib/etassia/parser/builders/pie.rb +105 -0
- data/lib/etassia/parser/builders/quadrant.rb +165 -0
- data/lib/etassia/parser/builders/radar.rb +157 -0
- data/lib/etassia/parser/builders/requirement.rb +230 -0
- data/lib/etassia/parser/builders/sankey.rb +142 -0
- data/lib/etassia/parser/builders/sequence.rb +431 -0
- data/lib/etassia/parser/builders/sequence_blocks.rb +117 -0
- data/lib/etassia/parser/builders/sequence_box_title.rb +57 -0
- data/lib/etassia/parser/builders/state_diagram.rb +364 -0
- data/lib/etassia/parser/builders/timeline.rb +133 -0
- data/lib/etassia/parser/builders/treemap.rb +138 -0
- data/lib/etassia/parser/builders/xy_chart.rb +148 -0
- data/lib/etassia/parser/c4.rb +37 -0
- data/lib/etassia/parser/class_diagram.rb +58 -0
- data/lib/etassia/parser/class_namespaces.rb +62 -0
- data/lib/etassia/parser/class_notes.rb +54 -0
- data/lib/etassia/parser/er_diagram.rb +28 -0
- data/lib/etassia/parser/error.rb +30 -0
- data/lib/etassia/parser/flowchart.rb +87 -0
- data/lib/etassia/parser/gantt.rb +43 -0
- data/lib/etassia/parser/git_graph.rb +106 -0
- data/lib/etassia/parser/grammars/architecture.rb +165 -0
- data/lib/etassia/parser/grammars/block.rb +190 -0
- data/lib/etassia/parser/grammars/c4.rb +229 -0
- data/lib/etassia/parser/grammars/class_diagram.rb +606 -0
- data/lib/etassia/parser/grammars/common.rb +107 -0
- data/lib/etassia/parser/grammars/er_diagram.rb +232 -0
- data/lib/etassia/parser/grammars/error.rb +32 -0
- data/lib/etassia/parser/grammars/flowchart.rb +1722 -0
- data/lib/etassia/parser/grammars/gantt.rb +198 -0
- data/lib/etassia/parser/grammars/git_graph.rb +234 -0
- data/lib/etassia/parser/grammars/info.rb +53 -0
- data/lib/etassia/parser/grammars/kanban.rb +417 -0
- data/lib/etassia/parser/grammars/mermaid_unicode_text.rb +108 -0
- data/lib/etassia/parser/grammars/mindmap.rb +220 -0
- data/lib/etassia/parser/grammars/packet.rb +71 -0
- data/lib/etassia/parser/grammars/pie.rb +128 -0
- data/lib/etassia/parser/grammars/quadrant.rb +202 -0
- data/lib/etassia/parser/grammars/radar.rb +158 -0
- data/lib/etassia/parser/grammars/requirement.rb +258 -0
- data/lib/etassia/parser/grammars/sankey.rb +104 -0
- data/lib/etassia/parser/grammars/sequence.rb +940 -0
- data/lib/etassia/parser/grammars/state_diagram.rb +382 -0
- data/lib/etassia/parser/grammars/timeline.rb +153 -0
- data/lib/etassia/parser/grammars/treemap.rb +122 -0
- data/lib/etassia/parser/grammars/xy_chart.rb +119 -0
- data/lib/etassia/parser/info.rb +32 -0
- data/lib/etassia/parser/kanban.rb +131 -0
- data/lib/etassia/parser/mermaid_shapes.rb +106 -0
- data/lib/etassia/parser/metadata_yaml.rb +452 -0
- data/lib/etassia/parser/mindmap.rb +92 -0
- data/lib/etassia/parser/native/builders/architecture.rb +103 -0
- data/lib/etassia/parser/native/builders/block.rb +68 -0
- data/lib/etassia/parser/native/builders/c4.rb +16 -0
- data/lib/etassia/parser/native/builders/class_diagram.rb +63 -0
- data/lib/etassia/parser/native/builders/er_diagram.rb +47 -0
- data/lib/etassia/parser/native/builders/flowchart.rb +58 -0
- data/lib/etassia/parser/native/builders/gantt.rb +35 -0
- data/lib/etassia/parser/native/builders/gitgraph.rb +35 -0
- data/lib/etassia/parser/native/builders/info.rb +30 -0
- data/lib/etassia/parser/native/builders/kanban.rb +37 -0
- data/lib/etassia/parser/native/builders/mindmap.rb +26 -0
- data/lib/etassia/parser/native/builders/packet.rb +63 -0
- data/lib/etassia/parser/native/builders/pie.rb +82 -0
- data/lib/etassia/parser/native/builders/quadrant.rb +27 -0
- data/lib/etassia/parser/native/builders/radar.rb +84 -0
- data/lib/etassia/parser/native/builders/requirement.rb +25 -0
- data/lib/etassia/parser/native/builders/sankey.rb +18 -0
- data/lib/etassia/parser/native/builders/sequence.rb +48 -0
- data/lib/etassia/parser/native/builders/state_diagram.rb +61 -0
- data/lib/etassia/parser/native/builders/timeline.rb +46 -0
- data/lib/etassia/parser/native/builders/treemap.rb +60 -0
- data/lib/etassia/parser/native/builders/user_journey.rb +83 -0
- data/lib/etassia/parser/native/builders/xy_chart.rb +94 -0
- data/lib/etassia/parser/native/declined.rb +12 -0
- data/lib/etassia/parser/native/mermaid.json +1 -0
- data/lib/etassia/parser/native/text.rb +31 -0
- data/lib/etassia/parser/native.rb +99 -0
- data/lib/etassia/parser/packet.rb +56 -0
- data/lib/etassia/parser/pie.rb +32 -0
- data/lib/etassia/parser/quadrant.rb +77 -0
- data/lib/etassia/parser/radar.rb +99 -0
- data/lib/etassia/parser/requirement.rb +32 -0
- data/lib/etassia/parser/sankey.rb +47 -0
- data/lib/etassia/parser/sequence.rb +34 -0
- data/lib/etassia/parser/state_diagram.rb +29 -0
- data/lib/etassia/parser/timeline.rb +40 -0
- data/lib/etassia/parser/treemap.rb +25 -0
- data/lib/etassia/parser/user_journey.rb +253 -0
- data/lib/etassia/parser/xy_chart.rb +98 -0
- data/lib/etassia/parser.rb +18 -0
- data/lib/etassia/renderer/architecture.rb +232 -0
- data/lib/etassia/renderer/architecture_edge_router.rb +379 -0
- data/lib/etassia/renderer/base.rb +295 -0
- data/lib/etassia/renderer/block.rb +157 -0
- data/lib/etassia/renderer/c4.rb +294 -0
- data/lib/etassia/renderer/class_diagram.rb +671 -0
- data/lib/etassia/renderer/er_diagram.rb +842 -0
- data/lib/etassia/renderer/error.rb +131 -0
- data/lib/etassia/renderer/flowchart.rb +315 -0
- data/lib/etassia/renderer/gantt.rb +177 -0
- data/lib/etassia/renderer/git_graph.rb +224 -0
- data/lib/etassia/renderer/info.rb +59 -0
- data/lib/etassia/renderer/kanban.rb +157 -0
- data/lib/etassia/renderer/line_break_text.rb +56 -0
- data/lib/etassia/renderer/markdown_text.rb +106 -0
- data/lib/etassia/renderer/mindmap.rb +290 -0
- data/lib/etassia/renderer/packet.rb +87 -0
- data/lib/etassia/renderer/pie.rb +113 -0
- data/lib/etassia/renderer/quadrant.rb +189 -0
- data/lib/etassia/renderer/radar.rb +191 -0
- data/lib/etassia/renderer/requirement.rb +209 -0
- data/lib/etassia/renderer/sankey.rb +114 -0
- data/lib/etassia/renderer/sequence/frame_drawing.rb +169 -0
- data/lib/etassia/renderer/sequence/note_drawing.rb +69 -0
- data/lib/etassia/renderer/sequence.rb +490 -0
- data/lib/etassia/renderer/state_diagram.rb +202 -0
- data/lib/etassia/renderer/timeline.rb +134 -0
- data/lib/etassia/renderer/timeline_palette.rb +18 -0
- data/lib/etassia/renderer/treemap/section_total.rb +33 -0
- data/lib/etassia/renderer/treemap.rb +128 -0
- data/lib/etassia/renderer/user_journey.rb +209 -0
- data/lib/etassia/renderer/xy_chart.rb +180 -0
- data/lib/etassia/renderer.rb +22 -0
- data/lib/etassia/runtime.rb +125 -0
- data/lib/etassia/source/frontmatter.rb +501 -0
- data/lib/etassia/source.rb +224 -0
- data/lib/etassia/svg/arrowhead.rb +205 -0
- data/lib/etassia/svg/circle.rb +19 -0
- data/lib/etassia/svg/document.rb +106 -0
- data/lib/etassia/svg/element.rb +209 -0
- data/lib/etassia/svg/ellipse.rb +23 -0
- data/lib/etassia/svg/escaping.rb +149 -0
- data/lib/etassia/svg/group.rb +64 -0
- data/lib/etassia/svg/line.rb +21 -0
- data/lib/etassia/svg/numbers.rb +53 -0
- data/lib/etassia/svg/path.rb +67 -0
- data/lib/etassia/svg/path_geometry.rb +378 -0
- data/lib/etassia/svg/polygon.rb +25 -0
- data/lib/etassia/svg/polyline.rb +28 -0
- data/lib/etassia/svg/rect.rb +34 -0
- data/lib/etassia/svg/style.rb +50 -0
- data/lib/etassia/svg/text.rb +181 -0
- data/lib/etassia/svg/tspan.rb +48 -0
- data/lib/etassia/svg.rb +38 -0
- data/lib/etassia/text_measurement/arial_advances.rb +122 -0
- data/lib/etassia/text_measurement/dejavu_advances.rb +111 -0
- data/lib/etassia/text_measurement/times_advances.rb +64 -0
- data/lib/etassia/text_measurement/trebuchet_advances.rb +53 -0
- data/lib/etassia/text_measurement/trebuchet_kerning.rb +29 -0
- data/lib/etassia/text_measurement.rb +198 -0
- data/lib/etassia/theme/builtin/dark.yml +229 -0
- data/lib/etassia/theme/builtin/default.yml +239 -0
- data/lib/etassia/theme/builtin/high_contrast.yml +231 -0
- data/lib/etassia/theme/builtin/light.yml +229 -0
- data/lib/etassia/theme/color_palette.rb +97 -0
- data/lib/etassia/theme/completion.rb +50 -0
- data/lib/etassia/theme/effect_styles.rb +34 -0
- data/lib/etassia/theme/registry.rb +45 -0
- data/lib/etassia/theme/shape_styles.rb +34 -0
- data/lib/etassia/theme/spacing_config.rb +30 -0
- data/lib/etassia/theme/typography.rb +40 -0
- data/lib/etassia/theme.rb +73 -0
- data/lib/etassia/version.rb +5 -0
- data/lib/etassia.rb +40 -0
- metadata +865 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a card in a Kanban column.
|
|
9
|
+
#
|
|
10
|
+
# A card has an id, text content, and optional metadata like
|
|
11
|
+
# assigned user, ticket number, icon, priority, etc.
|
|
12
|
+
class KanbanCard < Lutaml::Model::Serializable
|
|
13
|
+
# Card identifier
|
|
14
|
+
attribute :id, :string
|
|
15
|
+
|
|
16
|
+
# Card text content
|
|
17
|
+
attribute :text, :string
|
|
18
|
+
|
|
19
|
+
# Optional metadata
|
|
20
|
+
attribute :assigned, :string
|
|
21
|
+
attribute :ticket, :string
|
|
22
|
+
attribute :icon, :string
|
|
23
|
+
attribute :label, :string
|
|
24
|
+
attribute :priority, :string
|
|
25
|
+
|
|
26
|
+
# Classes assigned via the `:::className` directive line - mermaid's
|
|
27
|
+
# `@{ classes: ... }` key is not a recognized metadata field (verified
|
|
28
|
+
# against the installed @mermaid-js/mermaid-cli 11.12.0
|
|
29
|
+
# kanban-definition bundle) and is ignored. Not rendered - the
|
|
30
|
+
# renderer has no classDef-driven styling for kanban, matching
|
|
31
|
+
# Diagram::MindmapNode#classes, which is carried the same way to its
|
|
32
|
+
# own renderer and stops there too.
|
|
33
|
+
attribute :classes, :string, collection: true, default: -> { [] }
|
|
34
|
+
|
|
35
|
+
# Validates the card has required fields.
|
|
36
|
+
#
|
|
37
|
+
# @return [Boolean] true if card is valid
|
|
38
|
+
def valid?
|
|
39
|
+
!id.nil? && !id.empty? && !text.nil? && !text.empty?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Returns all metadata as a hash.
|
|
43
|
+
#
|
|
44
|
+
# @return [Hash] metadata hash
|
|
45
|
+
def metadata
|
|
46
|
+
{
|
|
47
|
+
assigned: assigned,
|
|
48
|
+
ticket: ticket,
|
|
49
|
+
icon: icon,
|
|
50
|
+
label: label,
|
|
51
|
+
priority: priority,
|
|
52
|
+
}.compact
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Checks if card has any metadata.
|
|
56
|
+
#
|
|
57
|
+
# @return [Boolean] true if card has metadata
|
|
58
|
+
def has_metadata?
|
|
59
|
+
!metadata.empty?
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Represents a column in a Kanban board.
|
|
64
|
+
#
|
|
65
|
+
# A column has an id, title, and contains multiple cards.
|
|
66
|
+
class KanbanColumn < Lutaml::Model::Serializable
|
|
67
|
+
# Column identifier
|
|
68
|
+
attribute :id, :string
|
|
69
|
+
|
|
70
|
+
# Column title/name
|
|
71
|
+
attribute :title, :string
|
|
72
|
+
|
|
73
|
+
# Icon, set by an `@{ icon: ... }` entry on the column's own item line
|
|
74
|
+
# or by a standalone `::icon(name)` line right after it. Not rendered
|
|
75
|
+
# - column headers have no metadata row today; see KanbanCard#classes
|
|
76
|
+
# for the same "modeled, not drawn" precedent.
|
|
77
|
+
attribute :icon, :string
|
|
78
|
+
|
|
79
|
+
# Classes, set by a standalone `:::className` line right after the
|
|
80
|
+
# column's own item line. Mermaid ignores an `@{ classes: ... }` entry
|
|
81
|
+
# on the item line itself; see KanbanCard#classes. Not rendered.
|
|
82
|
+
attribute :classes, :string, collection: true, default: -> { [] }
|
|
83
|
+
|
|
84
|
+
# Collection of cards in this column
|
|
85
|
+
attribute :cards, KanbanCard, collection: true, default: -> { [] }
|
|
86
|
+
|
|
87
|
+
# Validates the column has required fields.
|
|
88
|
+
#
|
|
89
|
+
# @return [Boolean] true if column is valid
|
|
90
|
+
def valid?
|
|
91
|
+
!id.nil? && !id.empty? &&
|
|
92
|
+
!title.nil? && !title.empty? &&
|
|
93
|
+
cards.all?(&:valid?)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Adds a card to this column.
|
|
97
|
+
#
|
|
98
|
+
# @param card [KanbanCard] the card to add
|
|
99
|
+
# @return [void]
|
|
100
|
+
def add_card(card)
|
|
101
|
+
cards << card
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Kanban board diagram model.
|
|
106
|
+
#
|
|
107
|
+
# Represents a complete Kanban board with columns and cards
|
|
108
|
+
# for workflow visualization.
|
|
109
|
+
#
|
|
110
|
+
# @example Creating a simple kanban board
|
|
111
|
+
# diagram = Kanban.new
|
|
112
|
+
# column = KanbanColumn.new.tap do |c|
|
|
113
|
+
# c.id = "todo"
|
|
114
|
+
# c.title = "Todo"
|
|
115
|
+
# end
|
|
116
|
+
# card = KanbanCard.new.tap do |c|
|
|
117
|
+
# c.id = "docs"
|
|
118
|
+
# c.text = "Create Documentation"
|
|
119
|
+
# c.priority = "High"
|
|
120
|
+
# end
|
|
121
|
+
# column.add_card(card)
|
|
122
|
+
# diagram.add_column(column)
|
|
123
|
+
class Kanban < Base
|
|
124
|
+
# Collection of columns in the board
|
|
125
|
+
attribute :columns, KanbanColumn, collection: true,
|
|
126
|
+
default: -> { [] }
|
|
127
|
+
|
|
128
|
+
# Returns the diagram type identifier.
|
|
129
|
+
#
|
|
130
|
+
# @return [Symbol] :kanban
|
|
131
|
+
def diagram_type
|
|
132
|
+
:kanban
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Validates the kanban board structure.
|
|
136
|
+
#
|
|
137
|
+
# A kanban is valid if:
|
|
138
|
+
# - It has no columns (a bare `kanban` header is a valid empty
|
|
139
|
+
# diagram, matching what mmdc renders — do not reintroduce a
|
|
140
|
+
# "must have at least one column" check here)
|
|
141
|
+
# - or every column it does have is valid
|
|
142
|
+
#
|
|
143
|
+
# @return [Boolean] true if kanban board is valid
|
|
144
|
+
def valid?
|
|
145
|
+
return true if columns.nil? || columns.empty?
|
|
146
|
+
|
|
147
|
+
columns.all?(&:valid?)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Adds a column to the board.
|
|
151
|
+
#
|
|
152
|
+
# @param column [KanbanColumn] the column to add
|
|
153
|
+
# @return [void]
|
|
154
|
+
def add_column(column)
|
|
155
|
+
columns << column
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Returns all cards across all columns.
|
|
159
|
+
#
|
|
160
|
+
# @return [Array<KanbanCard>] all cards in the board
|
|
161
|
+
def all_cards
|
|
162
|
+
columns.flat_map(&:cards)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Finds a column by id.
|
|
166
|
+
#
|
|
167
|
+
# @param id [String] the column id
|
|
168
|
+
# @return [KanbanColumn, nil] the column or nil if not found
|
|
169
|
+
def find_column(id)
|
|
170
|
+
columns.find { |c| c.id == id }
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Finds cards by assigned user.
|
|
174
|
+
#
|
|
175
|
+
# @param user [String] the assigned user
|
|
176
|
+
# @return [Array<KanbanCard>] cards assigned to the user
|
|
177
|
+
def cards_by_assigned(user)
|
|
178
|
+
all_cards.select { |c| c.assigned == user }
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Finds cards by priority.
|
|
182
|
+
#
|
|
183
|
+
# @param priority [String] the priority level
|
|
184
|
+
# @return [Array<KanbanCard>] cards with the given priority
|
|
185
|
+
def cards_by_priority(priority)
|
|
186
|
+
all_cards.select { |c| c.priority == priority }
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Finds cards by ticket.
|
|
190
|
+
#
|
|
191
|
+
# @param ticket [String] the ticket number
|
|
192
|
+
# @return [Array<KanbanCard>] cards with the given ticket
|
|
193
|
+
def cards_by_ticket(ticket)
|
|
194
|
+
all_cards.select { |c| c.ticket == ticket }
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a Mindmap diagram
|
|
9
|
+
class Mindmap < Base
|
|
10
|
+
# Represents a node in the mindmap
|
|
11
|
+
class MindmapNode < Lutaml::Model::Serializable
|
|
12
|
+
attribute :id, :string
|
|
13
|
+
attribute :content, :string
|
|
14
|
+
attribute :level, :integer, default: -> { 0 }
|
|
15
|
+
attribute :shape, :string, default: -> { "default" }
|
|
16
|
+
attribute :icon, :string
|
|
17
|
+
attribute :classes, :string, collection: true, default: -> { [] }
|
|
18
|
+
attribute :children, MindmapNode, collection: true, default: -> { [] }
|
|
19
|
+
attribute :parent, MindmapNode
|
|
20
|
+
|
|
21
|
+
# Shape constants
|
|
22
|
+
SHAPES = {
|
|
23
|
+
circle: "circle", # ((text))
|
|
24
|
+
cloud: "cloud", # )text(
|
|
25
|
+
bang: "bang", # ))text((
|
|
26
|
+
hexagon: "hexagon", # {{text}}
|
|
27
|
+
square: "square", # [text]
|
|
28
|
+
round: "round", # (text)
|
|
29
|
+
default: "default", # plain text
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
def add_child(child)
|
|
33
|
+
child.parent = self
|
|
34
|
+
child.level = level + 1
|
|
35
|
+
children << child
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def root?
|
|
39
|
+
level.zero?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def leaf?
|
|
43
|
+
children.empty?
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attribute :root, MindmapNode
|
|
48
|
+
attribute :nodes, MindmapNode, collection: true, default: -> { [] }
|
|
49
|
+
|
|
50
|
+
def add_node(node)
|
|
51
|
+
nodes << node
|
|
52
|
+
@root = node if node.root?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns the diagram type identifier.
|
|
56
|
+
#
|
|
57
|
+
# @return [Symbol] :mindmap
|
|
58
|
+
def diagram_type
|
|
59
|
+
:mindmap
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Mindmaps have no validation rules yet. See TODO.foundation's
|
|
63
|
+
# corpus burndown for real validation; this is deliberately trivial.
|
|
64
|
+
#
|
|
65
|
+
# @return [Boolean] true
|
|
66
|
+
def valid?
|
|
67
|
+
true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module Etassia
|
|
6
|
+
module Diagram
|
|
7
|
+
# Represents a packet diagram showing network packet structures
|
|
8
|
+
class Packet < Base
|
|
9
|
+
attr_accessor :title, :fields
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
super
|
|
13
|
+
@fields = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Returns the diagram type identifier.
|
|
17
|
+
#
|
|
18
|
+
# @return [Symbol] :packet
|
|
19
|
+
def diagram_type
|
|
20
|
+
:packet
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Packet diagrams have no validation rules yet. See
|
|
24
|
+
# TODO.foundation's corpus burndown for real validation; this is
|
|
25
|
+
# deliberately trivial.
|
|
26
|
+
#
|
|
27
|
+
# @return [Boolean] true
|
|
28
|
+
def valid?
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Add a field to the packet
|
|
33
|
+
def add_field(field)
|
|
34
|
+
@fields << field
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Get the maximum bit position used in the packet
|
|
38
|
+
def max_bit_position
|
|
39
|
+
return 0 if @fields.empty?
|
|
40
|
+
|
|
41
|
+
@fields.map(&:bit_end).max
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Calculate the number of rows needed (assuming 32-bit width)
|
|
45
|
+
def row_count(bits_per_row = 32)
|
|
46
|
+
return 1 if @fields.empty?
|
|
47
|
+
|
|
48
|
+
((max_bit_position + 1).to_f / bits_per_row).ceil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Represents a field in a packet diagram
|
|
53
|
+
class PacketField
|
|
54
|
+
attr_accessor :bit_start, :bit_end, :label
|
|
55
|
+
|
|
56
|
+
def initialize(bit_start, bit_end, label)
|
|
57
|
+
@bit_start = bit_start.to_i
|
|
58
|
+
@bit_end = bit_end.to_i
|
|
59
|
+
@label = label
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Get the size of the field in bits
|
|
63
|
+
def size
|
|
64
|
+
@bit_end - @bit_start + 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get the row this field starts in (for 32-bit rows)
|
|
68
|
+
def start_row(bits_per_row = 32)
|
|
69
|
+
@bit_start / bits_per_row
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Get the row this field ends in (for 32-bit rows)
|
|
73
|
+
def end_row(bits_per_row = 32)
|
|
74
|
+
@bit_end / bits_per_row
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Check if this field spans multiple rows
|
|
78
|
+
def spans_rows?(bits_per_row = 32)
|
|
79
|
+
start_row(bits_per_row) != end_row(bits_per_row)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Get the bit position within a row (0-31 for 32-bit rows)
|
|
83
|
+
def start_bit_in_row(bits_per_row = 32)
|
|
84
|
+
@bit_start % bits_per_row
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Get the ending bit position within a row
|
|
88
|
+
def end_bit_in_row(bits_per_row = 32)
|
|
89
|
+
@bit_end % bits_per_row
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a slice in a pie chart.
|
|
9
|
+
#
|
|
10
|
+
# A slice represents a data point with a label and numeric value.
|
|
11
|
+
class PieSlice < Lutaml::Model::Serializable
|
|
12
|
+
# Label/name for this slice
|
|
13
|
+
attribute :label, :string
|
|
14
|
+
|
|
15
|
+
# Numeric value for this slice (can be integer or decimal)
|
|
16
|
+
attribute :value, :float
|
|
17
|
+
|
|
18
|
+
# Validates the slice has required attributes.
|
|
19
|
+
#
|
|
20
|
+
# @return [Boolean] true if slice is valid
|
|
21
|
+
def valid?
|
|
22
|
+
!label.nil? && !label.empty? && !value.nil?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Calculate percentage of total.
|
|
26
|
+
#
|
|
27
|
+
# @param total [Float] the total value of all slices
|
|
28
|
+
# @return [Float] percentage (0-100)
|
|
29
|
+
def percentage(total)
|
|
30
|
+
return 0.0 if total.zero?
|
|
31
|
+
|
|
32
|
+
(value.to_f / total) * 100.0
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Pie chart diagram model.
|
|
37
|
+
#
|
|
38
|
+
# Represents a complete pie chart with labeled slices showing
|
|
39
|
+
# proportional data distribution. Pie charts are useful for showing
|
|
40
|
+
# part-to-whole relationships.
|
|
41
|
+
#
|
|
42
|
+
# @example Creating a simple pie chart
|
|
43
|
+
# pie = Pie.new
|
|
44
|
+
# pie.title = 'Sales Report'
|
|
45
|
+
# pie.slices << PieSlice.new(label: 'Apples', value: 42.5)
|
|
46
|
+
# pie.slices << PieSlice.new(label: 'Oranges', value: 30.2)
|
|
47
|
+
# pie.slices << PieSlice.new(label: 'Bananas', value: 27.3)
|
|
48
|
+
class Pie < Base
|
|
49
|
+
# Collection of data slices in the pie chart
|
|
50
|
+
attribute :slices, PieSlice, collection: true, default: -> { [] }
|
|
51
|
+
|
|
52
|
+
# Whether to show data values on the chart
|
|
53
|
+
attribute :show_data, :boolean, default: -> { false }
|
|
54
|
+
|
|
55
|
+
# Accessibility title (for screen readers)
|
|
56
|
+
attribute :acc_title, :string
|
|
57
|
+
|
|
58
|
+
# Accessibility description (for screen readers)
|
|
59
|
+
attribute :acc_description, :string
|
|
60
|
+
|
|
61
|
+
# Returns the diagram type identifier.
|
|
62
|
+
#
|
|
63
|
+
# @return [Symbol] :pie
|
|
64
|
+
def diagram_type
|
|
65
|
+
:pie
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Validates the pie chart structure.
|
|
69
|
+
#
|
|
70
|
+
# A pie chart is valid if:
|
|
71
|
+
# - All slices (if any) are valid
|
|
72
|
+
# - All slice values are numeric
|
|
73
|
+
#
|
|
74
|
+
# Note: Empty pie charts are allowed for parsing tests
|
|
75
|
+
#
|
|
76
|
+
# @return [Boolean] true if pie chart is valid
|
|
77
|
+
def valid?
|
|
78
|
+
return true if slices.nil? || slices.empty?
|
|
79
|
+
|
|
80
|
+
slices.all?(&:valid?)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Calculate total value of all slices.
|
|
84
|
+
#
|
|
85
|
+
# @return [Float] sum of all slice values
|
|
86
|
+
def total_value
|
|
87
|
+
slices.sum(&:value)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Get slices with their calculated percentages.
|
|
91
|
+
#
|
|
92
|
+
# @return [Array<Hash>] array of hashes with :slice and :percentage
|
|
93
|
+
def slices_with_percentages
|
|
94
|
+
total = total_value
|
|
95
|
+
slices.map do |slice|
|
|
96
|
+
{
|
|
97
|
+
slice: slice,
|
|
98
|
+
percentage: slice.percentage(total),
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Calculate angle in degrees for a slice.
|
|
104
|
+
#
|
|
105
|
+
# @param slice [PieSlice] the slice to calculate angle for
|
|
106
|
+
# @return [Float] angle in degrees (0-360)
|
|
107
|
+
def slice_angle(slice)
|
|
108
|
+
total = total_value
|
|
109
|
+
return 0.0 if total.zero?
|
|
110
|
+
|
|
111
|
+
(slice.value / total) * 360.0
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a data point in a quadrant chart.
|
|
9
|
+
#
|
|
10
|
+
# A point has a label, normalized x/y coordinates (0-1 range),
|
|
11
|
+
# and optional styling parameters.
|
|
12
|
+
class QuadrantPoint < Lutaml::Model::Serializable
|
|
13
|
+
# Label/name for this point
|
|
14
|
+
attribute :label, :string
|
|
15
|
+
|
|
16
|
+
# X coordinate (normalized 0-1)
|
|
17
|
+
attribute :x, :float
|
|
18
|
+
|
|
19
|
+
# Y coordinate (normalized 0-1)
|
|
20
|
+
attribute :y, :float
|
|
21
|
+
|
|
22
|
+
# Optional radius for the point
|
|
23
|
+
attribute :radius, :float
|
|
24
|
+
|
|
25
|
+
# Optional fill color
|
|
26
|
+
attribute :color, :string
|
|
27
|
+
|
|
28
|
+
# Optional stroke color
|
|
29
|
+
attribute :stroke_color, :string
|
|
30
|
+
|
|
31
|
+
# Optional stroke width
|
|
32
|
+
attribute :stroke_width, :float
|
|
33
|
+
|
|
34
|
+
# Validates the point has required attributes.
|
|
35
|
+
#
|
|
36
|
+
# @return [Boolean] true if point is valid
|
|
37
|
+
def valid?
|
|
38
|
+
!label.nil? && !label.empty? && coordinate?(x) && coordinate?(y)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Determine which quadrant this point is in (1-4).
|
|
42
|
+
#
|
|
43
|
+
# Quadrants are numbered:
|
|
44
|
+
# - Quadrant 1: top-right (x >= 0.5, y >= 0.5)
|
|
45
|
+
# - Quadrant 2: top-left (x < 0.5, y >= 0.5)
|
|
46
|
+
# - Quadrant 3: bottom-left (x < 0.5, y < 0.5)
|
|
47
|
+
# - Quadrant 4: bottom-right (x >= 0.5, y < 0.5)
|
|
48
|
+
#
|
|
49
|
+
# @return [Integer] quadrant number (1-4)
|
|
50
|
+
def quadrant
|
|
51
|
+
return x < 0.5 ? 2 : 1 if y >= 0.5
|
|
52
|
+
|
|
53
|
+
x < 0.5 ? 3 : 4
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def coordinate?(value)
|
|
59
|
+
!value.nil? && value.between?(0.0, 1.0)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Quadrant chart diagram model.
|
|
64
|
+
#
|
|
65
|
+
# Represents a 2x2 quadrant chart for visualizing data points
|
|
66
|
+
# in a two-dimensional space. Useful for categorizing items
|
|
67
|
+
# based on two independent variables.
|
|
68
|
+
#
|
|
69
|
+
# @example Creating a simple quadrant chart
|
|
70
|
+
# chart = Quadrant.new
|
|
71
|
+
# chart.title = 'Product Analysis'
|
|
72
|
+
# chart.x_axis_left = 'Low Cost'
|
|
73
|
+
# chart.x_axis_right = 'High Cost'
|
|
74
|
+
# chart.y_axis_bottom = 'Low Value'
|
|
75
|
+
# chart.y_axis_top = 'High Value'
|
|
76
|
+
# chart.quadrant_1_label = 'Invest'
|
|
77
|
+
# chart.points << QuadrantPoint.new(label: 'Product A', x: 0.3, y: 0.7)
|
|
78
|
+
class Quadrant < Base
|
|
79
|
+
# X-axis label for the left side
|
|
80
|
+
attribute :x_axis_left, :string
|
|
81
|
+
|
|
82
|
+
# X-axis label for the right side
|
|
83
|
+
attribute :x_axis_right, :string
|
|
84
|
+
|
|
85
|
+
# Y-axis label for the bottom
|
|
86
|
+
attribute :y_axis_bottom, :string
|
|
87
|
+
|
|
88
|
+
# Y-axis label for the top
|
|
89
|
+
attribute :y_axis_top, :string
|
|
90
|
+
|
|
91
|
+
# Label for quadrant 1 (top-right)
|
|
92
|
+
attribute :quadrant_1_label, :string
|
|
93
|
+
|
|
94
|
+
# Label for quadrant 2 (top-left)
|
|
95
|
+
attribute :quadrant_2_label, :string
|
|
96
|
+
|
|
97
|
+
# Label for quadrant 3 (bottom-left)
|
|
98
|
+
attribute :quadrant_3_label, :string
|
|
99
|
+
|
|
100
|
+
# Label for quadrant 4 (bottom-right)
|
|
101
|
+
attribute :quadrant_4_label, :string
|
|
102
|
+
|
|
103
|
+
# Collection of data points in the chart
|
|
104
|
+
attribute :points, QuadrantPoint, collection: true, default: -> { [] }
|
|
105
|
+
|
|
106
|
+
# Returns the diagram type identifier.
|
|
107
|
+
#
|
|
108
|
+
# @return [Symbol] :quadrant
|
|
109
|
+
def diagram_type
|
|
110
|
+
:quadrant
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Validates the quadrant chart structure.
|
|
114
|
+
#
|
|
115
|
+
# A quadrant chart is valid if:
|
|
116
|
+
# - All points (if any) are valid
|
|
117
|
+
#
|
|
118
|
+
# Note: Axis labels are optional for minimal diagrams
|
|
119
|
+
#
|
|
120
|
+
# @return [Boolean] true if chart is valid
|
|
121
|
+
def valid?
|
|
122
|
+
return false unless points.all?(&:valid?)
|
|
123
|
+
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Get points grouped by quadrant.
|
|
128
|
+
#
|
|
129
|
+
# @return [Hash<Integer, Array<QuadrantPoint>>] points by quadrant
|
|
130
|
+
def points_by_quadrant
|
|
131
|
+
points.group_by(&:quadrant)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module Etassia
|
|
6
|
+
module Diagram
|
|
7
|
+
# Represents a radar/spider chart diagram
|
|
8
|
+
class Radar < Base
|
|
9
|
+
attr_accessor :title, :acc_title, :acc_descr, :axes, :curves, :options
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
super
|
|
13
|
+
@axes = []
|
|
14
|
+
@curves = []
|
|
15
|
+
@options = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the diagram type identifier.
|
|
19
|
+
#
|
|
20
|
+
# @return [Symbol] :radar
|
|
21
|
+
def diagram_type
|
|
22
|
+
:radar
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Radar charts have no validation rules yet. See TODO.foundation's
|
|
26
|
+
# corpus burndown for real validation; this is deliberately trivial.
|
|
27
|
+
#
|
|
28
|
+
# @return [Boolean] true
|
|
29
|
+
def valid?
|
|
30
|
+
true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Represents an axis in a radar chart
|
|
35
|
+
class RadarAxis
|
|
36
|
+
attr_accessor :id, :label
|
|
37
|
+
|
|
38
|
+
def initialize(id, label = nil)
|
|
39
|
+
@id = id
|
|
40
|
+
@label = label || id
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Represents a data curve/dataset in a radar chart
|
|
45
|
+
class RadarCurve
|
|
46
|
+
attr_accessor :id, :label, :values
|
|
47
|
+
|
|
48
|
+
def initialize(id, label = nil)
|
|
49
|
+
@id = id
|
|
50
|
+
@label = label || id
|
|
51
|
+
@values = {}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Add a value for an axis
|
|
55
|
+
def add_value(axis_id, value)
|
|
56
|
+
@values[axis_id] = value.to_f
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Get value for an axis
|
|
60
|
+
def value_for(axis_id)
|
|
61
|
+
@values[axis_id] || 0.0
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|