archimate 2.0.3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24983cbe0a25eb6b4fdd4592faf9d424f3f6dab8a0a28495cfa0c79f81bf6f18
4
- data.tar.gz: 91796ec52b8680a1449c8a9e424894e786191a82b2e96679ca767dee69ffa04a
3
+ metadata.gz: 0f7cec778a203f45d8559a57bebf5ad29fbecfaad296d3c4a0b9fdc47d746baa
4
+ data.tar.gz: 304983b0c9afd59fdd6f703a0866fc29f716da49681970d3fa3b2736d9f0b8f1
5
5
  SHA512:
6
- metadata.gz: 6b3d2698127d1aad4f6f729ef1735322658670e8527ab0d7a746ca23c9c7d77669ccb9751d731a4efe431355bf376904237f3a85fd60edf260f252a411a1a6be
7
- data.tar.gz: 530ce2ba4cb376a6120fcb2c80c7aab6f2eed57c02a6dff21825de3018079c3714e39fec69728bc6dd38bbc0e8433e87d9c9d9fd458c9a4914738af2ad1cb0c5
6
+ metadata.gz: 5229b50c9b1af5e15e505f331ff197d3cbaf8519b0f93c3f7b636c852b282fcf8c15a9a05311ef7c2e8979c386deed3601be48d201e598e2523b854ec25c6bd6
7
+ data.tar.gz: 1cbb2a88d904e7a08e756c7ea51ba745a5c0da6dd4deb382359f3638fcdd593da18f1c007db24108e500a86529b6bc7cac4cb8cab791e02848ec09d1db4e3e8e
data/bin/archimate CHANGED
@@ -15,7 +15,7 @@ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
15
15
  bundle_binstub = File.expand_path("../bundle", __FILE__)
16
16
 
17
17
  if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
19
  load(bundle_binstub)
20
20
  else
21
21
  abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
@@ -62,12 +62,24 @@ module Archimate
62
62
  type: :boolean,
63
63
  default: false,
64
64
  desc: "Use diagram name for filename (default: diagram id)"
65
+ option :format_xml,
66
+ aliases: :f,
67
+ type: :boolean,
68
+ default: true,
69
+ desc: "Format (pretty print) the SVG output (default: true)"
70
+ option :legend,
71
+ aliases: :l,
72
+ type: :boolean,
73
+ default: false,
74
+ desc: "Include an ArchiMate legend in each diagram"
65
75
  def svg(archifile)
66
76
  Config.instance.interactive = !options.fetch("noninteractive", false)
67
77
  Archimate::Cli::Svger.export_svgs(
68
78
  archifile,
69
79
  options.fetch("output", Dir.pwd),
70
- options["name"] ? :name : :id
80
+ svg_name: options["name"] ? :name : :id,
81
+ legend: options["legend"],
82
+ format_xml: options["format_xml"]
71
83
  )
72
84
  end
73
85
 
@@ -2,18 +2,25 @@
2
2
 
3
3
  module Archimate
4
4
  module Cli
5
- SVG_NAME_OPTION = [:id, :name] # TODO: add a way to export in folders with :folder_name]
5
+ SVG_NAME_OPTION = %i[id name].freeze # TODO: add a way to export in folders with :folder_name]
6
+ DEFAULT_OPTIONS = {
7
+ svg_name: :id,
8
+ format_xml: true,
9
+ legend: false
10
+ }.freeze
6
11
 
7
12
  # This class is used to export SVG diagrams as defined in the given model
8
13
  class Svger
9
- def self.export_svgs(archi_file, output_dir, name_option = :id)
10
- new(Archimate.read(archi_file).diagrams, output_dir, name_option).export_svgs
14
+ attr_reader :options
15
+
16
+ def self.export_svgs(archi_file, output_dir, options = {})
17
+ new(Archimate.read(archi_file).diagrams, output_dir, options).export_svgs
11
18
  end
12
19
 
13
- def initialize(diagrams, output_dir, name_option = :id)
20
+ def initialize(diagrams, output_dir, options = {})
21
+ @options = DEFAULT_OPTIONS.merge(options)
14
22
  @diagrams = diagrams
15
23
  @output_dir = output_dir
16
- @name_option = name_option
17
24
  @diagram_base_names = {}
18
25
  end
19
26
 
@@ -21,7 +28,7 @@ module Archimate
21
28
  @diagram_base_names = {}
22
29
  progress = ProgressIndicator.new(total: @diagrams.size, title: "Writing SVGs")
23
30
  @diagrams.each do |diagram|
24
- export(diagram, filename_for(diagram, @name_option))
31
+ export(diagram, filename_for(diagram, options[:svg_name]))
25
32
  progress.increment
26
33
  end
27
34
  ensure
@@ -31,7 +38,7 @@ module Archimate
31
38
  def export(diagram, file_name = nil)
32
39
  file_name = Cli.process_svg_filename(file_name || diagram.id)
33
40
  File.open(File.join(@output_dir, file_name), "wb") do |svg_file|
34
- svg_file.write(Svg::Diagram.new(diagram).to_svg)
41
+ svg_file.write(Svg::Diagram.new(diagram, options).to_svg)
35
42
  end
36
43
  end
37
44
 
@@ -40,10 +47,8 @@ module Archimate
40
47
  base_name = diagram_base_name(diagram, name_option)
41
48
  if @diagram_base_names.include?(base_name)
42
49
  idx = 2
43
- while @diagram_base_names.include?(base_name + " - #{idx}") do
44
- idx += 1
45
- end
46
- base_name = base_name + " - #{idx}"
50
+ idx += 1 while @diagram_base_names.include?(base_name + " - #{idx}")
51
+ base_name += " - #{idx}"
47
52
  end
48
53
  base_name
49
54
  end
@@ -9,6 +9,7 @@ module Archimate
9
9
  # attribute of +xsi:type="BusinessRole"+ where +BusinessRole+ is a derived
10
10
  # type from [ElementType].
11
11
  class Element
12
+ LAYER = Layers::None
12
13
  include Comparison
13
14
  include Referenceable
14
15
  include RelationshipReferences
@@ -8,6 +8,8 @@ module Archimate
8
8
  #############################################################
9
9
 
10
10
  class BusinessActor < Element
11
+ NAME = "Business Actor"
12
+ DESCRIPTION = "A business actor is a business entity that is capable of performing behavior."
11
13
  CLASSIFICATION = :active_structure
12
14
  LAYER = Layers::Business
13
15
 
@@ -17,6 +19,8 @@ module Archimate
17
19
  end
18
20
 
19
21
  class BusinessCollaboration < Element
22
+ NAME = "Business Collaboration"
23
+ DESCRIPTION = "A business collaboration is an aggregate of two or more business internal active structure elements that work together to perform collective behavior."
20
24
  CLASSIFICATION = :active_structure
21
25
  LAYER = Layers::Business
22
26
 
