Welcome to drawio2cbd’s Documentation!

The script converts an XML file produced using draw.io (or its web-based incarnation diagrams.net) and the library of Causal Block Diagram (CBD) blocks CBDLibrary.xml to a Python source file for use with the CBD simulation framework.

Note

In the remainder of this documentation, ‘drawio’ will be used to refer to draw.io and/or diagrams.net.

Author:Randy Paredis
Python Version:>= 3.6

Installation

In order for drawio2cbd to work, and for being able to model CBDs from drawio, the following files and dependencies are required:

Setting up Drawio

In drawio, select File ‣ Open Library and load CBDLibrary.xml (which can be found here). This provides a set of primitive CBD blocks that can be used in your models. Once included, it can be found at the top of the shapes library.

_images/library.png

CBD Library in the Sidebar

Block Properties

All blocks in the library have some block-specific properties that can be set by the user. Hovering over a component shows all non-empty properties that were set on this shape.

There are several ways of accessing/modifying these properties:

  • Click with right mouse button to open a shape’s context menu. Near the bottom of the list, select Edit Data.
  • Select the shape (left mouse button) and in the top of the right panel, go to Arrange ‣ Edit Data.
  • Select the shape and press CTRL + M or CMND + M.

Warning

Do not change the class_name as the drawio2cbd script relies on this property.

_images/properties.png

Example of the Property Window (for a ConstantBlock)

Working with Library Blocks

To guarantee a consistent visual appearance of CBD models, no blocks in the library, except for the Custom Block, can be resized. Every block has zero or more input and output ports. Input ports are represented by the InputPortBlock (black triangle) and output ports by the OutputPortBlock (white triangle). When selecting (left mouse button) a port, a small, movable, yellow/orange diamond-shaped anchor will appear in front of the port’s name. The position of this label can be changed by dragging the anchor. The port name can be altered in the Edit Data window.

For each of a CBD model’s top-level OutputPortBlock shapes, a signal property may be added (see Block Properties). The drawio2cbd will then generate code to produce a plot, using https://bokeh.org/. Note that bokeh produces an HTML document which is rendered in a browser and allows some user interaction with the plot. The value of the signal property on a top-level OutputPortBlock should be the title to be put on the plot. Multiple signals may be rendered onto the same plot. For more complex CBD simulation result analysis and visualization, code should be added at the bottom of the generated file.

Each CBD block that is not a port may have the following properties:

  • ID or id: The drawio unique ID for this block. Note that drawio automatically overwrites a property with the key id by the value shown by ID (upon saving the diagram).

  • block_name: The name of the block. It is required that all blocks have a unique name within a class. When omitted, the ID is used.

  • class_name: The type of block.

    Warning

    Do not change the class_name as the drawio2cbd script relies on this property. Changing it makes it so the block type changes as well in the simulation.

  • symbol: The block symbol that must be rendered by MathJax/LaTeX. This is a purely graphical attribute and is ignored by the script. Is not required for the script to work.

Optionally, additional class parameters can be provided by adding more properties. Their values will be passed on as default values for the corresponding property as an argument, e.g., to use strings, enclose the value in “…” or ‘…’, for None, leave it empty or litterally type “None”…

Warning

Make sure these values are expressions/rvalues! If not, the generated Python file will crash, or cause some unexpected behavior. Furthermore, newlines may not be used in these values.

Class parameters that cannot be used are: label (prevented by drawio), id (overwritten by drawio), placeholders (prevented by drawio), symbol (ignored by the script) and __docstring__ (used for other purposes, see later).

Note

Blocks with a variable number of inputs (i.e., the OrBlock and the AndBlock) still need additional ports to be placed in the block when calling drawio2cbd with the -p or --port option. Otherwise, one may use a single input, as long as the numberOfInputs property is set to a value that is at least the total number of incoming links.

Creating Custom CBD Blocks

A custom hierarchical CBD block is constructed as a network of already provided blocks (which in their own right may be custom hierarchical blocks) using the Custom Block element from CBDLibrary.xml. This is a collapsible component in which a block diagram may be drawn. It has two important properties:

  • class_name: The new class name for the custom block. Note that all class names must be unique!
  • block_name: The name of an instance of the CBD model if it’s the top-level CBD (see The drawio2cbd Script).

Additional properties can be added to create custom class parameters. The same set of parameters that was discussed above cannot be set, with the exception of __docstring__, which now allows adding documentation to custom blocks.

The empty rectangle is a container for the custom hierachical block. Blocks can be dragged into the rectangular area and connected. InputPortBlock and OutputPortBlock are used to add inputs and outputs with their name property set to the port’s name.

