drawio_dsl 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.builders/_.rb +1 -0
- data/.builders/boot.rb +65 -0
- data/.builders/generators/01-bootstrap.rb +130 -0
- data/.builders/generators/10-layout.rb +21 -0
- data/.releaserc.json +40 -0
- data/.rspec +3 -0
- data/.rubocop.yml +93 -0
- data/.vscode/settings.json +3 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +44 -0
- data/Guardfile +30 -0
- data/LICENSE.txt +21 -0
- data/README.md +82 -0
- data/Rakefile +34 -0
- data/bin/console +16 -0
- data/bin/setup +11 -0
- data/lib/drawio_dsl/configuration.rb +118 -0
- data/lib/drawio_dsl/dom_builder.rb +103 -0
- data/lib/drawio_dsl/drawio.rb +103 -0
- data/lib/drawio_dsl/drawio_dsl-OLD.x +335 -0
- data/lib/drawio_dsl/layout_container.rb +54 -0
- data/lib/drawio_dsl/layout_engine.rb +47 -0
- data/lib/drawio_dsl/schema.rb +346 -0
- data/lib/drawio_dsl/version.rb +5 -0
- data/lib/drawio_dsl/xml_builder.rb +74 -0
- data/lib/drawio_dsl.rb +31 -0
- data/package-lock.json +10892 -0
- data/package.json +14 -0
- data/sig/drawio_dsl.rbs +4 -0
- metadata +130 -0
data/bin/setup
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Attach configuration to the DrawIO DSL module
|
4
|
+
module DrawioDsl
|
5
|
+
# Used to attach configuration to KConfig module
|
6
|
+
module ConfigurationExtension
|
7
|
+
def drawio
|
8
|
+
return @drawio if defined? @drawio
|
9
|
+
|
10
|
+
@drawio = DrawioDsl::Configuration.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Configuration container for the DrawIO DSL
|
15
|
+
class Configuration
|
16
|
+
include KLog::Logging
|
17
|
+
|
18
|
+
BaseStyle = Struct.new(:white_space, :html, :rounded, :shadow, :sketch, :glass, keyword_init: true)
|
19
|
+
|
20
|
+
ElementDefaults = Struct.new(:type, :x, :y, :w, :h, :style_modifiers)
|
21
|
+
ElementThemeStyle = Struct.new(:fill_color, :stroke_color, :font_color, :gradient, keyword_init: true)
|
22
|
+
|
23
|
+
attr_accessor :base_style
|
24
|
+
|
25
|
+
# Theme colors
|
26
|
+
attr_accessor :themes
|
27
|
+
|
28
|
+
# Element shapes
|
29
|
+
attr_accessor :element
|
30
|
+
attr_accessor :square
|
31
|
+
attr_accessor :rectangle
|
32
|
+
attr_accessor :circle
|
33
|
+
attr_accessor :process
|
34
|
+
attr_accessor :ellipse
|
35
|
+
attr_accessor :triangle
|
36
|
+
attr_accessor :parallelogram
|
37
|
+
attr_accessor :hexagon
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@base_style = BaseStyle.new(white_space: :wrap, html: 1, rounded: nil, shadow: nil, sketch: nil, glass: nil)
|
41
|
+
|
42
|
+
@element = ElementDefaults.new(:element , 0, 0, 20, 20, '')
|
43
|
+
@square = ElementDefaults.new(:square , 0, 0, 160, 160, '')
|
44
|
+
@rectangle = ElementDefaults.new(:rectangle , 0, 0, 240, 120, '')
|
45
|
+
@circle = ElementDefaults.new(:circle , 0, 0, 160, 160, 'ellipse')
|
46
|
+
@process = ElementDefaults.new(:process , 0, 0, 240, 120, 'shape=process')
|
47
|
+
@ellipse = ElementDefaults.new(:ellipse , 0, 0, 240, 120, 'ellipse')
|
48
|
+
@triangle = ElementDefaults.new(:triangle , 0, 0, 160, 160, 'rhombus')
|
49
|
+
|
50
|
+
@themes = {}
|
51
|
+
add_themes
|
52
|
+
end
|
53
|
+
|
54
|
+
def palette(theme)
|
55
|
+
@themes[theme]
|
56
|
+
end
|
57
|
+
|
58
|
+
def random_theme
|
59
|
+
@themes.keys.sample
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def add_theme(name, **opts)
|
65
|
+
@themes[name] = ElementThemeStyle.new(**opts)
|
66
|
+
end
|
67
|
+
|
68
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
69
|
+
def add_themes
|
70
|
+
add_theme(:style_01 , fill_color: '#f5f5f5', stroke_color: '#666666', font_color: '#333333')
|
71
|
+
add_theme(:style_02 , fill_color: '#dae8fc', stroke_color: '#6c8ebf', font_color: '#333333')
|
72
|
+
add_theme(:style_03 , fill_color: '#d5e8d4', stroke_color: '#82b366', font_color: '#333333')
|
73
|
+
add_theme(:style_04 , fill_color: '#ffe6cc', stroke_color: '#d79b00', font_color: '#333333')
|
74
|
+
add_theme(:style_05 , fill_color: '#fff2cc', stroke_color: '#d6b656', font_color: '#333333')
|
75
|
+
add_theme(:style_06 , fill_color: '#f8cecc', stroke_color: '#b85450', font_color: '#333333')
|
76
|
+
add_theme(:style_07 , fill_color: '#e1d5e7', stroke_color: '#9673a6', font_color: '#333333')
|
77
|
+
add_theme(:style_08 , fill_color: '#60a917', stroke_color: '#2D7600', font_color: '#ffffff')
|
78
|
+
add_theme(:style_09 , fill_color: '#008a00', stroke_color: '#005700', font_color: '#ffffff')
|
79
|
+
add_theme(:style_10 , fill_color: '#1ba1e2', stroke_color: '#006EAF', font_color: '#ffffff')
|
80
|
+
add_theme(:style_11 , fill_color: '#0050ef', stroke_color: '#001DBC', font_color: '#ffffff')
|
81
|
+
add_theme(:style_12 , fill_color: '#6a00ff', stroke_color: '#3700CC', font_color: '#ffffff')
|
82
|
+
add_theme(:style_13 , fill_color: '#aa00ff', stroke_color: '#7700CC', font_color: '#ffffff')
|
83
|
+
add_theme(:style_14 , fill_color: '#d80073', stroke_color: '#A50040', font_color: '#ffffff')
|
84
|
+
add_theme(:style_15 , fill_color: '#a20025', stroke_color: '#6F0000', font_color: '#ffffff')
|
85
|
+
add_theme(:style_16 , fill_color: '#e51400', stroke_color: '#B20000', font_color: '#ffffff')
|
86
|
+
add_theme(:style_17 , fill_color: '#fa6800', stroke_color: '#C73500', font_color: '#000000')
|
87
|
+
add_theme(:style_18 , fill_color: '#f0a30a', stroke_color: '#BD7000', font_color: '#000000')
|
88
|
+
add_theme(:style_19 , fill_color: '#e3c800', stroke_color: '#B09500', font_color: '#000000')
|
89
|
+
add_theme(:style_20 , fill_color: '#6d8764', stroke_color: '#3A5431', font_color: '#ffffff')
|
90
|
+
add_theme(:style_21 , fill_color: '#647687', stroke_color: '#314354', font_color: '#ffffff')
|
91
|
+
add_theme(:style_22 , fill_color: '#76608a', stroke_color: '#432D57', font_color: '#ffffff')
|
92
|
+
add_theme(:style_23 , fill_color: '#a0522d', stroke_color: '#6D1F00', font_color: '#ffffff')
|
93
|
+
add_theme(:style_24 , fill_color: '#fad7ac', stroke_color: '#b46504')
|
94
|
+
add_theme(:style_25 , fill_color: '#fad9d5', stroke_color: '#ae4132')
|
95
|
+
add_theme(:style_26 , fill_color: '#b0e3e6', stroke_color: '#0e8088')
|
96
|
+
add_theme(:style_27 , fill_color: '#b1ddf0', stroke_color: '#10739e')
|
97
|
+
add_theme(:style_28 , fill_color: '#d0cee2', stroke_color: '#56517e')
|
98
|
+
add_theme(:style_29 , fill_color: '#bac8d3', stroke_color: '#23445d')
|
99
|
+
add_theme(:style_30 , fill_color: '#f5f5f5', stroke_color: '#666666', gradient: '#b3b3b3')
|
100
|
+
add_theme(:style_31 , fill_color: '#dae8fc', stroke_color: '#6c8ebf', gradient: '#7ea6e0')
|
101
|
+
add_theme(:style_32 , fill_color: '#d5e8d4', stroke_color: '#82b366', gradient: '#97d077')
|
102
|
+
add_theme(:style_33 , fill_color: '#ffcd28', stroke_color: '#d79b00', gradient: '#ffa500')
|
103
|
+
add_theme(:style_34 , fill_color: '#fff2cc', stroke_color: '#d6b656', gradient: '#ffd966')
|
104
|
+
add_theme(:style_35 , fill_color: '#f8cecc', stroke_color: '#b85450', gradient: '#ea6b66')
|
105
|
+
add_theme(:style_36 , fill_color: '#e6d0de', stroke_color: '#996185', gradient: '#d5739d')
|
106
|
+
add_theme(:style_37 , fill_color: '#eeeeee', stroke_color: '#36393d')
|
107
|
+
add_theme(:style_38 , fill_color: '#f9f7ed', stroke_color: '#36393d')
|
108
|
+
add_theme(:style_39 , fill_color: '#ffcc99', stroke_color: '#36393d')
|
109
|
+
add_theme(:style_40 , fill_color: '#cce5ff', stroke_color: '#36393d')
|
110
|
+
add_theme(:style_41 , fill_color: '#ffff88', stroke_color: '#36393d')
|
111
|
+
add_theme(:style_42 , fill_color: '#cdeb8b', stroke_color: '#36393d')
|
112
|
+
add_theme(:style_43 , fill_color: '#ffcccc', stroke_color: '#36393d')
|
113
|
+
end
|
114
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
KConfig::Configuration.register(:drawio, DrawioDsl::ConfigurationExtension)
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DrawioDsl
|
4
|
+
# DrawioDsl is a DSL for draw-io diagrams.
|
5
|
+
class DomBuilder
|
6
|
+
attr_reader :actions
|
7
|
+
attr_reader :last_action
|
8
|
+
|
9
|
+
attr_reader :current_page
|
10
|
+
attr_reader :current_element
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@actions = []
|
14
|
+
@last_action = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def reset
|
18
|
+
@actions = []
|
19
|
+
@last_action = {}
|
20
|
+
set_diagram
|
21
|
+
set_layout_engine
|
22
|
+
end
|
23
|
+
|
24
|
+
def queue_action(action)
|
25
|
+
@actions << action
|
26
|
+
@last_action = action
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_layout_engine(**opts)
|
30
|
+
@layout_engine = DrawioDsl::LayoutEngine.new(**opts)
|
31
|
+
end
|
32
|
+
|
33
|
+
def layout_engine
|
34
|
+
return @layout_engine if defined? @layout_engine
|
35
|
+
|
36
|
+
set_layout_engine
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_diagram(**opts)
|
40
|
+
@diagram = DrawioDsl::Schema::Diagram.new(**opts)
|
41
|
+
end
|
42
|
+
|
43
|
+
def diagram
|
44
|
+
return @diagram if defined? @diagram
|
45
|
+
|
46
|
+
set_diagram
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_page(**opts)
|
50
|
+
@current_page = DrawioDsl::Schema::Page.new(diagram, **opts)
|
51
|
+
|
52
|
+
current_page.id = SecureRandom.alphanumeric(3) unless current_page.id
|
53
|
+
|
54
|
+
diagram.pages << @current_page
|
55
|
+
@current_page
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_element(element)
|
59
|
+
@current_element = element
|
60
|
+
|
61
|
+
element.id = "#{current_page.id}-#{current_page.elements.length + 1}" unless element.id
|
62
|
+
|
63
|
+
layout_engine.container.place_element(element)
|
64
|
+
|
65
|
+
current_page.elements << element
|
66
|
+
@current_element
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_square(**opts)
|
70
|
+
square = DrawioDsl::Schema::Square.new(current_page, **opts)
|
71
|
+
add_element(square)
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_rectangle(**opts)
|
75
|
+
rectangle = DrawioDsl::Schema::Rectangle.new(current_page, **opts)
|
76
|
+
add_element(rectangle)
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_circle(**opts)
|
80
|
+
circle = DrawioDsl::Schema::Circle.new(current_page, **opts)
|
81
|
+
add_element(circle)
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_process(**opts)
|
85
|
+
process = DrawioDsl::Schema::Process.new(current_page, **opts)
|
86
|
+
add_element(process)
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_ellipse(**opts)
|
90
|
+
ellipse = DrawioDsl::Schema::Ellipse.new(current_page, **opts)
|
91
|
+
add_element(ellipse)
|
92
|
+
end
|
93
|
+
|
94
|
+
def debug
|
95
|
+
puts JSON.pretty_generate(actions)
|
96
|
+
puts JSON.pretty_generate(diagram.to_h)
|
97
|
+
end
|
98
|
+
|
99
|
+
def dom
|
100
|
+
diagram.to_h
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DrawioDsl
|
4
|
+
# DrawioDsl is a DSL for draw-io diagrams.
|
5
|
+
class Drawio < KDirector::Directors::BaseDirector
|
6
|
+
default_builder_type(DrawioDsl::DomBuilder)
|
7
|
+
|
8
|
+
def layout(**opts)
|
9
|
+
builder.set_layout_engine(**opts)
|
10
|
+
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def diagram(**opts)
|
15
|
+
builder.set_diagram(**opts)
|
16
|
+
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def page(name = nil, **opts, &block)
|
21
|
+
page = DrawioDsl::DrawioPage.new(self, **opts.merge(name: name))
|
22
|
+
page.instance_eval(&block) if block_given?
|
23
|
+
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# DrawioDsl::DrawioPage is created when you call .page on the draw-io DSL.
|
29
|
+
class DrawioPage < KDirector::Directors::ChildDirector
|
30
|
+
attr_reader :auto_layout
|
31
|
+
attr_reader :current_x
|
32
|
+
attr_reader :current_y
|
33
|
+
|
34
|
+
def initialize(parent, **opts)
|
35
|
+
super(parent, **opts)
|
36
|
+
|
37
|
+
@auto_layout = true
|
38
|
+
@current_x = 20
|
39
|
+
@current_y = 20
|
40
|
+
|
41
|
+
builder.add_page(**opts)
|
42
|
+
end
|
43
|
+
|
44
|
+
def square(**opts)
|
45
|
+
opts = attach_xy(**opts)
|
46
|
+
builder.add_square(**opts)
|
47
|
+
update_layout
|
48
|
+
end
|
49
|
+
|
50
|
+
def rectangle(**opts)
|
51
|
+
opts = attach_xy(**opts)
|
52
|
+
builder.add_rectangle(**opts)
|
53
|
+
update_layout
|
54
|
+
end
|
55
|
+
|
56
|
+
def circle(**opts)
|
57
|
+
opts = attach_xy(**opts)
|
58
|
+
builder.add_circle(**opts)
|
59
|
+
update_layout
|
60
|
+
end
|
61
|
+
|
62
|
+
def process(**opts)
|
63
|
+
opts = attach_xy(**opts)
|
64
|
+
builder.add_process(**opts)
|
65
|
+
update_layout
|
66
|
+
end
|
67
|
+
|
68
|
+
def ellipse(**opts)
|
69
|
+
opts = attach_xy(**opts)
|
70
|
+
builder.add_ellipse(**opts)
|
71
|
+
update_layout
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def current_element
|
77
|
+
builder.current_element
|
78
|
+
end
|
79
|
+
|
80
|
+
# attr_reader :layout_engine
|
81
|
+
# set_layout
|
82
|
+
|
83
|
+
# layout.container.place_element(element)
|
84
|
+
|
85
|
+
def update_layout
|
86
|
+
return unless auto_layout
|
87
|
+
|
88
|
+
# puts current_element.page.x
|
89
|
+
# puts current_element.page.y
|
90
|
+
# puts current_element.page.w
|
91
|
+
# puts current_element.page.h
|
92
|
+
|
93
|
+
@current_x += current_element.w + 20
|
94
|
+
@current_y += current_element.h + 20
|
95
|
+
end
|
96
|
+
|
97
|
+
def attach_xy(**opts)
|
98
|
+
opts[:x] ||= current_x
|
99
|
+
opts[:y] ||= current_y
|
100
|
+
opts
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,335 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDirector
|
4
|
+
module Dsls
|
5
|
+
class DrawioXmlBuilder
|
6
|
+
include KLog::Logging
|
7
|
+
|
8
|
+
attr_reader :host
|
9
|
+
attr_reader :pages
|
10
|
+
|
11
|
+
attr_reader :current_id
|
12
|
+
attr_reader :row_index
|
13
|
+
attr_reader :row_offset
|
14
|
+
|
15
|
+
def initialize(opts, dom)
|
16
|
+
@host = opts[:host] || SecureRandom.alphanumeric(4)
|
17
|
+
@pages = dom[:pages] || []
|
18
|
+
# puts JSON.pretty_generate(dom)
|
19
|
+
|
20
|
+
@current_id = 10
|
21
|
+
@row_index = 0
|
22
|
+
@row_offset = 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def build
|
26
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
27
|
+
xml.mxfile(host: host) do
|
28
|
+
page_index = 0
|
29
|
+
pages.each do |page|
|
30
|
+
build_page(xml, page, page_index)
|
31
|
+
page_index += 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
xml_builder.to_xml.sub('<?xml version="1.0"?>', '').strip
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def next_id
|
42
|
+
result = @current_id
|
43
|
+
@current_id += 1
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
def next_row
|
48
|
+
@row_index += 150
|
49
|
+
end
|
50
|
+
|
51
|
+
def current_row_index
|
52
|
+
row_index + row_offset
|
53
|
+
end
|
54
|
+
|
55
|
+
def reset_row
|
56
|
+
@row_index = 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def random_text
|
60
|
+
return '' if rand(5) == 1
|
61
|
+
|
62
|
+
words = %w[
|
63
|
+
substantial
|
64
|
+
humor
|
65
|
+
jeans
|
66
|
+
hover
|
67
|
+
encouraging
|
68
|
+
glue
|
69
|
+
used
|
70
|
+
statuesque
|
71
|
+
umbrella
|
72
|
+
vigorous
|
73
|
+
horses
|
74
|
+
outgoing
|
75
|
+
]
|
76
|
+
|
77
|
+
# return a random word
|
78
|
+
words.sample
|
79
|
+
end
|
80
|
+
|
81
|
+
def element_color
|
82
|
+
element_colors = %w[
|
83
|
+
fillColor=#d0cee2;strokeColor=#56517e;fontColor=#333333;
|
84
|
+
fillColor=#FFCCCC;strokeColor=#36393D;fontColor=#333333;
|
85
|
+
fillColor=#CDEB8B;strokeColor=#36393D;fontColor=#333333;
|
86
|
+
fillColor=#FFFF88;strokeColor=#36393D;fontColor=#333333;
|
87
|
+
fillColor=#CCE5FF;strokeColor=#36393D;fontColor=#333333;
|
88
|
+
fillColor=#FFCC99;strokeColor=#36393D;fontColor=#333333;
|
89
|
+
fillColor=#F9F7ED;strokeColor=#36393D;fontColor=#333333;
|
90
|
+
fillColor=#EEEEEE;strokeColor=#36393D;fontColor=#333333;
|
91
|
+
fillColor=#BAC8D3;strokeColor=#23445D;fontColor=#333333;
|
92
|
+
fillColor=#D0CEE2;strokeColor=#56517E;fontColor=#333333;
|
93
|
+
fillColor=#B1DDF0;strokeColor=#10739E;fontColor=#333333;
|
94
|
+
fillColor=#B0E3E6;strokeColor=#0E8088;fontColor=#333333;
|
95
|
+
fillColor=#FAD9D5;strokeColor=#AE4132;fontColor=#333333;
|
96
|
+
]
|
97
|
+
|
98
|
+
# return a random color
|
99
|
+
element_colors.sample
|
100
|
+
# nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_page(xml, page, page_index)
|
104
|
+
page_id = SecureRandom.alphanumeric(3).to_s
|
105
|
+
@row_offset = 50 # Random.rand(350)
|
106
|
+
|
107
|
+
xml.diagram(id: page_id, name: page[:name]) do
|
108
|
+
size_ratio = Random.rand(0.5..3.0)
|
109
|
+
size_ratio = 2
|
110
|
+
|
111
|
+
reset_row
|
112
|
+
|
113
|
+
grid = 1
|
114
|
+
element_style = ''
|
115
|
+
|
116
|
+
case page_index
|
117
|
+
when 1
|
118
|
+
element_style = 'sketch=1'
|
119
|
+
grid = 0
|
120
|
+
when 2
|
121
|
+
element_style = 'shadow=1'
|
122
|
+
when 3
|
123
|
+
element_style = 'sketch=1;shadow=1'
|
124
|
+
grid = 0
|
125
|
+
end
|
126
|
+
|
127
|
+
# background = "##{SecureRandom.hex(3)}"
|
128
|
+
background = '#FFFACD'
|
129
|
+
# background = nil
|
130
|
+
|
131
|
+
# background="#FF99CC" backgroundImage="{"src":"data:page/id,AKs"}" math="0" shadow="1"
|
132
|
+
xml.mxGraphModel(dx: 800, dy: 583, background: background, grid: grid, gridSize: 10, guides: 1, tooltips: 1, connect: 1, arrows: 1, fold: 1, page: page_index, pageScale: 1, pageWidth: 1169,
|
133
|
+
pageHeight: 827, math: 0, shadow: 0) do
|
134
|
+
xml.root do
|
135
|
+
xml.mxCell(id: "#{page_id}-0")
|
136
|
+
xml.mxCell(id: "#{page_id}-1", parent: "#{page_id}-0")
|
137
|
+
|
138
|
+
# ------ Row 1 ------
|
139
|
+
|
140
|
+
# Square
|
141
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}", vertex: '1') do
|
142
|
+
xml.mxGeometry(x: size_ratio * 50 , y: size_ratio * current_row_index, width: size_ratio * 80, height: size_ratio * 80, as: 'geometry')
|
143
|
+
end
|
144
|
+
# Rectangle
|
145
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "rounded=0;whiteSpace=wrap;html=1;#{element_style};#{element_color}", vertex: '1') do
|
146
|
+
xml.mxGeometry(x: size_ratio * 170 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 60, as: 'geometry')
|
147
|
+
end
|
148
|
+
# Rectangle - Rounded
|
149
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "rounded=1;whiteSpace=wrap;html=1;#{element_style};#{element_color}", vertex: '1') do
|
150
|
+
xml.mxGeometry(x: size_ratio * 330 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 60, as: 'geometry')
|
151
|
+
end
|
152
|
+
|
153
|
+
# ------ Row 2 ------
|
154
|
+
|
155
|
+
next_row
|
156
|
+
|
157
|
+
# Circle
|
158
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "ellipse;whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}",
|
159
|
+
vertex: '1') do
|
160
|
+
xml.mxGeometry(x: size_ratio * 50 , y: size_ratio * current_row_index, width: size_ratio * 80, height: size_ratio * 80, as: 'geometry')
|
161
|
+
end
|
162
|
+
|
163
|
+
# Process
|
164
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text,
|
165
|
+
style: "shape=process;whiteSpace=wrap;html=1;aspect=fixed;backgroundOutline=1;#{element_style};#{element_color}", vertex: '1') do
|
166
|
+
xml.mxGeometry(x: size_ratio * 170 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 80, as: 'geometry')
|
167
|
+
end
|
168
|
+
|
169
|
+
# Ellipse
|
170
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "ellipse;whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}",
|
171
|
+
vertex: '1') do
|
172
|
+
xml.mxGeometry(x: size_ratio * 330 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 80, as: 'geometry')
|
173
|
+
end
|
174
|
+
|
175
|
+
# ------ Row 3 ------
|
176
|
+
|
177
|
+
next_row
|
178
|
+
|
179
|
+
# Rhombus
|
180
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "rhombus;whiteSpace=wrap;html=1;#{element_style};#{element_color}", vertex: '1') do
|
181
|
+
xml.mxGeometry(x: size_ratio * 50 , y: size_ratio * current_row_index, width: size_ratio * 80, height: size_ratio * 80, as: 'geometry')
|
182
|
+
end
|
183
|
+
|
184
|
+
# Parallelogram
|
185
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text,
|
186
|
+
style: "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;#{element_style};#{element_color}", vertex: '1') do
|
187
|
+
xml.mxGeometry(x: size_ratio * 170 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 60, as: 'geometry')
|
188
|
+
end
|
189
|
+
|
190
|
+
# Hexagon
|
191
|
+
xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text,
|
192
|
+
style: "shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;#{element_style};#{element_color}", vertex: '1') do
|
193
|
+
xml.mxGeometry(x: size_ratio * 330 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 80, as: 'geometry')
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# DrawioDsl is a DSL for draw-io diagrams.
|
202
|
+
class DrawioDsl < KDirector::Directors::BaseDirector
|
203
|
+
def default_template_base_folder
|
204
|
+
'drawio'
|
205
|
+
end
|
206
|
+
|
207
|
+
def page(name = nil, **opts, &block)
|
208
|
+
page = KDirector::Dsls::DrawioPage.new(self, **opts.merge(name: name))
|
209
|
+
page.instance_eval(&block) if block_given?
|
210
|
+
|
211
|
+
self
|
212
|
+
end
|
213
|
+
|
214
|
+
def create_diagram(name = nil, **opts)
|
215
|
+
xml_builder = DrawioXmlBuilder.new(opts, builder.dom)
|
216
|
+
add_file(name, content: xml_builder.build)
|
217
|
+
play_actions
|
218
|
+
|
219
|
+
self
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
class DrawioPage < KDirector::Directors::ChildDirector
|
224
|
+
attr_reader :name
|
225
|
+
attr_reader :data
|
226
|
+
|
227
|
+
def initialize(parent, **opts)
|
228
|
+
super(parent, **opts)
|
229
|
+
@name = opts[:name] || SecureRandom.alphanumeric(4)
|
230
|
+
@data = { name: name, elements: [] }
|
231
|
+
|
232
|
+
parent.builder.add(:pages, value: data) # , **repo_info_hash(**defaults))
|
233
|
+
end
|
234
|
+
|
235
|
+
def element(name = nil, **opts) # , &block)
|
236
|
+
data[:elements] << opts.merge(name: name)
|
237
|
+
end
|
238
|
+
|
239
|
+
def square(_name = nil, **opts)
|
240
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
241
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
242
|
+
|
243
|
+
# available params
|
244
|
+
# x, :y, :width, :height, :value
|
245
|
+
element(:square, **opts.merge(style: style))
|
246
|
+
end
|
247
|
+
|
248
|
+
def rectangle(_name = nil, **opts)
|
249
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
250
|
+
style = 'whiteSpace=wrap;html=1'
|
251
|
+
|
252
|
+
# available params
|
253
|
+
# x, :y, :width, :height, :value, :rounded
|
254
|
+
element(:square, **opts.merge(style: style))
|
255
|
+
end
|
256
|
+
|
257
|
+
def circle(_name = nil, **opts)
|
258
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
259
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
260
|
+
|
261
|
+
# available params
|
262
|
+
# x, :y, :width, :height, :value
|
263
|
+
element(:circle, **opts.merge(style: style))
|
264
|
+
end
|
265
|
+
|
266
|
+
def process(_name = nil, **opts)
|
267
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
268
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
269
|
+
|
270
|
+
# available params
|
271
|
+
# x, :y, :width, :height, :value
|
272
|
+
|
273
|
+
element(:process, **opts.merge(style: style))
|
274
|
+
end
|
275
|
+
|
276
|
+
def ellipse(_name = nil, **opts)
|
277
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
278
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
279
|
+
|
280
|
+
# available params
|
281
|
+
# x, :y, :width, :height, :value
|
282
|
+
|
283
|
+
element(:ellipse, **opts.merge(style: style))
|
284
|
+
end
|
285
|
+
|
286
|
+
def interface(_name = nil, **opts)
|
287
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
288
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
289
|
+
|
290
|
+
# available params
|
291
|
+
# x, :y, :width, :height, :value
|
292
|
+
|
293
|
+
element(:ellipse, **opts.merge(style: style))
|
294
|
+
end
|
295
|
+
|
296
|
+
def object(_name = nil, **opts)
|
297
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
298
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
299
|
+
|
300
|
+
# available params
|
301
|
+
# x, :y, :width, :height, :value
|
302
|
+
|
303
|
+
element(:ellipse, **opts.merge(style: style))
|
304
|
+
end
|
305
|
+
|
306
|
+
def component(_name = nil, **opts)
|
307
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
308
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
309
|
+
|
310
|
+
# available params
|
311
|
+
# x, :y, :width, :height, :value
|
312
|
+
|
313
|
+
element(:ellipse, **opts.merge(style: style))
|
314
|
+
end
|
315
|
+
|
316
|
+
def package(_name = nil, **opts)
|
317
|
+
# style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
|
318
|
+
style = 'whiteSpace=wrap;html=1;aspect=fixed'
|
319
|
+
|
320
|
+
# available params
|
321
|
+
# x, :y, :width, :height, :value
|
322
|
+
|
323
|
+
element(:ellipse, **opts.merge(style: style))
|
324
|
+
end
|
325
|
+
|
326
|
+
def lines(name = nil, **opts); end
|
327
|
+
def enum(name = nil, **opts); end
|
328
|
+
def box(name = nil, **opts); end
|
329
|
+
def down(name = nil, **opts); end
|
330
|
+
def right(name = nil, **opts); end
|
331
|
+
def left(name = nil, **opts); end
|
332
|
+
def up(name = nil, **opts); end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|