@@ -26,6 +30,8 @@ module Archimate
26
30
  end
27
31
 
28
32
  class BusinessEvent < Element
33
+ NAME = "Business Event"
34
+ DESCRIPTION = "A business event is a business behavior element that denotes an organizational state change. It may originate from and be resolved inside or outside the organization."
29
35
  CLASSIFICATION = :behavioral
30
36
  LAYER = Layers::Business
31
37
 
@@ -35,6 +41,8 @@ module Archimate
35
41
  end
36
42
 
37
43
  class BusinessFunction < Element
44
+ NAME = "Business Function"
45
+ DESCRIPTION = "A business function is a collection of business behavior based on a chosen set of criteria (typically required business resources and/or competencies), closely aligned to an organization, but not necessarily explicitly governed by the organization."
38
46
  CLASSIFICATION = :behavioral
39
47
  LAYER = Layers::Business
40
48
 
@@ -44,6 +52,8 @@ module Archimate
44
52
  end
45
53
 
46
54
  class BusinessInteraction < Element
55
+ NAME = "Business Interaction"
56
+ DESCRIPTION = "A business interaction is a unit of collective business behavior performed by (a collaboration of) two or more business roles."
47
57
  CLASSIFICATION = :behavioral
48
58
  LAYER = Layers::Business
49
59
 
@@ -53,6 +63,8 @@ module Archimate
53
63
  end
54
64
 
55
65
  class BusinessInterface < Element
66
+ NAME = "Business Interface"
67
+ DESCRIPTION = "A business interface is a point of access where a business service is made available to the environment."
56
68
  CLASSIFICATION = :active_structure
57
69
  LAYER = Layers::Business
58
70
 
@@ -62,6 +74,8 @@ module Archimate
62
74
  end
63
75
 
64
76
  class BusinessObject < Element
77
+ NAME = "Business Object"
78
+ DESCRIPTION = "A business object represents a concept used within a particular business domain."
65
79
  CLASSIFICATION = :passive_structure
66
80
  LAYER = Layers::Business
67
81
 
@@ -71,6 +85,8 @@ module Archimate
71
85
  end
72
86
 
73
87
  class BusinessProcess < Element
88
+ NAME = "Business Process"
89
+ DESCRIPTION = "A business process represents a sequence of business behaviors that achieves a specific outcome such as a defined set of products or business services."
74
90
  CLASSIFICATION = :behavioral
75
91
  LAYER = Layers::Business
76
92
 
@@ -80,6 +96,8 @@ module Archimate
80
96
  end
81
97
 
82
98
  class BusinessRole < Element
99
+ NAME = "Business Role"
100
+ DESCRIPTION = "A business role is the responsibility for performing specific behavior, to which an actor can be assigned, or the part an actor plays in a particular action or event."
83
101
  CLASSIFICATION = :active_structure
84
102
  LAYER = Layers::Business
85
103
 
@@ -89,6 +107,8 @@ module Archimate
89
107
  end
90
108
 
91
109
  class BusinessService < Element
110
+ NAME = "Business Service"
111
+ DESCRIPTION = "A business service represents an explicitly defined exposed business behavior."
92
112
  CLASSIFICATION = :behavioral
93
113
  LAYER = Layers::Business
94
114
 
@@ -98,6 +118,8 @@ module Archimate
98
118
  end
99
119
 
100
120
  class Contract < Element
121
+ NAME = "Contract"
122
+ DESCRIPTION = "A contract represents a formal or informal specification of an agreement between a provider and a consumer that specifies the rights and obligations associated with a product and establishes functional and non-functional parameters for interaction."
101
123
  CLASSIFICATION = :passive_structure
102
124
  LAYER = Layers::Business
103
125
 
@@ -107,6 +129,8 @@ module Archimate
107
129
  end
108
130
 
109
131
  class Location < Element
132
+ NAME = "Location"
133
+ DESCRIPTION = "A location is a place or position where structure elements can be located or behavior can be performed."
110
134
  CLASSIFICATION = :active_structure
111
135
  LAYER = Layers::Business
112
136
 
@@ -116,6 +140,8 @@ module Archimate
116
140
  end
117
141
 
118
142
  class Product < Element
143
+ NAME = "Product"
144
+ DESCRIPTION = "A product represents a coherent collection of services and/or passive structure elements, accompanied by a contract/set of agreements, which is offered as a whole to (internal or external) customers."
119
145
  CLASSIFICATION = :passive_structure
120
146
  LAYER = Layers::Business
121
147
 
@@ -125,6 +151,8 @@ module Archimate
125
151
  end
126
152
 
127
153
  class Representation < Element
154
+ NAME = "Representation"
155
+ DESCRIPTION = "A representation represents a perceptible form of the information carried by a business object."
128
156
  CLASSIFICATION = :passive_structure
129
157
  LAYER = Layers::Business
130
158
 
@@ -138,6 +166,8 @@ module Archimate
138
166
  #############################################################
139
167
 
140
168
  class ApplicationCollaboration < Element
169
+ NAME = "Application Collaboration"
170
+ DESCRIPTION = "An application collaboration represents an aggregate of two or more application components that work together to perform collective application behavior."
141
171
  CLASSIFICATION = :active_structure
142
172
  LAYER = Layers::Application
143
173
 
@@ -147,6 +177,8 @@ module Archimate
147
177
  end
148
178
 
149
179
  class ApplicationComponent < Element
180
+ NAME = "Application Component"
181
+ DESCRIPTION = "An application component represents an encapsulation of application functionality aligned to implementation structure, which is modular and replaceable. It encapsulates its behavior and data, exposes services, and makes them available through interfaces."
150
182
  CLASSIFICATION = :active_structure
151
183
  LAYER = Layers::Application
152
184
 
@@ -156,6 +188,8 @@ module Archimate
156
188
  end
157
189
 
158
190
  class ApplicationEvent < Element
191
+ NAME = "Application Event"
192
+ DESCRIPTION = "An application event is an application behavior element that denotes a state change."
159
193
  CLASSIFICATION = :behavioral
160
194
  LAYER = Layers::Application
161
195
 
@@ -165,6 +199,8 @@ module Archimate
165
199
  end
166
200
 
167
201
  class ApplicationFunction < Element
202
+ NAME = "Application Function"
203
+ DESCRIPTION = "An application function represents automated behavior that can be performed by an application component."
168
204
  CLASSIFICATION = :behavioral
169
205
  LAYER = Layers::Application
170
206
 
@@ -174,6 +210,8 @@ module Archimate
174
210
  end
175
211
 
176
212
  class ApplicationInteraction < Element
213
+ NAME = "Application Interaction"
214
+ DESCRIPTION = "An application interaction represents a unit of collective application behavior performed by (a collaboration of) two or more application components."
177
215
  CLASSIFICATION = :behavioral
178
216
  LAYER = Layers::Application
179
217
 