Hint

The Custom Block component can, in constrast with all other blocks in the library, be resized. This allows for larger hierarchical models to be created, as the basic blocks cannot be resized.

_images/custom-block.png

Custom Sine Generator Block with no Input Ports, a single Output Port and a Custom Graphical Representation

Next, create a graphical representation of the block (i.e., what an instance block should look like when used in a block diagram), add the corresponding ports and set the property class_name to the same class as that set in the Custom Block. Make sure not to forget to add any class parameters that were added to the Custom Block.

Hint

This can be done easily by adding a predefined block and changing its ports and properties to match the new custom block.

Note

Only the Custom Block components will be read by the drawio2cbd script. Anything else is implicitly ignored. Furthermore, the script is page-independent, meaning multiple pages may be used inside a single drawio document to maintain a clean overview of the created models.

The drawio2cbd Script

The script is to be run with Python (version >= 3.6) as given below. The generated code works with the CBD simulator, which is also for Python (version >= 3.6).

python drawio2cbd.py [options] input [output]

Where input represents an input file (a saved drawio diagram, either uncompressed or compressed XML), output an optional output file name. When omitted, the file will be printed to the console. Do note that both must be placed next to one another. options is a set of additional parameters that can influence the converted code:

  • -e ENTRY or --entry ENTRY: The top-level CBD’s name which will be instantiated and simulated. This option is required.
  • -T DELTA or --delta DELTA: Allows one to change the timestep size. For discrete-time CBDs, this should be 1.0. Continuous-time CBD will be be solved in terms of a discrete-time CBD approximation and the stepsize will be modelled explicitly as a constant. DELTA defaults to 1.0 (i.e., discrete-time CBDs). This parameter adds a DELTA_T ‘global’ variable to the generated simulation code, which may be referenced in drawio.
  • -t TIME or --time TIME: The simulation stop time. Defaults to 10. Start time is 0.
  • -P {mpl,matplotlib,bokeh,csv,off,false} or --plot {mpl,matplotlib,bokeh,csv,off,false}: Indicates the plotter that can be used. mpl or matplotlib indicates using matplotlib, bokeh will make use of bokeh, csv will write the plot data to a CSV file and off or false indicates no plot needs to be created. When the plotting library cannot be found, a warning will be shown and the simulation script will still be generated.
  • -a or --all: When set, CBDs without content will also be created as a class. This may be useful for subsequent manual completion of the class.
  • -p or --ports: Some port names can be identified from the context. By default, the generated code allows the CBD framework to do so. When this option is set, even those ports will explicitly be set.
  • -s SPACES or --spaces SPACES: Allows on to define the number of spaces that should act as an indent. When 0 or less, tabs will be used instead. Defaults to 0.

Note

Use the -h or --help flag to get a help menu.

Running the Simulation

For a simulation to be able to run, Python must be able to locate the CBD simulation framework. Once that is taken care of, the generated file can be run as-is. It can also first be customized with for example specific analysis post-processing of the simulation data.

Warning

The script does not do Python validity checking, so the CBD simulation may crash upon execution when the above-mentioned rules are violated (see Working with Library Blocks and Creating Custom CBD Blocks).

Tips and Tricks

  • The script does not care if the file is compressed or not. Yet, for debugging purposes and readability, one can disable the compression in the File ‣ Properties window in drawio.
  • When the models become quite large, it is possible drawio starts to lag. This can be prevented by using multiple pages (and sufficient hierarchy). Additionally, this makes the overal model file quite clean to work with. The conversion script ignores the use of pages and only concerns itself with the Custom Block components.
  • Make sure CBD models are fully contained by the large rectangle in the Custom Block shape. This can be tested by moving the Custom Block shape and checking that the contents move as well. You can see that you’re dragging a shape in this rectangle if its border becomes a blueish purple.
  • Custom Block shapes can be collapsed by clicking on the grey box in the top left corner of the shape.
  • CTRL + D or CMND + D allows one to duplicate shapes.
  • Dummy classes can be created by adding an empty block and converting with the -a or --all flag enabled. Do note that you would still need to implement these classes.
  • Keep custom shapes as simple as possible. Refrain from using other shapes to add icons or graphical representations for blocks. While it will be accepted by the script, groups can become quite cumbersome, especially with (partially) overlapping shapes. An easier way is by making use of UTF-8 icons, using their HTML notation. Take a look at one of the provided blocks for an example on how to do this. To add a more complex shape for blocks, Arrange ‣ Insert ‣ Shape can be used.