Basic usage
This little program renders Goal Structuring Notation in a YAML format to a scalable vector graphics (SVG) image.
Usage
You can create an SVG like this:
gsn2x <yourgsnfile.yaml>
The output is an argument view in SVG format and automatically written to <yourgsnfile.svg>
. If more than one input file is provided, they are treated as modules.
Options
Usage: gsn2x [OPTIONS] <INPUT>...
Arguments:
<INPUT>... Sets the input file(s) to use.
Options:
-h, --help Print help
-V, --version Print version
CHECKS:
-c, --check Only check the input file(s), but do not output graphs.
-x, --exclude <EXCLUDED_MODULE> Exclude this module from reference checks.
OUTPUT:
-N, --no-arg Do not output of argument view for provided input files.
-f, --full <COMPLETE_VIEW> Output the complete view to file with name <COMPLETE_VIEW>. [default: complete.svg]
-F, --no-full Do not output the complete view.
-a, --arch <ARCHITECTURE_VIEW> Output the architecture view to file with name <ARCHITECTURE_VIEW>. [default: architecture.svg]
-A, --no-arch Do not output the architecture view.
-e, --evidence <EVIDENCE> Output list of all evidence to file with name <EVIDENCE>. [default: evidence.md]
-E, --no-evidence Do not output list of all evidence.
-o, --output-dir <OUTPUT_DIRECTORY> Emit all output files to directory <OUTPUT_DIRECTORY>. [default: .]
OUTPUT MODIFICATION:
-l, --layer <LAYERS> Output additional layer. Can be used multiple times.
-s, --stylesheet <STYLESHEETS> Links a stylesheet in SVG output. Can be used multiple times.
-t, --embed-css Embed stylesheets instead of linking them.
-m, --mask <MASKED_MODULE> Do not show this module in views.
-G, --no-legend Do not output a legend based on module information.
-g, --full-legend Output a legend based on all module information.
-w, --wrap <CHAR_WRAP> Define the number of characters after which a line of text is wrapped.
Syntax in YAML
Elements
The following Goal Structuring Notation (GSN) core elements are supported:
Element Type | Prefix |
---|---|
Goal | G |
Assumption | A |
Justification | J |
Solution | Sn |
Context | C |
Strategy | S |
Every element is defined by a prefix (as shown in the table above) and an arbitrary identifier then.
Examples
G1:
G-TopLevelGoal:
C_A_certain_context:
Attributes
The only mandatory attribute is text
that is the textual contents of the element.
An optional supportedBy
gives a list of the supporting arguments. Thus, Goal, Strategy and Solution can be listed here.
An optional inContextOf
links Justifications, Contexts or Assumptions.
Every element may have an optional url
attribute that creates a navigation link in the resulting SVG.
This should support finding information more easily.
Goals and Strategies can be undeveloped i.e., without supporting Goals, Strategies or Solutions.
These elements should marked with undeveloped: true
, otherwise validation will emit warnings.
Example
G1:
text: This is a Goal
supportedBy: [S1]
inContextOf: [C1]
S1:
text: This is a Strategy
C1:
text: This is a Context
Please see examples/example.gsn.yaml for an example of the used syntax.
Summary
Attribute | Optional | Notes |
---|---|---|
text | no | |
supportedBy | yes | |
inContextOf | yes | |
undeveloped | yes | Mutually exclusive to supportedBy . |
url | yes | |
classes | yes | See Stylesheets. |
nodeType | yes | See footnote1 |
rankIncrement | yes | See Layout. |
horizontalIndex | yes | See Layout. |
charWrap | yes | See Line Breaks. |
acp | yes | See Confidence Argument Extension. |
When providing a nodeType
you do not need to follow the standard prefix scheme above.
Just give Goal
, Assumption
, Justification
, Solution
, Context
and Strategy
to give the type of the element.
Checks
Validation checks
The tool automatically performs the following validation checks on the input YAML.
Validations can be performed on individual input files.
ID | Meaning |
---|---|
V01 | All IDs must either start with a known prefix or a node_type must explicitly set. |
V02 | All Goals and Strategies must be either marked with undeveloped: true or have supporting Goals, Strategies or Solutions. |
V03 | Goals and Strategies marked as undeveloped, must have no supporting arguments. |
V04 | All elements listed under supportedBy and inContextOf must be known elements types and semantically sensible (e.g. a Justification cannot be listed under supportedBy ). |
V05 | All referenced elements in supportedBy and inContextOf must be unique i.e., no duplicates in the list. |
V06 | All referenced elements in supportedBy and inContextOf must not refer to the element itself. |
V07 | All elements listed as extending other elements must be known elements of the current module and semantically sensible (see V04). |
V08 | The IDs start contradicts the type of the element set with node_type . |
V09 | Element has an assurance claim point that references another element, that this is neither its own ID nor any of the connected elements. |
The following checks apply to the complete set of input files.
ID | Meaning |
---|---|
C01 | There should be only one but must be at least one top-level element (G,S,C,J,A,Sn) unreferenced. |
C02 | The top-level element must be a Goal. A top-level element is an element that is not referenced by any other element. |
C03 | All referenced elements in supportedBy and inContextOf must exist. |
C04 | There must be no circular supportedBy references. |
C06 | All module names must be unique. |
C07 | All IDs must be unique across all modules. |
C08 | All elements must be reachable from the root elements. This message can e.g. happen if there are multiple independent graphs where one contains circular references only. |
C09 | All extended modules must exist. |
C10 | All extended elements must exist in the named module and must be undeveloped. |
Uniqueness of keys (i.e. element IDs) is automatically enforced by the YAML format.
If called with option -c
or --check
the input file is only checked for validity, but the resulting graph is not written.
The checks for references (Cxx) can be skipped for individual files by using the -x
option.
Format of messages
Error messages and warnings are printed to stderr.
The following format is used:
(Warning|Error): \((?<module>.+)\) \((?<num>[CV][0-9][0-9])\): (?<msg>.+)
Advance Use-cases
There are a few extra, advanced use-cases:
Formatting
gsn2x allows for different ways to formatting text. Formatting loosely follows Markdown syntax, even though not the full specification is supported.
Text emphasis
You can use *
and _
to emphasize text.
Text enclosed in *
's will be assigned a CSS class "bold".
Text enclosed in _
's will be assigned a CSS class "italic".
A default inline style is also assigned.
Example
This text:
This is a *bold* text. This is an _italic_ text.
will be rendered to:
This is a
bold
text. This is an
italic
text.
Hyperlinks
You can add hyperlinks for text:
attributes as well as all additional layers.
Hyperlinks are automatically detected when they start with "http://", "https://", "file://".
If you like to hide the actual URL, you can assign a text to the link that is rendered instead.
The syntax for this follows Markdown syntax. However, a title is not supported, only text
and href
are.
URLs may not contain whitespace characters. If you URL has one, just replace with %20
.
Please note that the link created by url:
cannot have additional text, since it is anyway invisible and applicable to the complete node.
Example
This link:
[Link Text](https://github.com/jonasthewolf/gsn2x)
will be rendered to:
This link:
https://github.com/jonasthewolf/gsn2x
will be rendered to:
https://github.com/jonasthewolf/gsn2x
Text layout within elements
You can control line breaks by YAML means, e.g. following this example:
G1:
text: |
This
is
shown
on
separate
lines
Alternatively, you can use the -w
option and provide a global number of characters after which lines are wrapped.
You can also use the optional charWrap
attribute for an element to individually define the number of characters after which line is wrapped. The same attribute can be applied for a complete module at the module
section.
Please note that wrapping is done if a whitespace is detected after the given number of characters.
Layout of elements
How does the default layout of the graph work?
At first, the root elements are identified. Root elements are elements
that are not referenced as supportedBy
or inContextOf
.
Each level in the rendered graph is called rank.
The elements on each rank are sorted lexicographically before being placed on that rank.
Then, starting with the first element on the current rank, the elements of the next rank are identified.
An element is only ranked if all elements referencing it are already placed.
Finally, the inContextOf
elements are placed on that rank.
Placement of elements
Vertical placement
To influence the vertical placement i.e., the rank, of an element in the rendered graph,
you can use rankIncrement
for a node.
A rank increment is a positive number to push an element this amount of ranks downwards.
It is not possible to decrease the rank that would be assigned by the above algorithm.
Incrementing the rank is especially useful, if e.g., two goals or strategies are on the same logical level, but have a different "depth" in the argumentation (i.e. a different number of goals or strategies in their path to the root goal).
See the example for usage. The strategy S2 has an incremented rank.
Horizontal placement
The order of the GSN elements on the same rank is in the first place defined by their ID.
The elements are sorted lexicographically. Thus, a goal G1
if placed on the same rank is placed left to G2
.
You can use horizontalIndex
to reorder elements after lexicographical sorting.
The index can be modified by giving a relative or absolute index.
In the following example, G1 and G2 are placed on the same rank. However, G2 is placed left of G1 because of the relative horizontal index.
G1:
text: Goal 1
undeveloped: true
G2:
text: Goal 2
undeveloped: true
horizontalIndex:
relative: -1
Please see Sn2 and Sn4 in example for how to use the absolute index.
Typical use-cases for defining an absolute index are putting elements at the beginning or the end within a rank. Please see the following example for how to use an absolute index.
G1:
text: Goal 1
undeveloped: true
horizontalIndex:
absolute: last
G2:
text: Goal 2
undeveloped: true
horizontalIndex:
absolute: 0
Please note that giving the horizontal index for G1 and G2 is redundant.
The absolute index is zero-based. You can use last
to move elements
to the very right of the graph.
The horizontal index can also be applied to inContextOf
elements.
You would typically use an absolute index with either 0
or last
to place them
either left or right of the element they are referenced from.
horizontalIndex
and rankIncrement
can also be used for module
elements.
They will be used for the Architecture View then (see Modular extension).
Troubleshooting
There can be situations (e.g. a n:m relation between goals and solutions)
that lead to weird looking graphs.
You may even encounter the following message
Diagram took too many iterations ({run}). See documentation (https://jonasthewolf.github.io/gsn2x/) for hints how to solve this situation.
In such cases, please use the mechanisms described above to support
the algorithm in ranking the elements more sensibly.
Moreover, gsn2x also outputs a hint on the list of elements that might cause the problem.
If you have trouble doing so, please feel free to create an issue or start a discussion on the GitHub site. The issue template on GitHub shows you how to remove intellectual property from the files that I would ask for then.
Example
The following small example will yield the above mentioned message:
G1:
text: First
supportedBy: [Sn2]
G2:
text: Second
supportedBy: [Sn1]
Sn1:
text: Solution to Second
Sn2:
text: Solution to First
The created SVG is hardly readable:
The reason for this is, that G1
is lexicographically ordered before G2
, but Sn2
after Sn1
.
Sn1
thus "pushes" Sn2
to the right in each iteration of the layout algorithm.
The problem is easily solvable in different ways:
- Rename
G1
and/orG2
to change their lexicographical order. - Rename
Sn1
and/orSn2
to change their lexicographical order. - Apply
horizontalIndex: absolute: last
toG1
orSn1
. - Apply
horizontalIndex: absolute: 0
toG2
orSn2
. - Apply
horizontalIndex: relative: +1
toG1
orSn1
. - Apply
horizontalIndex: relative: -1
toG2
orSn2
.
The order above can be considered - as a general rule of thumb - as a suggested order when trying to resolve layout issues.
Additional layers
Additional attributes of an element are not output into the rendered diagram.
With the command line option -l
or --layers
you can enable the output of those additional attributes.
By using this feature different views on the GSN can be generated.
Example
G1:
text: This is a Goal
supportedBy: [S1]
inContextOf: [C1]
layer1: This is additional information for G1.
S1:
text: This is a Strategy
layer1: This is additional information for S1.
C1:
text: This is a Context
layer1: This is additional information for C1.
In this example, a call to gsn2x -l layer1
will show the additional information to each element prefixed with LAYER1:
.
Of course, using text
, inContextOf
, supportedBy
, url
, undeveloped
,
horizontalRank
, rankIncrement
, acp
or classes
are not sensible parameters to pass for the -l
option.
Please note that using module
and passing it as a layer option will also not work.
It is intentional that information is only added for a view, but not hidden to ensure consistency of the GSN in all variants.
Only additional associative arrays with a string key can be used as additional layers.
Stylesheets for SVG rendering
You can provide (multiple) custom CSS stylesheets for SVG via the -s
or --stylesheet
options.
The path may be relative to the current working directory, absolute, or an URL (i.e. starting with http://
, https://
or file://
).
When adding -t
or --embed-css
on the command line, the CSS stylesheets will be embedded in the SVG.
If an output path is provided (see Basic usage), the stylesheet(s) will be copied there. If a relative path is used, the relative path to the current working directory is preserved. If an absolute path is used, the stylesheet will be copied to the root of the output path.
If a URL (see above for definition) is provided for a stylesheet, it is neither embedded nor copied to an output directory.
Classes and styles
Every element will also be addressable by id
. The id
is the same as the YAML id.
This table shows the CSS classes assigned to a certain element:
Class | Assigned to | SVG Element |
---|---|---|
gsndiagram | The complete diagram | svg |
gsnelem | All elements | g |
gsngoal | Goal | g |
gsn_undeveloped | Undeveloped | g |
gsnsltn | Solution | g |
gsnawaysltn | Away Solution | g |
gsnstgy | Strategy | g |
gsnasmp | Assumption | g |
gsnawayasmp | Away Assumption | g |
gsnjust | Justification | g |
gsnawayjust | Away Justification | g |
gsnctxt | Context | g |
gsnawayctxt | Away Context | g |
gsnmodule | Module | g |
gsn_module_module | Module name | g |
gsnedge | All edges | path |
gsnlay_<layer> | Layer <layer> | path |
gsninctxt | In Context Of | path |
gsnspby | Supported By | path |
gsncomposite | Composite (In Context Of AND Supported By) | path |
gsn_masked | Masked elements | g |
acp_acp_name | Elements or edges with an ACP | g or path |
You can assign additional classes by adding the classes:
attribute. It must be a list of classes you want to assign.
Additional layers will be added as CSS classes, too. A layer1
will e.g. be added as gsnlay_layer1
.
For more information on how to use CSS with SVGs, see here.
Example
The GSN YAML:
G1:
text: This is a Goal
classes: [additionalclass1, additionalclass2]
undeveloped: true
The corresponding CSS:
.additionalclass1 path { fill: red; fill-opacity: 1;}
.additionalclass1 text,a { fill: white; }
The result looks like this:
Highlighting elements when navigating
The CSS :target
pseudo class can be used to highlight the element you clicked on in the previous image.
An example could look like this:
g:target path {
fill: lightsteelblue;
fill-opacity: 1;
}
List of evidence
An additional file that lists all the evidence in the input file is output by default in evidence.md
.
See examples/evidence.md for an example.
The format can be used in Markdown and reStructuredText files.
If the list of evidence should not be output, use the -E
option.
You can use the -e
option to rename the standard evidence.md
to another file name, but not subdirectory.
The -o
option also applies to the evidence file.
Markdown from examples/evidence.md
List of Evidence
-
Sn1: Solution 1
examples_example_gsn_yaml
https://github.com/jonasthewolf/gsn2x
-
Sn2: Solution 2
examples_example_gsn_yaml
-
Sn3: Solution 3
examples_example_gsn_yaml
-
Sn4: Solution 4
examples_example_gsn_yaml
-
Sn5: Solution 5
examples_example_gsn_yaml
Modular extension
gsn2x partially supports the Modular Extension of the GSN standard (see Standard support).
Each module is a separate file. The name of the module is the file name (incl. the path provided to the gsn2x command line).
If modules are used, all related module files must be provided to the command line of gsn2x.
Element IDs must be unique across all modules. Checks will by default be performed across all modules.
Check messages for individual modules can be omitted using the -x
option.
The argument view of individual modules will show "away" elements if elements from other modules are referenced. All elements are public, meaning they can be referenced from other modules.
Note: There is no "away strategy" in the standard.
In addition to the default argument view for each module, there are two output files generated (if more than one input file is provided):
- Complete View (default to:
complete.svg
) - Architecture View (default to:
architecture.svg
)
You can only change the file names of these additional views.
They are put in the directory that all input files have in common.
The -o
option can be used for these views, too.
If the argument view should not be updated, use the -N
option.
If the complete view should not be output, use the -F
option.
If the architecture view should not be output, use the -A
option.
Complete view
The complete view is a similar to an argument view for a single module, but showing all modules within the same diagram. The modules are "unrolled".
See example here.
Architecture view
The architecture view only shows the selected modules and their dependencies. THe architecture view is navigable to the module argument view.
The architecture view only contains the links to the individual module files, if they actually exist when generating the architecture view.
See example here.
Example:
gsn2x -f full.svg -a arch.svg main.yml sub1.yml sub3.yml
This will generate the argument view for each module, the complete view (-f full.svg
) of all modules and the architecture view (-a arch.svg
).
Developing undeveloped elements from other modules
In a customer supplier relationship it may be helpful to develop otherwise undeveloped elements from other modules. This allows creating distributed assurance cases.
Example for a module with undeveloped elements:
module:
name: template
brief: Template for an assurance case
G1:
text: A claim somebody else should support
undeveloped: true
Example for developing those elements in another module:
module:
name: instance
brief: Extending instance
extends:
- module: template
develops:
G1: [G2]
G2:
text: This is the argument provided by somebody else.
supportedBy: [Sn1]
Sn1:
text: A solution
Optional module information
It is possible to add additional module
information in the source YAML.
This allows describing the module`s name and an optional brief description.
Even arbitrary information can be added.
name
and brief
are mandatory if a module
is added.
module:
name: MainModule
brief: This is a short description of the module
additionalInformation:
v1: Changed line 2
v2: Added line 4
The module information is printed as part of a legend for the argument view.
To influence the position in the architecture view, you can use the horizontalIndex
and rankIncrement
as you would for elements in the Argument view (see Layout of elements ).
You can use the -G
option to suppress the legend completely,
or the -g
option to limit it to name
, brief
and the time and date of generation of the SVG.
Including other modules
Multiple modules, i.e. files, can be provided at the command line:
gsn2x index.gsn.yaml required_module1.gsn.yaml required_module2.gsn.yaml required_module3.gsn.yaml
However, this might requires long and complex calls at the command line for reasonably large arguments.
Another way to use multiple modules is to "use" them from others. You can do so by adding a uses
attribute to a module:
module:
name: MainModule
brief: This is the index.gsn.yaml file
uses: [required_module1.yaml, required_module2.gsn.yaml, required_module3.gsn.yaml]
The command line is now simplified to:
gsn2x index.gsn.yaml
Or even (if you name the entry point file: index.gsn.yaml
):
gsn2x
Of course, "used" modules can also include other modules on their own. There is a check implemented to prevent circular includes.
Confidence Argument Extension
The Confidence Argument Extension is supported. It defines so called Assurance Claim Points (ACPs).
They can be defined either for an element or for the relation between elements.
The following YAML shows an example of their usage:
G1:
text: System is acceptably safe to operate
supportedBy: [S1]
acp:
ACP1: S1
S1:
text: Argument over all hazards
supportedBy: [G2, G3]
inContextOf: [C1]
acp:
ACP4: C1
C1:
text: Hazard list
acp:
ACP6: C1
G2:
text: Hazard 1 mitigated
supportedBy: [Sn1]
acp:
ACP2: Sn1
Sn1:
text: Evidence for Hazard 1
G3:
text: Hazard 2 mitigated
supportedBy: [Sn2a, Sn2b]
acp:
ACP3: [Sn2a, Sn2b]
Sn2a:
text: Evidence for Hazard 2
Sn2b:
text: More evidence for Hazard 2
acp:
ACP5: Sn2b
Assurance Claim Points (ACP) are defined with the acp
attribute.
The name of the ACP is followed by:
- either a reference to the element itself, or
- a reference or a list of references to elements that are directly related (
supportedBy
orinContextOf
).
There can be multiple ACPs per element.
Interfacing
Here is some guidance on interfacing with external sources.
I currently see two use-cases:
-
Use-case: Check if all configuration management items of a project exist that are mandated by the argumentation (as solutions/evidence).
The reference list may comprise more items that are required for argumentation, i.e. the list items must be attributed.
The reference list may be distributed across multiple files.
-
Use-case: Check if all normative/external requirements are fulfilled.
The reference list is a list of all normative requirements.
This use-case is actually the other way around than the first one.
For the example scripts below, yq
is required.
Checking evidence
This command lists all Solutions that are in example.gsn.yaml
but are not in reference.yaml
:
yq ea '[select(file_index == 0)|.Sn*.text] - [select(file_index == 1)|.[]]' examples/example.gsn.yaml reference.yaml
reference.yaml
could look like this:
# Configuration Management Items
- Solution 1
- Solution 2
Checking references
Depending on how the external format is defined, you can swap the part before the -
,
with the part after.
Standard support
This tool is based on the Goal Structuring Notation Community Standard Version 3.
This table shows the support of gsn2x
for the different parts of the standard.
Standard | Support |
---|---|
Core GSN | ✅ full |
Argument Pattern Extension | ❌ not planned |
Modular Extension | 🟡 partially, see Modular Extension; Module Interfaces (Section 1:4.6) and Inter-Module Contracts (Section 1:4.7) are not supported (this includes public decorators and module interface connectors). |
Confidence Argument Extension | ✅ full, see Confidence Argument Extension |
Dialectic Extension | ❌ not planned |
Troubleshooting
YAML error messages
If you encounter an error message like this, please use a YAML editor or online validator to check for the well-formedness of the input file:
Error: Failed to parse YAML from file <filename>
Caused by:
No valid GSN element can be found starting from line <n>.
This typically means that the YAML is completely invalid, or
the `text:` attribute is missing for an element,
or `supportedBy` or `inContextOf` are not followed by a list ([]).
Please see the documentation for details (https://jonasthewolf.github.io/gsn2x/troubleshooting.html).
Original error message: data did not match any variant of untagged enum GsnDocument.
Please see the YAML Syntax what is expected by the programs.
A good strategy to find out which element is causing the problem is to remove all but the first element from the input YAML file. Then running gsn2x again and incrementally adding the elements one by one again, until you hit the error message again.
Unfortunately, it is currently not possible to improve on the location of the error messages in this case.
Sanitizing files for e.g. support requests
You can sanitize your files from your intellectual property using, e.g. https://mikefarah.gitbook.io/yq/.
This statement replaces all text with x
es while keeping the number of characters:
yq "(.[] | select(. | has(\"text\"))) .text |=sub(\"[a-zA-Z0-9]\",\"x\"), ... comments=\"\"" inputfile.yaml > outputfile.yaml
Please note that element identifiers and additional layers are not sanitizied.
Design goals
I noticed that it might make sense to add some information about the goals I have set for myself for this project:
-
Everything-as-code
The tool should work in a continuos integration environment. The input format should be diff-able to support common git workflows with pull/merge requests.
-
Simplicity
I would like to keep things simple. Simple for me and others.
That means the input format should be simple to learn and edit manually in any editor. I also did not want invent a new DSL (domain-specific language) for that purpose. YAML (input file format) might not be the best format, but it serves as a good tradeoff for my purposes. Moreover, it can be parsed by other programs easily, too.
-
Standard conformance
I would like the program output to be very close to the GSN standard.
I don't want to redefine the semantics or add additional ones. The standard was created so that as many people as possible have some common grounds. If I added new fancy stuff, everyone might have a different interpretation of that again.
-
As few dependencies as possible
Since I understand that this tool might be used in some corporate environment where usage of free and open-source software might be limited, I try to keep the dependencies of this program as few as possible.
I used a very relaxed license and try to take care that it is compatible with those of the dependencies.
-
Full control by the user how the diagram is layed out
Creating an optimal rendering for all different use-cases is incredibly difficult. I failed in creating an algorithm that would allow for that. When trying I recognized that it is anyhow preferable to give the user full control over how the diagram should look like.
History
I also noticed that (also for myself) it is good to note down some history of the project:
-
It all started out in 2017 with the need for graphically representing some argumentation at work. I wrote a tiny Python script that used a jinja template to transform the YAML syntax into something Graphviz could understand.
From there Graphviz could generate different output formats. That's where the
x
ingsn2x
is from. -
It got obvious that some validation, especially on the uniqueness and reference resolution is needed to handle larger argumentation.
I did not want to write those validations in Python, but in my favorite programming language Rust. I released the first Rust version in July 2021.
-
I desperately tried adding the modular extension by convincing Graphviz to draw what I want, but I failed. I finally made decided to no longer output DOT, but directly generate SVGs from the program. This required writing a specialized version for rendering the tree on my own which ended up in version 2 finally released in April 2022.
-
I tried hard improving the layout algorithm over time but I failed to come up with a satisfying solution. Moreover, I recognized that it is anyway preferable if the user is in full control of the layout of the diagram. Thus, I decided to redesign the layout algorithm and create version 3. A new major version was needed because of different user input that is required now.
In addition, I changed the license from CC-BY-4.0 to MIT. MIT is shorter and more applicable to software.
-
Own usage and feedback from various people led to improvements of the layout algorithm. And now also to the implementation of the Confidence Argument Extension of the GSN standard as part of version 3.1.
Any feedback, especially the use-case in your company is very much appreciated.
Migrating from Version 2.x to Version 3.x
Version 2 of gsn2x tried to fully automate the layout of diagrams. Version 3 intentionally changed this approach.
To get similar or even better renderings, please follow the guidelines below.
Replace level
with rankIncrement
level
was deprecated. Instead, increment the rank of the elements that should be pushed further down.
Please see Layout for more information on how to use rankIncrement
.
Use strict lexicographical sorting and horizontal reordering to optimize the graph
If you find situations that are not rendered correctly by default,
please check if your IDs are sensibly defined (i.e. lexicographically increasing).
Use horizontalIndex
as described here to fix e.g., crossing edges.