@@ -183,6 +221,8 @@ module Archimate
183
221
  end
184
222
 
185
223
  class ApplicationInterface < Element
224
+ NAME = "Application Interface"
225
+ DESCRIPTION = "An application interface represents a point of access where application services are made available to a user, another application component, or a node."
186
226
  CLASSIFICATION = :active_structure
187
227
  LAYER = Layers::Application
188
228
 
@@ -192,6 +232,8 @@ module Archimate
192
232
  end
193
233
 
194
234
  class ApplicationProcess < Element
235
+ NAME = "Application Process"
236
+ DESCRIPTION = "An application process represents a sequence of application behaviors that achieves a specific outcome."
195
237
  CLASSIFICATION = :behavioral
196
238
  LAYER = Layers::Application
197
239
 
@@ -201,6 +243,8 @@ module Archimate
201
243
  end
202
244
 
203
245
  class ApplicationService < Element
246
+ NAME = "Application Service"
247
+ DESCRIPTION = "An application service represents an explicitly defined exposed application behavior."
204
248
  CLASSIFICATION = :behavioral
205
249
  LAYER = Layers::Application
206
250
 
@@ -210,6 +254,8 @@ module Archimate
210
254
  end
211
255
 
212
256
  class DataObject < Element
257
+ NAME = "Data Object"
258
+ DESCRIPTION = "A data object represents data structured for automated processing."
213
259
  CLASSIFICATION = :passive_structure
214
260
  LAYER = Layers::Application
215
261
 
@@ -223,6 +269,8 @@ module Archimate
223
269
  #############################################################
224
270
 
225
271
  class Artifact < Element
272
+ NAME = "Artifact"
273
+ DESCRIPTION = "An artifact represents a piece of data that is used or produced in a software development process, or by deployment and operation of an IT system."
226
274
  CLASSIFICATION = :passive_structure
227
275
  LAYER = Layers::Technology
228
276
 
@@ -232,6 +280,8 @@ module Archimate
232
280
  end
233
281
 
234
282
  class CommunicationNetwork < Element
283
+ NAME = "Communication Network"
284
+ DESCRIPTION = "A communication network represents a set of structures that connects computer systems or other electronic devices for transmission, routing, and reception of data or data-based communications such as voice and video."
235
285
  CLASSIFICATION = :active_structure
236
286
  LAYER = Layers::Technology
237
287
 
@@ -241,6 +291,8 @@ module Archimate
241
291
  end
242
292
 
243
293
  class CommunicationPath < Element
294
+ NAME = "Communication Path"
295
+ DESCRIPTION = "A path represents a link between two or more nodes, through which these nodes can exchange data or material."
244
296
  CLASSIFICATION = :active_structure
245
297
  LAYER = Layers::Technology
246
298
 
@@ -250,6 +302,8 @@ module Archimate
250
302
  end
251
303
 
252
304
  class Device < Element
305
+ NAME = "Device"
306
+ DESCRIPTION = "A device is a physical IT resource upon which system software and artifacts may be stored or deployed for execution."
253
307
  CLASSIFICATION = :active_structure
254
308
  LAYER = Layers::Technology
255
309
 
@@ -259,6 +313,8 @@ module Archimate
259
313
  end
260
314
 
261
315
  class InfrastructureFunction < Element
316
+ NAME = "Infrastructure Function"
317
+ DESCRIPTION = "A technology function represents a collection of technology behavior that can be performed by a node."
262
318
  CLASSIFICATION = :active_structure
263
319
  LAYER = Layers::Technology
264
320
 
@@ -268,6 +324,8 @@ module Archimate
268
324
  end
269
325
 
270
326
  class InfrastructureInterface < Element
327
+ NAME = "Infrastructure Interface"
328
+ DESCRIPTION = "A technology interface represents a point of access where technology services offered by a node can be accessed."
271
329
  CLASSIFICATION = :active_structure
272
330
  LAYER = Layers::Technology
273
331
 
@@ -277,6 +335,8 @@ module Archimate
277
335
  end
278
336
 
279
337
  class InfrastructureService < Element
338
+ NAME = "Infrastructure Service"
339
+ DESCRIPTION = "A technology service represents an explicitly defined exposed technology behavior."
280
340
  CLASSIFICATION = :active_structure
281
341
  LAYER = Layers::Technology
282
342
 
@@ -286,6 +346,8 @@ module Archimate
286
346
  end
287
347
 
288
348
  class Network < Element
349
+ NAME = "Network"
350
+ DESCRIPTION = "A communication network represents a set of structures that connects computer systems or other electronic devices for transmission, routing, and reception of data or data-based communications such as voice and video."
289
351
  CLASSIFICATION = :active_structure
290
352
  LAYER = Layers::Technology
291
353
 
@@ -295,6 +357,8 @@ module Archimate
295
357
  end
296
358
 
297
359
  class Node < Element
360
+ NAME = "Node"
361
+ DESCRIPTION = "A node represents a computational or physical resource that hosts, manipulates, or interacts with other computational or physical resources."
298
362
  CLASSIFICATION = :active_structure
299
363
  LAYER = Layers::Technology
300
364
 
@@ -304,6 +368,8 @@ module Archimate
304
368
  end
305
369
 
306
370
  class Path < Element
371
+ NAME = "Path"
372
+ DESCRIPTION = "A path represents a link between two or more nodes, through which these nodes can exchange data or material."
307
373
  CLASSIFICATION = :active_structure
308
374
  LAYER = Layers::Technology
309
375
 
@@ -313,6 +379,8 @@ module Archimate
313
379
  end
314
380
 
315
381
  class SystemSoftware < Element
382
+ NAME = "System Software"
383
+ DESCRIPTION = "System software represents software that provides or contributes to an environment for storing, executing, and using software or data deployed within it."
316
384
  CLASSIFICATION = :active_structure
317
385
  LAYER = Layers::Technology
318
386
 
@@ -322,6 +390,8 @@ module Archimate
322
390
  end
323
391
 
324
392
  class TechnologyCollaboration < Element
393
+ NAME = "Technology Collaboration"
394
+ DESCRIPTION = "A technology collaboration represents an aggregate of two or more nodes that work together to perform collective technology behavior."
325
395
  CLASSIFICATION = :active_structure
326
396
  LAYER = Layers::Technology
327
397
 
@@ -331,6 +401,8 @@ module Archimate
331
401
  end
332
402
 
333
403
  class TechnologyEvent < Element
404
+ NAME = "Technology Event"
405
+ DESCRIPTION = "A technology event is a technology behavior element that denotes a state change."
334
406
  CLASSIFICATION = :behavioral
335
407
  LAYER = Layers::Technology
336
408
 
@@ -340,6 +412,8 @@ module Archimate
340
412
  end
341
413
 
342
414
  class TechnologyFunction < Element
415
+ NAME = "Technology Function"
416
+ DESCRIPTION = "A technology function represents a collection of technology behavior that can be performed by a node."
343
417
  CLASSIFICATION = :behavioral
344
418
  LAYER = Layers::Technology
345
419
 
@@ -349,6 +423,8 @@ module Archimate
349
423
  end
350
424
 
351
425
  class TechnologyInteraction < Element
426
+ NAME = "Technology Interaction"
427
+ DESCRIPTION = "A technology interaction represents a unit of collective technology behavior performed by (a collaboration of) two or more nodes."
352
428
  CLASSIFICATION = :behavioral
353
429
  LAYER = Layers::Technology
354
430
 
@@ -358,6 +434,8 @@ module Archimate
358
434
  end
359
435
 
360
436
  class TechnologyInterface < Element
437
+ NAME = "Technology Interface"
438
+ DESCRIPTION = "A technology interface represents a point of access where technology services offered by a node can be accessed."
361
439
  CLASSIFICATION = :active_structure
362
440
  LAYER = Layers::Technology
363
441
 
@@ -367,6 +445,8 @@ module Archimate
367
445
  end
368
446
 
369
447
  class TechnologyObject < Element
448
+ NAME = "Technology Object"
449
+ DESCRIPTION = "A technology object represents a passive element that is used or produced by technology behavior."
370
450
  CLASSIFICATION = :passive_structure
371
451
  LAYER = Layers::Technology
372
452
 
@@ -376,6 +456,8 @@ module Archimate
376
456
  end
377
457
 
378
458
  class TechnologyProcess < Element
459
+ NAME = "Technology Process"
460
+ DESCRIPTION = "A technology process represents a sequence of technology behaviors that achieves a specific outcome."
379
461
  CLASSIFICATION = :behavioral
380
462
  LAYER = Layers::Technology
381
463
 
@@ -385,6 +467,8 @@ module Archimate
385
467
  end
386
468
 
387
469
  class TechnologyService < Element
470
+ NAME = "Technology Service"
471
+ DESCRIPTION = "A technology service represents an explicitly defined exposed technology behavior."
388
472
  CLASSIFICATION = :behavioral
389
473
  LAYER = Layers::Technology
390
474
 
@@ -398,6 +482,8 @@ module Archimate
398
482
  #############################################################
399
483
 
400
484
  class DistributionNetwork < Element
485
+ NAME = "Distribution Network"
486
+ DESCRIPTION = "A distribution network represents a physical network used to transport materials or energy."
401
487
  CLASSIFICATION = :active_structure
402
488
  LAYER = Layers::Physical
403
489
 
@@ -407,6 +493,8 @@ module Archimate
407
493
  end
408
494
 
409
495
  class Equipment < Element
496
+ NAME = "Equipment"
497
+ DESCRIPTION = "Equipment represents one or more physical machines, tools, or instruments that can create, use, store, move, or transform materials."
410
498
  CLASSIFICATION = :active_structure
411
499
  LAYER = Layers::Physical
412
500
 
@@ -416,6 +504,8 @@ module Archimate
416
504
  end
417
505
 
418
506
  class Facility < Element
507
+ NAME = "Facility"
508
+ DESCRIPTION = "A facility represents a physical structure or environment."
419
509
  CLASSIFICATION = :active_structure
420
510
  LAYER = Layers::Physical
421
511
 
@@ -425,6 +515,8 @@ module Archimate
425
515
  end
426
516
 
427
517
  class Material < Element
518
+ NAME = "Material"
519
+ DESCRIPTION = "Material represents tangible physical matter or physical elements."
428
520
  CLASSIFICATION = :passive_structure
429
521
  LAYER = Layers::Physical
430
522
 
@@ -438,6 +530,8 @@ module Archimate
438
530
  #############################################################
439
531
 
440
532
  class Assessment < Element
533
+ NAME = "Assessment"
534
+ DESCRIPTION = "An assessment represents the result of an analysis of the state of affairs of the enterprise with respect to some driver."
441
535
  CLASSIFICATION = :active_structure
442
536
  LAYER = Layers::Motivation
443
537
 
@@ -447,6 +541,8 @@ module Archimate
447
541
  end
448
542
 
449
543
  class Constraint < Element
544
+ NAME = "Constraint"
545
+ DESCRIPTION = "A constraint represents a factor that prevents or obstructs the realization of goals."
450
546
  CLASSIFICATION = :active_structure
451
547
  LAYER = Layers::Motivation
452
548
 
@@ -456,6 +552,8 @@ module Archimate
456
552
  end
457
553
 
458
554
  class Driver < Element
555
+ NAME = "Driver"
556
+ DESCRIPTION = "A driver represents an external or internal condition that motivates an organization to define its goals and implement the changes necessary to achieve them."
459
557
  CLASSIFICATION = :active_structure
460
558
  LAYER = Layers::Motivation
461
559
 
@@ -465,6 +563,8 @@ module Archimate
465
563
  end
466
564
 
467
565
  class Goal < Element
566
+ NAME = "Goal"
567
+ DESCRIPTION = "A goal represents a high-level statement of intent, direction, or desired end state for an organization and its stakeholders."
468
568
  CLASSIFICATION = :active_structure
469
569
  LAYER = Layers::Motivation
470
570
 
@@ -474,6 +574,8 @@ module Archimate
474
574
  end
475
575
 
476
576
  class Meaning < Element
577
+ NAME = "Meaning"
578
+ DESCRIPTION = "Meaning represents the knowledge or expertise present in, or the interpretation given to, a core element in a particular context."
477
579
  CLASSIFICATION = :passive_structure
478
580
  LAYER = Layers::Motivation
479
581
 
@@ -483,6 +585,8 @@ module Archimate
483
585
  end
484
586
 
485
587
  class Outcome < Element
588
+ NAME = "Outcome"
589
+ DESCRIPTION = "An outcome represents an end result that has been achieved."
486
590
  CLASSIFICATION = :active_structure
487
591
  LAYER = Layers::Motivation
488
592
 
@@ -492,6 +596,8 @@ module Archimate
492
596
  end
493
597
 
494
598
  class Principle < Element
599
+ NAME = "Principle"
600
+ DESCRIPTION = "A principle represents a qualitative statement of intent that should be met by the architecture."
495
601
  CLASSIFICATION = :active_structure
496
602
  LAYER = Layers::Motivation
497
603
 
@@ -501,6 +607,8 @@ module Archimate
501
607
  end
502
608
 
503
609
  class Requirement < Element
610
+ NAME = "Requirement"
611
+ DESCRIPTION = "A requirement represents a statement of need that must be met by the architecture."
504
612
  CLASSIFICATION = :active_structure
505
613
  LAYER = Layers::Motivation
506
614
 
@@ -510,6 +618,8 @@ module Archimate
510
618
  end
511
619
 
512
620
  class Stakeholder < Element
621
+ NAME = "Stakeholder"
622
+ DESCRIPTION = "A stakeholder is the role of an individual, team, or organization (or classes thereof) that represents their interests in the outcome of the architecture."
513
623
  CLASSIFICATION = :active_structure
514
624
  LAYER = Layers::Motivation
515
625
 
@@ -519,6 +629,8 @@ module Archimate
519
629
  end
520
630
 
521
631
  class Value < Element
632
+ NAME = "Value"
633
+ DESCRIPTION = "Value represents the relative worth, utility, or importance of a core element or an outcome."
522
634
  CLASSIFICATION = :passive_structure
523
635
  LAYER = Layers::Motivation
524
636
 
@@ -532,6 +644,8 @@ module Archimate
532
644
  #############################################################
533
645
 
534
646
  class Deliverable < Element
647
+ NAME = "Deliverable"
648
+ DESCRIPTION = "A deliverable represents a precisely-defined outcome of a work package."
535
649
  CLASSIFICATION = :passive_structure
536
650
  LAYER = Layers::Implementation_and_migration
537
651
 
@@ -541,6 +655,8 @@ module Archimate
541
655
  end
542
656
 
543
657
  class Gap < Element
658
+ NAME = "Gap"
659
+ DESCRIPTION = "A gap represents a statement of difference between two plateaus."
544
660
  CLASSIFICATION = :passive_structure
545
661
  LAYER = Layers::Implementation_and_migration
546
662
 
@@ -550,6 +666,8 @@ module Archimate
550
666
  end
551
667
 
552
668
  class ImplementationEvent < Element
669
+ NAME = "Implementation Event"
670
+ DESCRIPTION = "An implementation event is a behavior element that denotes a state change related to implementation or migration."
553
671
  CLASSIFICATION = :active_structure
554
672
  LAYER = Layers::Implementation_and_migration
555
673
 
@@ -559,6 +677,8 @@ module Archimate
559
677
  end
560
678
 
561
679
  class Plateau < Element
680
+ NAME = "Plateau"
681
+ DESCRIPTION = "A plateau represents a relatively stable state of the architecture that exists during a limited period of time."
562
682
  CLASSIFICATION = :active_structure
563
683
  LAYER = Layers::Implementation_and_migration
564
684
 
@@ -568,6 +688,8 @@ module Archimate
568
688
  end
569
689
 
570
690
  class WorkPackage < Element
691
+ NAME = "Work Package"
692
+ DESCRIPTION = "A work package represents a series of actions identified and designed to achieve specific results within specified time and resource constraints."
571
693
  CLASSIFICATION = :behavioral
572
694
  LAYER = Layers::Implementation_and_migration
573
695
 
@@ -581,6 +703,8 @@ module Archimate
581
703
  #############################################################
582
704
 
583
705
  class AndJunction < Element
706
+ NAME = "And Junction"
707
+ DESCRIPTION = "A junction is used to connect relationships of the same type."
584
708
  CLASSIFICATION = :active_structure
585
709
  LAYER = Layers::Connectors
586
710
 
@@ -590,6 +714,8 @@ module Archimate
590
714
  end
591
715
 
592
716
  class Junction < Element
717
+ NAME = "Junction"
718
+ DESCRIPTION = "A junction is used to connect relationships of the same type."
593
719
  CLASSIFICATION = :active_structure
594
720
  LAYER = Layers::Connectors
595
721
 
@@ -599,6 +725,8 @@ module Archimate
599
725
  end
600
726
 
601
727
  class OrJunction < Element
728
+ NAME = "Or Junction"
729
+ DESCRIPTION = "A junction is used to connect relationships of the same type."
602
730
  CLASSIFICATION = :active_structure
603
731
  LAYER = Layers::Connectors
604
732
 
@@ -612,6 +740,8 @@ module Archimate
612
740
  #############################################################
613
741
 
614
742
  class Capability < Element
743
+ NAME = "Capability"
744
+ DESCRIPTION = "A capability represents an ability that an active structure element, such as an organization, person, or system, possesses."
615
745
  CLASSIFICATION = :active_structure
616
746
  LAYER = Layers::Strategy
617
747
 
@@ -621,6 +751,8 @@ module Archimate
621
751
  end
622
752
 
623
753
  class CourseOfAction < Element
754
+ NAME = "Course Of Action"
755
+ DESCRIPTION = "A course of action is an approach or plan for configuring some capabilities and resources of the enterprise, undertaken to achieve a goal."
624
756
  CLASSIFICATION = :active_structure
625
757
  LAYER = Layers::Strategy
626
758
 
@@ -630,6 +762,8 @@ module Archimate
630
762
  end
631
763
 
632
764
  class Resource < Element
765
+ NAME = "Resource"
766
+ DESCRIPTION = "A resource represents an asset owned or controlled by an individual or organization."
633
767
  CLASSIFICATION = :active_structure
634
768
  LAYER = Layers::Strategy
635
769
 
@@ -643,6 +777,8 @@ module Archimate
643
777
  #############################################################
644
778
 
645
779
  class Grouping < Element
780
+ NAME = "Grouping"
781
+ DESCRIPTION = "The grouping element aggregates or composes concepts that belong together based on some common characteristic."
646
782
  CLASSIFICATION = :other
647
783
  LAYER = Layers::Other
648
784
 
@@ -177,6 +177,10 @@ module Archimate
177
177
  end
178
178
  end
179
179
 
180
+ def find_by_class(klass)
181
+ @index_hash.values.select { |item| item.is_a?(klass) }
182
+ end
183
+
180
184
  private
181
185
 
182
186
  # Only used by [#find_default_organization]
@@ -239,10 +243,6 @@ module Archimate
239
243
  end
240
244
  end
241
245
 
242
- def find_by_class(klass)
243
- @index_hash.values.select { |item| item.is_a?(klass) }
244
- end
245
-
246
246
  def find_default_organization(type, name)
247
247
  result = organizations.find { |f| f.type == type }
248
248
  return result unless result.nil?
@@ -21,6 +21,8 @@ module Archimate
21
21
  # relationship.
22
22
  module Relationships
23
23
  class Composition < Relationship
24
+ NAME = "Composition"
25
+ DESCRIPTION = "The composition relationship indicates that an element consists of one or more other concepts."
24
26
  WEIGHT = 10
25
27
  CLASSIFICATION = :structural
26
28
  VERB = "composes"
@@ -32,6 +34,8 @@ module Archimate
32
34
  end
33
35
 
34
36
  class Aggregation < Relationship
37
+ NAME = "Aggregation"
38
+ DESCRIPTION = "The aggregation relationship indicates that an element groups a number of other concepts. "
35
39
  WEIGHT = 9
36
40
  CLASSIFICATION = :structural
37
41
  VERB = "aggregates"
@@ -43,6 +47,8 @@ module Archimate
43
47
  end
44
48
 
45
49
  class Assignment < Relationship
50
+ NAME = "Assignment"
51
+ DESCRIPTION = "The assignment relationship expresses the allocation of responsibility, performance of behavior, or execution."
46
52
  WEIGHT = 8
47
53
  CLASSIFICATION = :structural
48
54
  VERB = "assigned to"
@@ -54,6 +60,8 @@ module Archimate
54
60
  end
55
61
 
56
62
  class Realization < Relationship
63
+ NAME = "Realization"
64
+ DESCRIPTION = "The realization relationship indicates that an entity plays a critical role in the creation, achievement, sustenance, or operation of a more abstract entity."
57
65
  WEIGHT = 7
58
66
  CLASSIFICATION = :structural
59
67
  VERB = "realizes"
@@ -65,6 +73,8 @@ module Archimate
65
73
  end
66
74
 
67
75
  class Serving < Relationship
76
+ NAME = "Serving"
77
+ DESCRIPTION = "The serving relationship models that an element provides its functionality to another element. I.e. the element pointed to calls the other element."
68
78
  WEIGHT = 6
69
79
  CLASSIFICATION = :dependency
70
80
  VERB = "serves"
@@ -76,6 +86,8 @@ module Archimate
76
86
  end
77
87
 
78
88
  class Access < Relationship
89
+ NAME = "Access"
90
+ DESCRIPTION = "The access relationship models the ability of behavior and active structure elements to observe or act upon passive structure elements."
79
91
  WEIGHT = 5
80
92
  CLASSIFICATION = :dependency
81
93
  VERB = "accesses"
@@ -87,6 +99,8 @@ module Archimate
87
99
  end
88
100
 
89
101
  class Influence < Relationship
102
+ NAME = "Influence"
103
+ DESCRIPTION = "The influence relationship models that an element affects the implementation or achievement of some motivation element."
90
104
  WEIGHT = 4
91
105
  CLASSIFICATION = :dependency
92
106
  VERB = "influences"
@@ -98,6 +112,8 @@ module Archimate
98
112
  end
99
113
 
100
114
  class Triggering < Relationship
115
+ NAME = "Triggering"
116
+ DESCRIPTION = "The triggering relationship describes a temporal or causal relationship between elements."
101
117
  WEIGHT = 3
102
118
  CLASSIFICATION = :dynamic
103
119
  VERB = "triggers"
@@ -109,6 +125,8 @@ module Archimate
109
125
  end
110
126
 
111
127
  class Flow < Relationship
128
+ NAME = "Flow"
129
+ DESCRIPTION = "The flow relationship represents transfer from one element to another."
112
130
  WEIGHT = 2
113
131
  CLASSIFICATION = :dynamic
114
132
  VERB = "flows to"
@@ -120,6 +138,8 @@ module Archimate
120
138
  end
121
139
 
122
140
  class Specialization < Relationship
141
+ NAME = "Specialization"
142
+ DESCRIPTION = "The specialization relationship indicates that an element is a particular kind of another element."
123
143
  WEIGHT = 1
124
144
  CLASSIFICATION = :other
125
145
  VERB = "specializes"
@@ -131,6 +151,8 @@ module Archimate
131
151
  end
132
152
 
133
153
  class Association < Relationship
154
+ NAME = "Association"
155
+ DESCRIPTION = "An association relationship models an unspecified relationship, or one that is not represented by another ArchiMate relationship."
134
156
  WEIGHT = 0
135
157
  CLASSIFICATION = :other
136
158
  VERB = "associated with"
@@ -144,6 +166,8 @@ module Archimate
144
166
  # Junction is a relationship connector
145
167
  # * All relationships connected with relationship connectors must be of the same type
146
168
  class Junction < Relationship
169
+ NAME = "Junction"
170
+ DESCRIPTION = "A junction is used to connect relationships of the same type."
147
171
  WEIGHT = 0
148
172
  CLASSIFICATION = :other
149
173
  VERB = "junction to"
@@ -157,6 +181,8 @@ module Archimate
157
181
  # Junction is a relationship connector
158
182
  # * All relationships connected with relationship connectors must be of the same type
159
183
  class AndJunction < Relationship
184
+ NAME = "AndJunction"
185
+ DESCRIPTION = "A junction is used to connect relationships of the same type."
160
186
  WEIGHT = 0
161
187
  CLASSIFICATION = :other
162
188
  VERB = "and junction to"
@@ -170,6 +196,8 @@ module Archimate
170
196
  # Junction is a relationship connector
171
197
  # * All relationships connected with relationship connectors must be of the same type
172
198
  class OrJunction < Relationship
199
+ NAME = "OrJunction"
200
+ DESCRIPTION = "A junction is used to connect relationships of the same type."
173
201
  WEIGHT = 0
174
202
  CLASSIFICATION = :other
175
203
  VERB = "or junction to"
@@ -46,7 +46,7 @@ module Archimate
46
46
  module Export
47
47
  Quad = Struct.new(:subject, :predicate, :object) do
48
48
  def fmt_obj
49
- if object =~ /\s/
49
+ if /\s/ === object
50
50
  "\"#{object.gsub('"', '\\"').gsub(/[\n\r]/, '\\n')}\""
51
51
  else
52
52
  "<#{object}>"
@@ -29,6 +29,16 @@ path {
29
29
  z-index: 1000;
30
30
  }
31
31
 
32
+ .archimate-legend-title {
33
+ font-weight: bold;
34
+ }
35
+
36
+ .archimate-legend {
37
+ fill: #eee;
38
+ stroke: #bbb;
39
+ stroke-width: 2px;
40
+ }
41
+
32
42
  table.properties {
33
43
  background-color: whitesmoke;
34
44
  border: 2px solid gray;
@@ -138,6 +148,11 @@ table.properties>caption {
138
148
  stroke: #9cb29c;
139
149
  }
140
150
 
151
+ .archimate-connectors-background, .archimate-other-background {
152
+ fill: #eee;
153
+ stroke: #bbb;
154
+ }
155
+
141
156
  .archimate-note-background {
142
157
  fill: #fff;
143
158
  stroke: #b2b2b2;
@@ -7,57 +7,95 @@ module Archimate
7
7
  module Svg
8
8
  class Diagram
9
9
  attr_reader :diagram
10
+ attr_reader :svg_doc
11
+ attr_reader :options
10
12
 
11
- def initialize(diagram)
13
+ DEFAULT_SVG_OPTIONS = {
14
+ legend: false,
15
+ format_xml: true
16
+ }.freeze
17
+
18
+ def initialize(diagram, options = {})
12
19
  @diagram = diagram
20
+ @options = DEFAULT_SVG_OPTIONS.merge(options)
13
21
  @svg_template = Nokogiri::XML(SvgTemplate.new.to_s).freeze
14
22
  end
15
23
 
16
24
  def to_svg
17
- svg_doc = @svg_template.clone
18
- set_title(svg_doc)
19
- top_group = svg_doc.at_css("#archimate-diagram")
25
+ @svg_doc = @svg_template.clone
26
+ set_title
20
27
  render_connections(
21
- render_elements(top_group)
28
+ render_elements(archimate_diagram_group)
22
29
  )
23
- update_viewbox(svg_doc.at_css("svg"))
24
- format_node(top_group)
25
- svg_doc.to_xml(encoding: 'UTF-8', indent: 2)
30
+ legend = Legend.new(self)
31
+ if include_legend?
32
+ legend.insert
33
+ else
34
+ legend.remove
35
+ end
36
+ update_viewbox
37
+ format_node(archimate_diagram_group) if format_xml?
38
+ format_node(legend_group) if include_legend? && format_xml?
39
+ svg_doc.to_xml(encoding: 'UTF-8', indent: indentation)
40
+ end
41
+
42
+ def svg_element
43
+ @svg_element ||= svg_doc.at_css("svg")
44
+ end
45
+
46
+ def archimate_diagram_group
47
+ @archimate_diagram_group ||= svg_doc.at_css("#archimate-diagram")
48
+ end
49
+
50
+ def legend_group
51
+ @legend_group ||= svg_doc.at_css("#archimate-legend")
26
52
  end
27
53
 
28
- def set_title(svg)
29
- svg.at_css("title").content = diagram.name || "untitled"
30
- svg.at_css("desc").content = diagram.documentation.to_s || ""
54
+ def include_legend?
55
+ options[:legend]
56
+ end
57
+
58
+ def format_xml?
59
+ options[:format_xml]
60
+ end
61
+
62
+ def indentation
63
+ format_xml? ? 2 : 0
64
+ end
65
+
66
+ def set_title
67
+ svg_doc.at_css("title").content = diagram.name || "untitled"
68
+ svg_doc.at_css("desc").content = diagram.documentation.to_s || ""
31
69
  end
32
70
 
33
71
  # Scan the SVG and figure out min & max
34
- def update_viewbox(svg)
35
- extents = calculate_max_extents(svg).expand(10)
36
- svg.set_attribute(:width, extents.width)
37
- svg.set_attribute(:height, extents.height)
38
- svg.set_attribute("viewBox", "#{extents.min_x} #{extents.min_y} #{extents.width} #{extents.height}")
39
- svg
72
+ def update_viewbox
73
+ extents = calculate_max_extents.expand(10)
74
+ svg_element.set_attribute(:width, extents.width)
75
+ svg_element.set_attribute(:height, extents.height)
76
+ svg_element.set_attribute("viewBox", "#{extents.min_x} #{extents.min_y} #{extents.width} #{extents.height}")
77
+ svg_element
40
78
  end
41
79
 
42
80
  def format_node(node, depth = 4)
43
81
  node.children.each do |child|
44
- child.add_previous_sibling("\n#{ ' ' * depth }")
82
+ child.add_previous_sibling("\n#{' ' * depth}")
45
83
  format_node(child, depth + 2)
46
- child.add_next_sibling("\n#{ ' ' * (depth - 2) }") if node.children.last == child
84
+ child.add_next_sibling("\n#{' ' * (depth - 2)}") if node.children.last == child
47
85
  end
48
86
  end
49
87
 
50
- def calculate_max_extents(doc)
88
+ def calculate_max_extents
51
89
  node_vals =
52
- doc
90
+ svg_element
53
91
  .xpath("//*[@x or @y]")
54
92
  .map { |node| %w[x y width height].map { |attr| node.attr(attr).to_i } }
55
- doc.css(".archimate-relationship")
56
- .each { |path|
57
- path.attr("d").split(" ").each_slice(3) do |point|
58
- node_vals << [point[1].to_i, point[2].to_i, 0, 0]
59
- end
60
- }
93
+ svg_element.css(".archimate-relationship")
94
+ .each do |path|
95
+ path.attr("d").split(" ").each_slice(3) do |point|
96
+ node_vals << [point[1].to_i, point[2].to_i, 0, 0]
97
+ end
98
+ end
61
99
  Extents.new(
62
100
  node_vals.map(&:first).min,
63
101
  node_vals.map { |v| v[0] + v[2] }.max,
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module Archimate
6
+ module Svg
7
+ class Legend
8
+ attr_reader :svg_diagram
9
+ attr_reader :legend_group
10
+ attr_reader :columns
11
+ attr_reader :element_width
12
+ attr_reader :element_height
13
+ attr_reader :line_height
14
+ attr_reader :text_indent
15
+ attr_reader :description_width
16
+ attr_reader :col_width
17
+ attr_reader :row_height
18
+ attr_reader :top_margin
19
+ attr_reader :section_width
20
+ attr_reader :legend_width
21
+ attr_reader :layers
22
+ attr_reader :element_classes
23
+ attr_reader :relationship_classes
24
+
25
+ def initialize(svg_diagram)
26
+ @svg_diagram = svg_diagram
27
+ @legend_group = svg_diagram.legend_group
28
+ @top_margin = 25
29
+ @columns = 2
30
+ @element_width = 110
31
+ @element_height = 50
32
+ @line_height = 15
33
+ @text_indent = 10
34
+ @description_width = 500
35
+ @col_width = element_width + text_indent + description_width + text_indent
36
+ @row_height = element_height + text_indent
37
+ @section_width = columns * col_width
38
+ @legend_width = text_indent * 2 + columns * col_width
39
+ diagram = svg_diagram.diagram
40
+ @element_classes = diagram.elements.map(&:class).uniq
41
+ @layers = diagram.elements.map(&:layer).uniq.sort
42
+ @relationship_classes = diagram.relationships.map(&:class).uniq
43
+ end
44
+
45
+ def remove
46
+ legend_group.remove
47
+ end
48
+
49
+ def insert
50
+ Nokogiri::XML::Builder.with(legend_group) do |xml|
51
+ legend_for_relationship_classes(xml,
52
+ legend_for_element_types_by_layer(xml,
53
+ top_level_legend(xml)))
54
+ end
55
+ end
56
+
57
+ def top_level_legend(xml)
58
+ text(legend_left, legend_top, legend_width, legend_height, "Legend", "archimate-legend", xml) + line_height
59
+ end
60
+
61
+ def legend_for_element_types_by_layer(xml, top)
62
+ layers.inject(top) do |section_top, layer|
63
+ section_legend(section_top, layer.name, layer.background_class, layer_elements(layer), xml)
64
+ end
65
+ end
66
+
67
+ def legend_for_relationship_classes(xml, top)
68
+ return top if relationship_classes.empty?
69
+
70
+ section_legend(top, "Relationships", "archimate-other-background", relationship_classes, xml)
71
+ end
72
+
73
+ def section_legend(top, heading, css_class, items, xml)
74
+ sec_height = section_height(items)
75
+ top = text(legend_left + text_indent, top, section_width, sec_height, heading, css_class, xml)
76
+ items.each_with_index do |item, idx|
77
+ item_example(item_x(idx), item_y(top, idx), item, xml)
78
+ end
79
+ top + sec_height
80
+ end
81
+
82
+ # Legend entry for a particular element type
83
+ def item_example(x, y, klass, xml)
84
+ klass_name = klass.name.split("::").last
85
+ if klass.superclass == DataModel::Element
86
+ element_example(x, y, klass, klass_name, xml)
87
+ elsif klass.superclass == DataModel::Relationship
88
+ relationship_example(x, y, klass_name, xml)
89
+ end
90
+ element_type_description(klass::DESCRIPTION, text_bounds(x, y), xml)
91
+ end
92
+
93
+ def element_example(x, y, klass, klass_name, xml)
94
+ case klass_name
95
+ when "Junction"
96
+ r = (element_height - 10) / 4
97
+
98
+ xml.circle(cx: x + r, cy: y + r, r: r, style: "fill:#000;stroke:#000")
99
+ xml.text_(x: x + r * 2 + text_indent, y: y + r + line_height / 2, class: "archimate-legend-title") do
100
+ xml.text("And Junction")
101
+ end
102
+ xml.circle(cx: x + r, cy: y + row_height / 2 + r, r: r, style: "fill:#fff;stroke:#000")
103
+ xml.text_(x: x + r * 2 + text_indent, y: y + row_height / 2 + r + line_height / 2, class: "archimate-legend-title") do
104
+ xml.text("Or Junction")
105
+ end
106
+ else
107
+ element = DataModel::Elements.const_get(klass_name).new(id: "legend-element-#{klass_name}", name: klass::NAME)
108
+ view_node = DataModel::ViewNode.new(
109
+ id: "legend-element-type-#{klass_name}",
110
+ name: klass::NAME,
111
+ type: klass_name,
112
+ element: element,
113
+ diagram: svg_diagram.diagram,
114
+ bounds: DataModel::Bounds.new(x: x, y: y, width: element_width, height: element_height)
115
+ )
116
+ EntityFactory.make_entity(view_node, nil).to_svg(xml)
117
+ end
118
+ end
119
+
120
+ def relationship_example(x, y, klass_name, xml)
121
+ css_class = "archimate-#{klass_name.downcase} archimate-relationship"
122
+ xml.path(d: "M#{x} #{y + row_height / 2} h #{element_width}", class: css_class)
123
+ end
124
+
125
+ # Paragraph that describes a element or relationship
126
+ def element_type_description(text, text_bounds, xml)
127
+ css_style = "height:#{text_bounds.height}px;width:#{text_bounds.width}px;"
128
+ xml.foreignObject(text_bounds.to_h) do
129
+ xml.table(xmlns: "http://www.w3.org/1999/xhtml", style: css_style) do
130
+ xml.tr(style: "height:#{text_bounds.height}px;") do
131
+ xml.td(class: "entity-description") do
132
+ xml.p(class: "entity-description") do
133
+ text.tr("\r\n", "\n").split(/[\r\n]/).each do |line|
134
+ xml.text(line)
135
+ xml.br
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ def text(x, y, width, height, str, css_class, xml)
145
+ css_style = "fill-opacity: 0.4"
146
+ xml.rect(x: x, y: y - line_height, width: width, height: height,
147
+ rx: 5, ry: 5, class: css_class, style: css_style)
148
+ xml.text_(x: x + text_indent, y: y, class: "archimate-legend-title") do
149
+ xml.text(str)
150
+ end
151
+ y + line_height
152
+ end
153
+
154
+ def extents
155
+ @extents ||= svg_diagram.calculate_max_extents
156
+ end
157
+
158
+ def diagram_width
159
+ @diagram_width ||= extents.width
160
+ end
161
+
162
+ def legend_top
163
+ extents.max_y + top_margin
164
+ end
165
+
166
+ def legend_left
167
+ extents.min_x
168
+ end
169
+
170
+ def layer_elements(layer)
171
+ element_classes.select { |k| k::LAYER == layer }
172
+ end
173
+
174
+ def legend_height
175
+ height = layers.inject(line_height) do |h, layer|
176
+ h + rows(layer_elements(layer)) * row_height + line_height * 3
177
+ end + line_height
178
+ height += rows(relationship_classes) * row_height + line_height * 3 unless relationship_classes.empty?
179
+ height
180
+ end
181
+
182
+ def rows(items)
183
+ (items.size / columns.to_f).round
184
+ end
185
+
186
+ def section_height(items)
187
+ rows(items) * row_height + line_height * 2
188
+ end
189
+
190
+ def item_x(idx)
191
+ legend_left + (text_indent * 2) + (col_width * (idx % columns))
192
+ end
193
+
194
+ def item_y(top, idx)
195
+ top + (row_height * (idx / columns))
196
+ end
197
+
198
+ def text_bounds(x, y)
199
+ DataModel::Bounds.new(
200
+ x: x + element_width + text_indent,
201
+ y: y,
202
+ width: description_width,
203
+ height: element_height
204
+ )
205
+ end
206
+ end
207
+ end
208
+ end
@@ -174,4 +174,5 @@
174
174
  </marker>
175
175
  </defs>
176
176
  <g id="archimate-diagram"></g>
177
+ <g id="archimate-legend"></g>
177
178
  </svg>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Archimate
4
- VERSION = "2.0.3"
4
+ VERSION = "2.1.0"
5
5
  end
data/lib/archimate.rb CHANGED
@@ -56,6 +56,7 @@ module Archimate
56
56
  autoload :Entity, 'archimate/svg/entity'
57
57
  autoload :EntityFactory, 'archimate/svg/entity_factory'
58
58
  autoload :Extents, 'archimate/svg/extents'
59
+ autoload :Legend, 'archimate/svg/legend'
59
60
  autoload :Path, 'archimate/svg/path'
60
61
  autoload :Point, 'archimate/svg/point'
61
62
  autoload :Segment, 'archimate/svg/segment'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: archimate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Morga
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-22 00:00:00.000000000 Z
11
+ date: 2019-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -655,6 +655,7 @@ files:
655
655
  - lib/archimate/svg/entity/work_package.rb
656
656
  - lib/archimate/svg/entity_factory.rb
657
657
  - lib/archimate/svg/extents.rb
658
+ - lib/archimate/svg/legend.rb
658
659
  - lib/archimate/svg/path.rb
659
660
  - lib/archimate/svg/point.rb
660
661
  - lib/archimate/svg/segment.rb
@@ -681,8 +682,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
681
682
  - !ruby/object:Gem::Version
682
683
  version: '0'
683
684
  requirements: []
684
- rubyforge_project:
685
- rubygems_version: 2.7.3
685
+ rubygems_version: 3.0.1
686
686
  signing_key:
687
687
  specification_version: 4
688
688
  summary: Archi Tools