diff --git a/diagram_types/tree_diagrams/index.html b/diagram_types/tree_diagrams/index.html index ec1d0e9..f979ffd 100644 --- a/diagram_types/tree_diagrams/index.html +++ b/diagram_types/tree_diagrams/index.html @@ -1002,6 +1002,8 @@

Add Nodes

tree.auto_layout()
 tree.write()
 
+

With some more additions, the resulting diagram renders as:

+

coffee_grinders_tree

diff --git a/img/edge_styles/coords_examples.png b/img/edge_styles/coords_examples.png new file mode 100644 index 0000000..242b090 Binary files /dev/null and b/img/edge_styles/coords_examples.png differ diff --git a/img/edge_styles/coords_legend.png b/img/edge_styles/coords_legend.png new file mode 100644 index 0000000..ebce0cd Binary files /dev/null and b/img/edge_styles/coords_legend.png differ diff --git a/img/edge_styles/label_positions.png b/img/edge_styles/label_positions.png new file mode 100644 index 0000000..a1dc204 Binary files /dev/null and b/img/edge_styles/label_positions.png differ diff --git a/img/object_styles/object_default.png b/img/object_styles/object_default.png new file mode 100644 index 0000000..37cdc06 Binary files /dev/null and b/img/object_styles/object_default.png differ diff --git a/img/object_styles/object_default_fred.png b/img/object_styles/object_default_fred.png new file mode 100644 index 0000000..e9079e8 Binary files /dev/null and b/img/object_styles/object_default_fred.png differ diff --git a/img/object_styles/stylestr_edit_style.png b/img/object_styles/stylestr_edit_style.png new file mode 100644 index 0000000..bf5a0e5 Binary files /dev/null and b/img/object_styles/stylestr_edit_style.png differ diff --git a/img/object_styles/stylestr_styled_object.png b/img/object_styles/stylestr_styled_object.png new file mode 100644 index 0000000..c7fde72 Binary files /dev/null and b/img/object_styles/stylestr_styled_object.png differ diff --git a/img/tree_diagram/coffee_grinders_tree.png b/img/tree_diagram/coffee_grinders_tree.png new file mode 100644 index 0000000..f2c22c4 Binary files /dev/null and b/img/tree_diagram/coffee_grinders_tree.png differ diff --git a/search/search_index.json b/search/search_index.json index 2458aa8..7a0a8e9 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to drawpyo","text":"

Drawpyo is a Python library for programmatically generating Draw.io charts. It enables creating a diagram object, placing and styling objects, then writing the object to a file.

"},{"location":"#historyjustification","title":"History/Justification","text":"

I love Draw.io! Compared to expensive and heavy commercial options like Visio and Miro, Draw.io's free and lightweight app allows wider and more universal distribution of diagrams. Because the files are stored in plaintext they can be versioned alongside code in a repository as documentation. Draw.io also maintains back compatibility and any diagram created in the app since it was launched can still be opened. The XML-based file format makes these diagrams semi-portable, and could easily be ported to other applications if Draw.io ever disappeared. For these reason, I think it's one of the best options for documentation diagrams.

So wen I had a need to generate heirarchical tree diagrams of requirement structures I looked to Draw.io but I was surprised to find there wasn't even a single existing Python library for working with these files. I took the project home and spent a weekend building the initial functionality. I've been adding functionality, robustness, and documentation intermittently since.

"},{"location":"#the-future-of-drawpyo","title":"The Future of Drawpyo","text":"

I will continue to tinker away with this tool, creating new functionality as I need it or find it interesting. But it's unfortunately a rather low priority so if anyone wants to contribute I would be grateful for the help! Reach out to me at xander@merriman.industries if you want to contribute.

"},{"location":"about/","title":"Conventions and Naming","text":"

This library contains quite a lot of camel case (capitalizeEachWord) attributes. While the Python convention is snake case (underscores_between_lowercase) the Draw.io style strings and attributes are camel case. Wherever possible, drawpyo uses the terminology and variable names from Draw.io to make it more intuitive to work between the two apps. However, any attribute that does not have an analogy in the Draw.io app is snake case. While this is a bit confusing I hope it helps to clarify when there's a direct analog between drawpyo and Draw.io and when the variable is a drawpyo abstraction. If this is confusing please share that feedback on the GitHub page or email and it may be changed in future versions!

"},{"location":"about/#basic-diagrams","title":"Basic Diagrams","text":"

Drawpyo's basic functionality provides the same features as using the Draw.io app. You can create files with one or more pages, add objects to them, and position those objects. You can style objects from built-in shape libraries, manually, or from style strings. Those objects can be shapes, containers, or edges to connect them. Finally you can save your diagrams where they can be opened with the Draw.io app.

See the full documentation for these functions in Basic Diagrams - Usage.

"},{"location":"about/#extended-functionality","title":"Extended Functionality","text":"

Drawpyo extends the basic functionality of the Draw.io app with custom diagram types. These custom diagrams have automated styling and layouting to make common or complex diagrams easier to generate.

"},{"location":"about/#treediagram","title":"TreeDiagram","text":"

This diagram makes creating directed tree graphs easy. Define trees, nodes, and the apply an auto layout.

Documentation

"},{"location":"api/architecture/","title":"Architecture","text":"

Drawpyo provides two high level classes to define critical methods and attributes for all exportable Draw.io objects. Primarily they define the parent and id attributes as well as a series of methods and properties for generating XML and style strings.

"},{"location":"api/architecture/#xmlbase","title":"XMLBase","text":"

XMLBase is the base class for all exportable objects in drawpyo. This class defines a few useful properties that drawpyo needs to use to generate a Draw.io file.

Source code in src/drawpyo/xml_base.py
class XMLBase:\n    \"\"\"\n    XMLBase is the base class for all exportable objects in drawpyo. This class defines a few useful properties that drawpyo needs to use to generate a Draw.io file.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        self._id = kwargs.get(\"id\", id(self))\n        self.xml_class = kwargs.get(\"xml_class\", \"xml_tag\")\n\n        # There's only one situation where XMLBase is called directly: to\n        # create the two empty mxCell objects at the beginning of every\n        # Draw.io diagram. The following declarations should be overwritten\n        # in every other use case.\n        self.xml_parent = kwargs.get(\"xml_parent\", None)\n\n    @property\n    def id(self):\n        \"\"\"\n        id is a unique identifier. Draw.io generated diagrams use an ID many more characters but the app isn't picky when parsing so drawpyo just uses Python's built-in id() function as it guarantees unique identifiers.\n\n        Returns:\n            int: A unique identifier for the Draw.io object\n        \"\"\"\n        return self._id\n\n    @property\n    def attributes(self):\n        \"\"\"\n        The most basic attributes of a Draw.io object. Extended by subclasses.\n\n        Returns:\n            dict: A dict containing an 'id' and 'xml_parent' object.\n        \"\"\"\n        return {\"id\": self.id, \"parent\": self.xml_parent}\n\n    ###########################################################\n    # XML Tags\n    ###########################################################\n\n    @property\n    def xml_open_tag(self):\n        \"\"\"\n        The open tag contains the name of the object but also the attribute tags. This property function concatenates all the attributes in the class along with the opening and closing angle brackets and returns them as a string.\n\n        Example:\n        <class_name attribute_name=attribute_value>\n\n        Returns:\n            str: The opening tag of the object with all the attributes.\n        \"\"\"\n        open_tag = \"<\" + self.xml_class\n        for att, value in self.attributes.items():\n            if value is not None:\n                xml_parameter = self.xml_ify(str(value))\n                open_tag = open_tag + \" \" + att + '=\"' + xml_parameter + '\"'\n        return open_tag + \">\"\n\n    @property\n    def xml_close_tag(self):\n        \"\"\"\n        The closing tag contains the name of the object wrapped in angle brackets.\n\n        Example:\n        </class_name>\n\n        Returns:\n            str: The closing tag of the object with all the attributes.\n        \"\"\"\n        return \"</{0}>\".format(self.xml_class)\n\n    @property\n    def xml(self):\n        \"\"\"\n        All drawpyo exportable classes contain an xml property that returns the formatted string of their XML output.\n\n        This default version of the function assumes no inner value so it just returns the opening tag closed with a '/>'. Subclasses that require more printing overload this function with their own implementation.\n\n        Example:\n        <class_name attribute_name=attribute_value/>\n\n        Returns:\n            str: A single XML tag containing the object name, style attributes, and a closer.\n        \"\"\"\n        return self.xml_open_tag[:-1] + \" />\"\n\n    def xml_ify(self, parameter_string):\n        return self.translate_txt(parameter_string, xmlize)\n\n    @staticmethod\n    def translate_txt(string, replacement_dict):\n        new_str = \"\"\n        for char in string:\n            if char in replacement_dict:\n                new_str = new_str + replacement_dict[char]\n            else:\n                new_str = new_str + char\n        return new_str\n
"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.attributes","title":"attributes property","text":"

The most basic attributes of a Draw.io object. Extended by subclasses.

Returns:

Name Type Description dict

A dict containing an 'id' and 'xml_parent' object.

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.id","title":"id property","text":"

id is a unique identifier. Draw.io generated diagrams use an ID many more characters but the app isn't picky when parsing so drawpyo just uses Python's built-in id() function as it guarantees unique identifiers.

Returns:

Name Type Description int

A unique identifier for the Draw.io object

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.xml","title":"xml property","text":"

All drawpyo exportable classes contain an xml property that returns the formatted string of their XML output.

This default version of the function assumes no inner value so it just returns the opening tag closed with a '/>'. Subclasses that require more printing overload this function with their own implementation.

Example:

Returns:

Name Type Description str

A single XML tag containing the object name, style attributes, and a closer.

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.xml_close_tag","title":"xml_close_tag property","text":"

The closing tag contains the name of the object wrapped in angle brackets.

Example:

Returns:

Name Type Description str

The closing tag of the object with all the attributes.

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.xml_open_tag","title":"xml_open_tag property","text":"

The open tag contains the name of the object but also the attribute tags. This property function concatenates all the attributes in the class along with the opening and closing angle brackets and returns them as a string.

Example:

Returns:

Name Type Description str

The opening tag of the object with all the attributes.

"},{"location":"api/architecture/#diagrambase","title":"DiagramBase","text":"

Bases: XMLBase

This class is the base for all diagram objects to inherit from. It defines some general creation methods and properties to make diagram objects printable and useful.

Source code in src/drawpyo/diagram/base_diagram.py
class DiagramBase(XMLBase):\n    \"\"\"\n    This class is the base for all diagram objects to inherit from. It defines some general creation methods and properties to make diagram objects printable and useful.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self._style_attributes = [\"html\"]\n        self.page = kwargs.get(\"page\", None)\n        self.xml_parent = kwargs.get(\"xml_parent\", None)\n\n    @classmethod\n    def create_from_library(cls, library, obj):\n        return cls\n\n    # XML_parent property\n    @property\n    def xml_parent_id(self):\n        if self.xml_parent is not None:\n            return self.xml_parent.id\n        else:\n            return 1\n\n    # Parent object linking\n    @property\n    def xml_parent(self):\n        return self._xml_parent\n\n    @xml_parent.setter\n    def xml_parent(self, p):\n        if p is not None:\n            p.add_object(self)\n            self._xml_parent = p\n        else:\n            self._xml_parent = None\n\n    @xml_parent.deleter\n    def xml_parent(self):\n        self._xml_parent.remove_object(self)\n        self._xml_parent = None\n\n    # Page property\n    @property\n    def page_id(self):\n        if self.page is not None:\n            return self.page.id\n        else:\n            return 1\n\n    # page object linking\n    @property\n    def page(self):\n        return self._page\n\n    @page.setter\n    def page(self, p):\n        if p is not None:\n            p.add_object(self)\n            self._page = p\n        else:\n            self._page = None\n\n    @page.deleter\n    def page(self):\n        self._page.remove_object(self)\n        self._page = None\n\n    ###########################################################\n    # Style properties\n    ###########################################################\n    def add_style_attribute(self, style_attr):\n        if style_attr not in self._style_attributes:\n            self._style_attributes.append(style_attr)\n\n    @property\n    def style_attributes(self):\n        \"\"\"\n        The style attributes are the list of style tags that should be printed into the style XML attribute. This is a subset of the attributes defined on the object method.\n\n        Returns:\n            list: A list of the names of the style_attributes.\n        \"\"\"\n        return self._style_attributes\n\n    @style_attributes.setter\n    def style_attributes(self, value):\n        self._style_attributes = value\n\n    @property\n    def style(self):\n        \"\"\"\n        This function returns the style string of the object to be appended into the style XML attribute.\n\n        First it searches the object properties called out in\n        self.style_attributes. If the property is initialized to something\n        that isn't None or an empty string, it will add it. Otherwise it\n        searches the base_style defined by the object template.\n\n        Returns:\n            str: The style string of the object.\n\n        \"\"\"\n\n        style_str = \"\"\n        if (\n            hasattr(self, \"baseStyle\")\n            and getattr(self, \"baseStyle\") is not None\n            and getattr(self, \"baseStyle\") != \"\"\n        ):\n            style_str = getattr(self, \"baseStyle\") + \";\"\n\n        # Add style attributes\n        for attribute in self.style_attributes:\n            if hasattr(self, attribute) and getattr(self, attribute) is not None:\n                attr_val = getattr(self, attribute)\n                # reformat different datatypes to strings\n                if isinstance(attr_val, bool):\n                    attr_val = format(attr_val * 1)\n                style_str = style_str + \"{0}={1};\".format(attribute, attr_val)\n\n        # Add style objects\n        if hasattr(self, \"text_format\") and self.text_format is not None:\n            style_str = style_str + self.text_format.style\n        return style_str\n\n    def _add_and_set_style_attrib(self, attrib, value):\n        if hasattr(self, attrib):\n            setattr(self, attrib, value)\n        else:\n            setattr(self, attrib, value)\n            self.add_style_attribute(attrib)\n\n    def apply_style_string(self, style_str):\n        \"\"\"\n        This function will apply a passed in style string to the object. This style string can be obtained from the Draw.io app by selecting Edit Style from the context menu of any object. This function will iterate through the attributes in the style string and assign the corresponding property the value.\n\n        Args:\n            style_str (str): A Draw.io style string\n        \"\"\"\n        for attrib in style_str.split(\";\"):\n            if attrib == \"\":\n                pass\n            elif \"=\" in attrib:\n                a_name = attrib.split(\"=\")[0]\n                a_value = attrib.split(\"=\")[1]\n                if a_value.isdigit():\n                    if \".\" in a_value:\n                        a_value = float(a_value)\n                    else:\n                        a_value = int(a_value)\n                elif a_value == \"True\" or a_value == \"False\":\n                    a_value = bool(a_value)\n\n                self._add_and_set_style_attrib(a_name, a_value)\n            else:\n                self.baseStyle = attrib\n\n    def _apply_style_from_template(self, template):\n        for attrib in template.style_attributes:\n            value = getattr(template, attrib)\n            self._add_and_set_style_attrib(attrib, value)\n\n    def apply_attribute_dict(self, attr_dict):\n        \"\"\"\n        This function takes in a dictionary of attributes and applies them\n        to the object. These attributes can be style or properties. If the\n        attribute isn't already defined as a property of the class it's\n        assumed to be a style attribute. It will then be added as a property\n        and also appended to the .style_attributes list.\n\n        Parameters\n        ----------\n        attr_dict : dict\n            A dictionary of attributes to set or add to the object.\n\n        Returns\n        -------\n        None.\n\n        \"\"\"\n        for attr, val in attr_dict.items():\n            self._add_and_set_style_attrib(attr, val)\n\n    @classmethod\n    def from_style_string(cls, style_string):\n        \"\"\"\n        This classmethod allows the intantiation of an object from a style\n        string. This is useful since Draw.io allows copying the style string\n        out of an object in their UI. This string can then be copied into the\n        Python environment and further objects created that match the style.\n\n        Args:\n            style_string (str): A Draw.io style string\n\n        Returns:\n            BaseDiagram: A BaseDiagram or subclass instantiated with the style from the Draw.io string\n        \"\"\"\n        new_obj = cls()\n        new_obj.apply_style_string(style_string)\n        return new_obj\n
"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.style","title":"style property","text":"

This function returns the style string of the object to be appended into the style XML attribute.

First it searches the object properties called out in self.style_attributes. If the property is initialized to something that isn't None or an empty string, it will add it. Otherwise it searches the base_style defined by the object template.

Returns:

Name Type Description str

The style string of the object.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.style_attributes","title":"style_attributes property writable","text":"

The style attributes are the list of style tags that should be printed into the style XML attribute. This is a subset of the attributes defined on the object method.

Returns:

Name Type Description list

A list of the names of the style_attributes.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_attribute_dict","title":"apply_attribute_dict(attr_dict)","text":"

This function takes in a dictionary of attributes and applies them to the object. These attributes can be style or properties. If the attribute isn't already defined as a property of the class it's assumed to be a style attribute. It will then be added as a property and also appended to the .style_attributes list.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_attribute_dict--parameters","title":"Parameters","text":"

attr_dict : dict A dictionary of attributes to set or add to the object.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_attribute_dict--returns","title":"Returns","text":"

None.

Source code in src/drawpyo/diagram/base_diagram.py
def apply_attribute_dict(self, attr_dict):\n    \"\"\"\n    This function takes in a dictionary of attributes and applies them\n    to the object. These attributes can be style or properties. If the\n    attribute isn't already defined as a property of the class it's\n    assumed to be a style attribute. It will then be added as a property\n    and also appended to the .style_attributes list.\n\n    Parameters\n    ----------\n    attr_dict : dict\n        A dictionary of attributes to set or add to the object.\n\n    Returns\n    -------\n    None.\n\n    \"\"\"\n    for attr, val in attr_dict.items():\n        self._add_and_set_style_attrib(attr, val)\n
"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_style_string","title":"apply_style_string(style_str)","text":"

This function will apply a passed in style string to the object. This style string can be obtained from the Draw.io app by selecting Edit Style from the context menu of any object. This function will iterate through the attributes in the style string and assign the corresponding property the value.

Parameters:

Name Type Description Default style_str str

A Draw.io style string

required Source code in src/drawpyo/diagram/base_diagram.py
def apply_style_string(self, style_str):\n    \"\"\"\n    This function will apply a passed in style string to the object. This style string can be obtained from the Draw.io app by selecting Edit Style from the context menu of any object. This function will iterate through the attributes in the style string and assign the corresponding property the value.\n\n    Args:\n        style_str (str): A Draw.io style string\n    \"\"\"\n    for attrib in style_str.split(\";\"):\n        if attrib == \"\":\n            pass\n        elif \"=\" in attrib:\n            a_name = attrib.split(\"=\")[0]\n            a_value = attrib.split(\"=\")[1]\n            if a_value.isdigit():\n                if \".\" in a_value:\n                    a_value = float(a_value)\n                else:\n                    a_value = int(a_value)\n            elif a_value == \"True\" or a_value == \"False\":\n                a_value = bool(a_value)\n\n            self._add_and_set_style_attrib(a_name, a_value)\n        else:\n            self.baseStyle = attrib\n
"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.from_style_string","title":"from_style_string(style_string) classmethod","text":"

This classmethod allows the intantiation of an object from a style string. This is useful since Draw.io allows copying the style string out of an object in their UI. This string can then be copied into the Python environment and further objects created that match the style.

Parameters:

Name Type Description Default style_string str

A Draw.io style string

required

Returns:

Name Type Description BaseDiagram

A BaseDiagram or subclass instantiated with the style from the Draw.io string

Source code in src/drawpyo/diagram/base_diagram.py
@classmethod\ndef from_style_string(cls, style_string):\n    \"\"\"\n    This classmethod allows the intantiation of an object from a style\n    string. This is useful since Draw.io allows copying the style string\n    out of an object in their UI. This string can then be copied into the\n    Python environment and further objects created that match the style.\n\n    Args:\n        style_string (str): A Draw.io style string\n\n    Returns:\n        BaseDiagram: A BaseDiagram or subclass instantiated with the style from the Draw.io string\n    \"\"\"\n    new_obj = cls()\n    new_obj.apply_style_string(style_string)\n    return new_obj\n
"},{"location":"api/edges/","title":"Edges","text":""},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge","title":"src.drawpyo.diagram.edges.Edge","text":"

Bases: DiagramBase

The Edge class is the simplest class for defining an edge or an arrow in a Draw.io diagram.

The three primary styling inputs are the waypoints, connections, and pattern. These are how edges are styled in the Draw.io app, with dropdown menus for each one. But it's not how the style string is assembled in the XML. To abstract this, the Edge class loads a database called edge_styles.toml. The database maps the options in each dropdown to the style strings they correspond to. The Edge class then assembles the style strings on export.

More information about edges are in the Usage documents at Usage - Edges.

Source code in src/drawpyo/diagram/edges.py
class Edge(DiagramBase):\n    \"\"\"The Edge class is the simplest class for defining an edge or an arrow in a Draw.io diagram.\n\n    The three primary styling inputs are the waypoints, connections, and pattern. These are how edges are styled in the Draw.io app, with dropdown menus for each one. But it's not how the style string is assembled in the XML. To abstract this, the Edge class loads a database called edge_styles.toml. The database maps the options in each dropdown to the style strings they correspond to. The Edge class then assembles the style strings on export.\n\n    More information about edges are in the Usage documents at [Usage - Edges](../../usage/edges).\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        \"\"\"Edges can be initialized with almost all styling parameters as args.\n        See [Usage - Edges](../../usage/edges) for more information and the options for each parameter.\n\n        Args:\n            source (DiagramBase): The Draw.io object that the edge originates from\n            target (DiagramBase): The Draw.io object that the edge points to\n            label (str): The text to place on the edge.\n            label_position (float): Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center\n            label_offset (int): How far the label is offset away from the axis of the edge in pixels\n            waypoints (str): How the edge should be styled in Draw.io\n            connection (str): What type of style the edge should be rendered with\n            pattern (str): How the line of the edge should be rendered\n            shadow (bool, optional): Add a shadow to the edge\n            rounded (bool): Whether the corner of the line should be rounded\n            flowAnimation (bool): Add a marching ants animation along the edge\n            sketch (bool, optional): Add sketch styling to the edge\n            line_end_target (str): What graphic the edge should be rendered with at the target\n            line_end_source (str): What graphic the edge should be rendered with at the source\n            endFill_target (boolean): Whether the target graphic should be filled\n            endFill_source (boolean): Whether the source graphic should be filled\n            endSize (int): The size of the end arrow in points\n            startSize (int): The size of the start arrow in points\n            jettySize (str or int): Length of the straight sections at the end of the edge. \"auto\" or a number\n            targetPerimeterSpacing (int): The negative or positive spacing between the target and end of the edge (points)\n            sourcePerimeterSpacing (int): The negative or positive spacing between the source and end of the edge (points)\n            entryX (int): From where along the X axis on the source object the edge originates (0-1)\n            entryY (int): From where along the Y axis on the source object the edge originates (0-1)\n            entryDx (int): Applies an offset in pixels to the X axis entry point\n            entryDy (int): Applies an offset in pixels to the Y axis entry point\n            exitX (int): From where along the X axis on the target object the edge originates (0-1)\n            exitY (int): From where along the Y axis on the target object the edge originates (0-1)\n            exitDx (int): Applies an offset in pixels to the X axis exit point\n            exitDy (int): Applies an offset in pixels to the Y axis exit point\n            strokeColor (str): The color of the border of the edge ('none', 'default', or hex color code)\n            fillColor (str): The color of the fill of the edge ('none', 'default', or hex color code)\n            jumpStyle (str): The line jump style ('arc', 'gap', 'sharp', 'line')\n            jumpSize (int): The size of the line jumps in points.\n            opacity (int): The opacity of the edge (0-100)\n        \"\"\"\n        super().__init__(**kwargs)\n        self.xml_class = \"mxCell\"\n\n        # Style\n        self.text_format = kwargs.get(\"text_format\", TextFormat())\n        self.waypoints = kwargs.get(\"waypoints\", \"orthogonal\")\n        self.connection = kwargs.get(\"connection\", \"line\")\n        self.pattern = kwargs.get(\"pattern\", \"solid\")\n        self.opacity = kwargs.get(\"opacity\", None)\n        self.strokeColor = kwargs.get(\"strokeColor\", None)\n        self.fillColor = kwargs.get(\"fillColor\", None)\n\n        # Line end\n        self.line_end_target = kwargs.get(\"line_end_target\", None)\n        self.line_end_source = kwargs.get(\"line_end_source\", None)\n        self.endFill_target = kwargs.get(\"endFill_target\", False)\n        self.endFill_source = kwargs.get(\"endFill_source\", False)\n        self.endSize = kwargs.get(\"endSize\", None)\n        self.startSize = kwargs.get(\"startSize\", None)\n\n        self.rounded = kwargs.get(\"rounded\", 0)\n        self.sketch = kwargs.get(\"sketch\", None)\n        self.shadow = kwargs.get(\"shadow\", None)\n        self.flowAnimation = kwargs.get(\"flowAnimation\", None)\n\n        self.jumpStyle = kwargs.get(\"jumpStyle\", None)\n        self.jumpSize = kwargs.get(\"jumpSize\", None)\n\n        # Connection and geometry\n        self.jettySize = kwargs.get(\"jettySize\", \"auto\")\n        self.geometry = EdgeGeometry()\n        self.edge = kwargs.get(\"edge\", 1)\n        self.targetPerimeterSpacing = kwargs.get(\"targetPerimeterSpacing\", None)\n        self.sourcePerimeterSpacing = kwargs.get(\"sourcePerimeterSpacing\", None)\n        self.source = kwargs.get(\"source\", None)\n        self.target = kwargs.get(\"target\", None)\n        self.entryX = kwargs.get(\"entryX\", None)\n        self.entryY = kwargs.get(\"entryY\", None)\n        self.entryDx = kwargs.get(\"entryDx\", None)\n        self.entryDy = kwargs.get(\"entryDy\", None)\n        self.exitX = kwargs.get(\"exitX\", None)\n        self.exitY = kwargs.get(\"exitY\", None)\n        self.exitDx = kwargs.get(\"exitDx\", None)\n        self.exitDy = kwargs.get(\"exitDy\", None)\n\n        # Label\n        self.label = kwargs.get(\"label\", None)\n        self.edge_axis_offset = kwargs.get(\"edge_offset\", None)\n        self.label_offset = kwargs.get(\"label_offset\", None)\n        self.label_position = kwargs.get(\"label_position\", None)\n\n    def __repr__(self):\n        name_str = \"{0} edge from {1} to {2}\".format(\n            self.__class__.__name__, self.source, self.target\n        )\n        return name_str\n\n    def __str__(self):\n        return self.__repr__()\n\n    def remove(self):\n        \"\"\"This function removes references to the Edge from its source and target objects then deletes the Edge.\"\"\"\n        if self.source is not None:\n            self.source.remove_out_edge(self)\n        if self.target is not None:\n            self.target.remove_in_edge(self)\n        del self\n\n    @property\n    def attributes(self):\n        \"\"\"Returns the XML attributes to be added to the tag for the object\n\n        Returns:\n            dict: Dictionary of object attributes and their values\n        \"\"\"\n        base_attr_dict = {\n            \"id\": self.id,\n            \"style\": self.style,\n            \"edge\": self.edge,\n            \"parent\": self.xml_parent_id,\n            \"source\": self.source_id,\n            \"target\": self.target_id,\n        }\n        if self.value is not None:\n            base_attr_dict[\"value\"] = self.value\n        return base_attr_dict\n\n    ###########################################################\n    # Source and Target Linking\n    ###########################################################\n\n    # Source\n    @property\n    def source(self):\n        \"\"\"The source object of the edge. Automatically adds the edge to the object when set and removes it when deleted.\n\n        Returns:\n            BaseDiagram: source object of the edge\n        \"\"\"\n        return self._source\n\n    @source.setter\n    def source(self, f):\n        if f is not None:\n            f.add_out_edge(self)\n            self._source = f\n\n    @source.deleter\n    def source(self):\n        self._source.remove_out_edge(self)\n        self._source = None\n\n    @property\n    def source_id(self):\n        \"\"\"The ID of the source object or 1 if no source is set\n\n        Returns:\n            int: Source object ID\n        \"\"\"\n        if self.source is not None:\n            return self.source.id\n        else:\n            return 1\n\n    # Target\n    @property\n    def target(self):\n        \"\"\"The target object of the edge. Automatically adds the edge to the object when set and removes it when deleted.\n\n        Returns:\n            BaseDiagram: target object of the edge\n        \"\"\"\n        return self._target\n\n    @target.setter\n    def target(self, f):\n        if f is not None:\n            f.add_in_edge(self)\n            self._target = f\n\n    @target.deleter\n    def target(self):\n        self._target.remove_in_edge(self)\n        self._target = None\n\n    @property\n    def target_id(self):\n        \"\"\"The ID of the target object or 1 if no target is set\n\n        Returns:\n            int: Target object ID\n        \"\"\"\n        if self.target is not None:\n            return self.target.id\n        else:\n            return 1\n\n    def add_point(self, x, y):\n        \"\"\"Add a point to the edge\n\n        Args:\n            x (int): The x coordinate of the point in pixels\n            y (int): The y coordinate of the point in pixels\n        \"\"\"\n        self.geometry.points.append(Point(x=x, y=y))\n\n    def add_point_pos(self, position):\n        \"\"\"Add a point to the edge by position tuple\n\n        Args:\n            position (tuple): A tuple of ints describing the x and y coordinates in pixels\n        \"\"\"\n        self.geometry.points.append(Point(x=position[0], y=position[1]))\n\n    ###########################################################\n    # Style properties\n    ###########################################################\n\n    @property\n    def style_attributes(self):\n        \"\"\"The style attributes to add to the style tag in the XML\n\n        Returns:\n            list: A list of style attributes\n        \"\"\"\n        return [\n            \"rounded\",\n            \"sketch\",\n            \"shadow\",\n            \"flowAnimation\",\n            \"jettySize\",\n            \"entryX\",\n            \"entryY\",\n            \"entryDx\",\n            \"entryDy\",\n            \"exitX\",\n            \"exitY\",\n            \"exitDx\",\n            \"exitDy\",\n            \"startArrow\",\n            \"endArrow\",\n            \"startFill\",\n            \"endFill\",\n            \"strokeColor\",\n            \"fillColor\",\n            \"jumpStyle\",\n            \"jumpSize\",\n            \"targetPerimeterSpacing\",\n            \"sourcePerimeterSpacing\",\n            \"endSize\",\n            \"startSize\",\n            \"opacity\",\n        ]\n\n    @property\n    def baseStyle(self):\n        \"\"\"Generates the baseStyle string from the connection style, waypoint style, pattern style, and base style string.\n\n        Returns:\n            str: Concatenated baseStyle string\n        \"\"\"\n        style_str = []\n        connection_style = style_str_from_dict(connection_db[self.connection])\n        if connection_style is not None and connection_style != \"\":\n            style_str.append(connection_style)\n\n        waypoint_style = style_str_from_dict(waypoints_db[self.waypoints])\n        if waypoint_style is not None and waypoint_style != \"\":\n            style_str.append(waypoint_style)\n\n        pattern_style = style_str_from_dict(pattern_db[self.pattern])\n        if pattern_style is not None and pattern_style != \"\":\n            style_str.append(pattern_style)\n\n        if len(style_str) == 0:\n            return None\n        else:\n            return \";\".join(style_str)\n\n    @property\n    def startArrow(self):\n        \"\"\"What graphic the edge should be rendered with at the source\n\n        Returns:\n            str: The source edge graphic\n        \"\"\"\n        return self.line_end_source\n\n    @startArrow.setter\n    def startArrow(self, val):\n        self.line_end_source = val\n\n    @property\n    def startFill(self):\n        \"\"\"Whether the graphic at the source should be filled\n\n        Returns:\n            bool: The source graphic fill\n        \"\"\"\n        if line_ends_db[self.line_end_source][\"fillable\"]:\n            return self.endFill_source\n        else:\n            return None\n\n    @property\n    def endArrow(self):\n        \"\"\"What graphic the edge should be rendered with at the target\n\n        Returns:\n            str: The target edge graphic\n        \"\"\"\n        return self.line_end_target\n\n    @endArrow.setter\n    def endArrow(self, val):\n        self.line_end_target = val\n\n    @property\n    def endFill(self):\n        \"\"\"Whether the graphic at the target should be filled\n\n        Returns:\n            bool: The target graphic fill\n        \"\"\"\n        if line_ends_db[self.line_end_target][\"fillable\"]:\n            return self.endFill_target\n        else:\n            return None\n\n    # Base Line Style\n\n    # Waypoints\n    @property\n    def waypoints(self):\n        \"\"\"The waypoint style. Checks if the passed in value is in the TOML database of waypoints before setting and throws a ValueError if not.\n\n        Returns:\n            str: The style of the waypoints\n        \"\"\"\n        return self._waypoints\n\n    @waypoints.setter\n    def waypoints(self, value):\n        if value in waypoints_db.keys():\n            self._waypoints = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of waypoints\")\n\n    # Connection\n    @property\n    def connection(self):\n        \"\"\"The connection style. Checks if the passed in value is in the TOML database of connections before setting and throws a ValueError if not.\n\n        Returns:\n            str: The style of the connections\n        \"\"\"\n        return self._connection\n\n    @connection.setter\n    def connection(self, value):\n        if value in connection_db.keys():\n            self._connection = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of connection\".format(value))\n\n    # Pattern\n    @property\n    def pattern(self):\n        \"\"\"The pattern style. Checks if the passed in value is in the TOML database of patterns before setting and throws a ValueError if not.\n\n        Returns:\n            str: The style of the patterns\n        \"\"\"\n        return self._pattern\n\n    @pattern.setter\n    def pattern(self, value):\n        if value in pattern_db.keys():\n            self._pattern = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of pattern\")\n\n    # Color properties (enforce value)\n    ## strokeColor\n    @property\n    def strokeColor(self):\n        return self._strokeColor\n\n    @strokeColor.setter\n    def strokeColor(self, value):\n        self._strokeColor = color_input_check(value)\n\n    @strokeColor.deleter\n    def strokeColor(self):\n        self._strokeColor = None\n\n    # fillColor\n    @property\n    def fillColor(self):\n        return self._fillColor\n\n    @fillColor.setter\n    def fillColor(self, value):\n        self._fillColor = color_input_check(value)\n\n    @fillColor.deleter\n    def fillColor(self):\n        self._fillColor = None\n\n    # Jump style (enforce value)\n    @property\n    def jumpStyle(self):\n        return self._jumpStyle\n\n    @jumpStyle.setter\n    def jumpStyle(self, value):\n        if value in [None, \"arc\", \"gap\", \"sharp\", \"line\"]:\n            self._jumpStyle = value\n        else:\n            raise ValueError(f\"'{value}' is not a permitted jumpStyle value!\")\n\n    @jumpStyle.deleter\n    def jumpStyle(self):\n        self._jumpStyle = None\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n\n    @property\n    def label(self):\n        \"\"\"The text to place on the label, aka its value.\"\"\"\n        return self.value\n\n    @label.setter\n    def label(self, value):\n        self.value = value\n\n    @label.deleter\n    def label(self):\n        self.value = None\n\n    @property\n    def label_offset(self):\n        \"\"\"How far the label is offset away from the axis of the edge in pixels\"\"\"\n        return self.geometry.y\n\n    @label_offset.setter\n    def label_offset(self, value):\n        self.geometry.y = value\n\n    @label_offset.deleter\n    def label_offset(self):\n        self.geometry.y = None\n\n    @property\n    def label_position(self):\n        \"\"\"Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center.\"\"\"\n        return self.geometry.x\n\n    @label_position.setter\n    def label_position(self, value):\n        self.geometry.x = value\n\n    @label_position.deleter\n    def label_position(self):\n        self.geometry.x = None\n\n    @property\n    def xml(self):\n        \"\"\"The opening and closing XML tags with the styling attributes included.\n\n        Returns:\n            str: _description_\n        \"\"\"\n        tag = self.xml_open_tag + \"\\n  \" + self.geometry.xml + \"\\n\" + self.xml_close_tag\n        return tag\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.attributes","title":"attributes property","text":"

Returns the XML attributes to be added to the tag for the object

Returns:

Name Type Description dict

Dictionary of object attributes and their values

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.baseStyle","title":"baseStyle property","text":"

Generates the baseStyle string from the connection style, waypoint style, pattern style, and base style string.

Returns:

Name Type Description str

Concatenated baseStyle string

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.connection","title":"connection property writable","text":"

The connection style. Checks if the passed in value is in the TOML database of connections before setting and throws a ValueError if not.

Returns:

Name Type Description str

The style of the connections

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.endArrow","title":"endArrow property writable","text":"

What graphic the edge should be rendered with at the target

Returns:

Name Type Description str

The target edge graphic

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.endFill","title":"endFill property","text":"

Whether the graphic at the target should be filled

Returns:

Name Type Description bool

The target graphic fill

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.label","title":"label deletable property writable","text":"

The text to place on the label, aka its value.

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.label_offset","title":"label_offset deletable property writable","text":"

How far the label is offset away from the axis of the edge in pixels

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.label_position","title":"label_position deletable property writable","text":"

Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center.

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.pattern","title":"pattern property writable","text":"

The pattern style. Checks if the passed in value is in the TOML database of patterns before setting and throws a ValueError if not.

Returns:

Name Type Description str

The style of the patterns

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.source","title":"source deletable property writable","text":"

The source object of the edge. Automatically adds the edge to the object when set and removes it when deleted.

Returns:

Name Type Description BaseDiagram

source object of the edge

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.source_id","title":"source_id property","text":"

The ID of the source object or 1 if no source is set

Returns:

Name Type Description int

Source object ID

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.startArrow","title":"startArrow property writable","text":"

What graphic the edge should be rendered with at the source

Returns:

Name Type Description str

The source edge graphic

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.startFill","title":"startFill property","text":"

Whether the graphic at the source should be filled

Returns:

Name Type Description bool

The source graphic fill

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.style_attributes","title":"style_attributes property","text":"

The style attributes to add to the style tag in the XML

Returns:

Name Type Description list

A list of style attributes

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.target","title":"target deletable property writable","text":"

The target object of the edge. Automatically adds the edge to the object when set and removes it when deleted.

Returns:

Name Type Description BaseDiagram

target object of the edge

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.target_id","title":"target_id property","text":"

The ID of the target object or 1 if no target is set

Returns:

Name Type Description int

Target object ID

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.waypoints","title":"waypoints property writable","text":"

The waypoint style. Checks if the passed in value is in the TOML database of waypoints before setting and throws a ValueError if not.

Returns:

Name Type Description str

The style of the waypoints

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.xml","title":"xml property","text":"

The opening and closing XML tags with the styling attributes included.

Returns:

Name Type Description str

description

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.__init__","title":"__init__(**kwargs)","text":"

Edges can be initialized with almost all styling parameters as args. See Usage - Edges for more information and the options for each parameter.

Parameters:

Name Type Description Default source DiagramBase

The Draw.io object that the edge originates from

required target DiagramBase

The Draw.io object that the edge points to

required label str

The text to place on the edge.

required label_position float

Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center

required label_offset int

How far the label is offset away from the axis of the edge in pixels

required waypoints str

How the edge should be styled in Draw.io

required connection str

What type of style the edge should be rendered with

required pattern str

How the line of the edge should be rendered

required shadow bool

Add a shadow to the edge

required rounded bool

Whether the corner of the line should be rounded

required flowAnimation bool

Add a marching ants animation along the edge

required sketch bool

Add sketch styling to the edge

required line_end_target str

What graphic the edge should be rendered with at the target

required line_end_source str

What graphic the edge should be rendered with at the source

required endFill_target boolean

Whether the target graphic should be filled

required endFill_source boolean

Whether the source graphic should be filled

required endSize int

The size of the end arrow in points

required startSize int

The size of the start arrow in points

required jettySize str or int

Length of the straight sections at the end of the edge. \"auto\" or a number

required targetPerimeterSpacing int

The negative or positive spacing between the target and end of the edge (points)

required sourcePerimeterSpacing int

The negative or positive spacing between the source and end of the edge (points)

required entryX int

From where along the X axis on the source object the edge originates (0-1)

required entryY int

From where along the Y axis on the source object the edge originates (0-1)

required entryDx int

Applies an offset in pixels to the X axis entry point

required entryDy int

Applies an offset in pixels to the Y axis entry point

required exitX int

From where along the X axis on the target object the edge originates (0-1)

required exitY int

From where along the Y axis on the target object the edge originates (0-1)

required exitDx int

Applies an offset in pixels to the X axis exit point

required exitDy int

Applies an offset in pixels to the Y axis exit point

required strokeColor str

The color of the border of the edge ('none', 'default', or hex color code)

required fillColor str

The color of the fill of the edge ('none', 'default', or hex color code)

required jumpStyle str

The line jump style ('arc', 'gap', 'sharp', 'line')

required jumpSize int

The size of the line jumps in points.

required opacity int

The opacity of the edge (0-100)

required Source code in src/drawpyo/diagram/edges.py
def __init__(self, **kwargs):\n    \"\"\"Edges can be initialized with almost all styling parameters as args.\n    See [Usage - Edges](../../usage/edges) for more information and the options for each parameter.\n\n    Args:\n        source (DiagramBase): The Draw.io object that the edge originates from\n        target (DiagramBase): The Draw.io object that the edge points to\n        label (str): The text to place on the edge.\n        label_position (float): Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center\n        label_offset (int): How far the label is offset away from the axis of the edge in pixels\n        waypoints (str): How the edge should be styled in Draw.io\n        connection (str): What type of style the edge should be rendered with\n        pattern (str): How the line of the edge should be rendered\n        shadow (bool, optional): Add a shadow to the edge\n        rounded (bool): Whether the corner of the line should be rounded\n        flowAnimation (bool): Add a marching ants animation along the edge\n        sketch (bool, optional): Add sketch styling to the edge\n        line_end_target (str): What graphic the edge should be rendered with at the target\n        line_end_source (str): What graphic the edge should be rendered with at the source\n        endFill_target (boolean): Whether the target graphic should be filled\n        endFill_source (boolean): Whether the source graphic should be filled\n        endSize (int): The size of the end arrow in points\n        startSize (int): The size of the start arrow in points\n        jettySize (str or int): Length of the straight sections at the end of the edge. \"auto\" or a number\n        targetPerimeterSpacing (int): The negative or positive spacing between the target and end of the edge (points)\n        sourcePerimeterSpacing (int): The negative or positive spacing between the source and end of the edge (points)\n        entryX (int): From where along the X axis on the source object the edge originates (0-1)\n        entryY (int): From where along the Y axis on the source object the edge originates (0-1)\n        entryDx (int): Applies an offset in pixels to the X axis entry point\n        entryDy (int): Applies an offset in pixels to the Y axis entry point\n        exitX (int): From where along the X axis on the target object the edge originates (0-1)\n        exitY (int): From where along the Y axis on the target object the edge originates (0-1)\n        exitDx (int): Applies an offset in pixels to the X axis exit point\n        exitDy (int): Applies an offset in pixels to the Y axis exit point\n        strokeColor (str): The color of the border of the edge ('none', 'default', or hex color code)\n        fillColor (str): The color of the fill of the edge ('none', 'default', or hex color code)\n        jumpStyle (str): The line jump style ('arc', 'gap', 'sharp', 'line')\n        jumpSize (int): The size of the line jumps in points.\n        opacity (int): The opacity of the edge (0-100)\n    \"\"\"\n    super().__init__(**kwargs)\n    self.xml_class = \"mxCell\"\n\n    # Style\n    self.text_format = kwargs.get(\"text_format\", TextFormat())\n    self.waypoints = kwargs.get(\"waypoints\", \"orthogonal\")\n    self.connection = kwargs.get(\"connection\", \"line\")\n    self.pattern = kwargs.get(\"pattern\", \"solid\")\n    self.opacity = kwargs.get(\"opacity\", None)\n    self.strokeColor = kwargs.get(\"strokeColor\", None)\n    self.fillColor = kwargs.get(\"fillColor\", None)\n\n    # Line end\n    self.line_end_target = kwargs.get(\"line_end_target\", None)\n    self.line_end_source = kwargs.get(\"line_end_source\", None)\n    self.endFill_target = kwargs.get(\"endFill_target\", False)\n    self.endFill_source = kwargs.get(\"endFill_source\", False)\n    self.endSize = kwargs.get(\"endSize\", None)\n    self.startSize = kwargs.get(\"startSize\", None)\n\n    self.rounded = kwargs.get(\"rounded\", 0)\n    self.sketch = kwargs.get(\"sketch\", None)\n    self.shadow = kwargs.get(\"shadow\", None)\n    self.flowAnimation = kwargs.get(\"flowAnimation\", None)\n\n    self.jumpStyle = kwargs.get(\"jumpStyle\", None)\n    self.jumpSize = kwargs.get(\"jumpSize\", None)\n\n    # Connection and geometry\n    self.jettySize = kwargs.get(\"jettySize\", \"auto\")\n    self.geometry = EdgeGeometry()\n    self.edge = kwargs.get(\"edge\", 1)\n    self.targetPerimeterSpacing = kwargs.get(\"targetPerimeterSpacing\", None)\n    self.sourcePerimeterSpacing = kwargs.get(\"sourcePerimeterSpacing\", None)\n    self.source = kwargs.get(\"source\", None)\n    self.target = kwargs.get(\"target\", None)\n    self.entryX = kwargs.get(\"entryX\", None)\n    self.entryY = kwargs.get(\"entryY\", None)\n    self.entryDx = kwargs.get(\"entryDx\", None)\n    self.entryDy = kwargs.get(\"entryDy\", None)\n    self.exitX = kwargs.get(\"exitX\", None)\n    self.exitY = kwargs.get(\"exitY\", None)\n    self.exitDx = kwargs.get(\"exitDx\", None)\n    self.exitDy = kwargs.get(\"exitDy\", None)\n\n    # Label\n    self.label = kwargs.get(\"label\", None)\n    self.edge_axis_offset = kwargs.get(\"edge_offset\", None)\n    self.label_offset = kwargs.get(\"label_offset\", None)\n    self.label_position = kwargs.get(\"label_position\", None)\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.add_point","title":"add_point(x, y)","text":"

Add a point to the edge

Parameters:

Name Type Description Default x int

The x coordinate of the point in pixels

required y int

The y coordinate of the point in pixels

required Source code in src/drawpyo/diagram/edges.py
def add_point(self, x, y):\n    \"\"\"Add a point to the edge\n\n    Args:\n        x (int): The x coordinate of the point in pixels\n        y (int): The y coordinate of the point in pixels\n    \"\"\"\n    self.geometry.points.append(Point(x=x, y=y))\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.add_point_pos","title":"add_point_pos(position)","text":"

Add a point to the edge by position tuple

Parameters:

Name Type Description Default position tuple

A tuple of ints describing the x and y coordinates in pixels

required Source code in src/drawpyo/diagram/edges.py
def add_point_pos(self, position):\n    \"\"\"Add a point to the edge by position tuple\n\n    Args:\n        position (tuple): A tuple of ints describing the x and y coordinates in pixels\n    \"\"\"\n    self.geometry.points.append(Point(x=position[0], y=position[1]))\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.remove","title":"remove()","text":"

This function removes references to the Edge from its source and target objects then deletes the Edge.

Source code in src/drawpyo/diagram/edges.py
def remove(self):\n    \"\"\"This function removes references to the Edge from its source and target objects then deletes the Edge.\"\"\"\n    if self.source is not None:\n        self.source.remove_out_edge(self)\n    if self.target is not None:\n        self.target.remove_in_edge(self)\n    del self\n
"},{"location":"api/file/","title":"File","text":""},{"location":"api/file/#src.drawpyo.file.File","title":"src.drawpyo.file.File","text":"

Bases: XMLBase

The File class defines a Draw.io file, its properties, and the methods required for saving it.

Source code in src/drawpyo/file.py
class File(XMLBase):\n    \"\"\"The File class defines a Draw.io file, its properties, and the methods required for saving it.\"\"\"\n\n    def __init__(\n        self,\n        file_name=\"Drawpyo Diagram.drawio\",\n        file_path=path.join(path.expanduser(\"~\"), \"Drawpyo Charts\"),\n    ):\n        \"\"\"To initiate a File object, pass in a name and path or leave it to the defaults.\n\n        Args:\n            file_name (str, optional): The name of the file.\n            file_path (str, optional): The location where the file will be saved.\n        \"\"\"\n\n        super().__init__()\n\n        self.pages = []\n        self.file_name = file_name\n        self.file_path = file_path\n\n        # Attributes\n        self.host = \"Drawpyo\"\n        self.type = \"device\"\n        self.version = \"21.6.5\"  # This is the version of the Draw.io spec\n        self.xml_class = \"mxfile\"\n\n    def __repr__(self):\n        return f\"drawpyo File - {self.file_name}\"\n\n    @property\n    def attributes(self):\n        return {\n            \"host\": self.host,\n            \"modified\": self.modified,\n            \"agent\": self.agent,\n            \"etag\": self.etag,\n            \"version\": self.version,\n            \"type\": self.type,\n        }\n\n    def add_page(self, page):\n        \"\"\"Add a page to the file.\n\n        Args:\n            page (drawpyo.diagram.Page): A Page object\n        \"\"\"\n        page._file = self\n        self.pages.append(page)\n\n    def remove_page(self, page):\n        \"\"\"Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.\n\n        Args:\n            page (drawpyo.diagram.Page or str or int): A Page object that's currently contained in the file\n        \"\"\"\n        if isinstance(page, int):\n            del self.pages[page]\n        elif isinstance(page, str):\n            for pg in self.pages:\n                if pg.name == page:\n                    self.pages.remove(pg)\n        elif isinstance(page, Page):\n            self.pages.remove(page)\n\n    ###########################################################\n    # File Properties\n    ###########################################################\n\n    @property\n    def modified(self):\n        return datetime.now().strftime(\"%Y-%m-%dT%H:%M:%S\")\n\n    @property\n    def agent(self):\n        python_version = f\"{version_info.major}.{version_info.minor}\"\n        drawpyo_version = f\"0.01\"\n        return f\"Python {python_version}, Drawpyo {drawpyo_version}\"\n\n    @property\n    def etag(self):\n        # etag is in the Draw.io spec but not sure how it's used or if I need to create it\n        return None\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n\n    @property\n    def xml(self):\n        \"\"\"This function goes through each page in the file, retrieves its XML, and appends it to a list, then wraps that list in the file's open and close tags.\n\n        Returns:\n            str: The XML data for the file and all the pages in it\n        \"\"\"\n        xml_string = self.xml_open_tag\n        for diag in self.pages:\n            xml_string = xml_string + \"\\n  \" + diag.xml\n        xml_string = xml_string + \"\\n\" + self.xml_close_tag\n        return xml_string\n\n    ###########################################################\n    # File Handling\n    ###########################################################\n    def write(self, **kwargs):\n        \"\"\"This function write the file to disc at the path and name specified.\n\n        Args:\n            file_path (str, opt): The path to save the file in\n            file_name (str, opt): The name of the file\n            overwrite (bool, opt): Whether to overwrite an existing file or not\n        \"\"\"\n\n        # Check if file_path or file_name were passed in, or are preexisting\n        self.file_path = kwargs.get(\"file_path\", self.file_path)\n\n        self.file_name = kwargs.get(\"file_name\", self.file_name)\n\n        overwrite = kwargs.get(\"overwrite\", True)\n        if overwrite:\n            write_mode = \"w\"\n        else:\n            write_mode = \"x\"\n\n        if not path.exists(self.file_path):\n            makedirs(self.file_path)\n\n        f = open(\n            path.join(self.file_path, self.file_name), write_mode, encoding=\"utf-8\"\n        )\n        f.write(self.xml)\n        f.close\n\n        return path.join(self.file_path, self.file_name)\n
"},{"location":"api/file/#src.drawpyo.file.File.xml","title":"xml property","text":"

This function goes through each page in the file, retrieves its XML, and appends it to a list, then wraps that list in the file's open and close tags.

Returns:

Name Type Description str

The XML data for the file and all the pages in it

"},{"location":"api/file/#src.drawpyo.file.File.__init__","title":"__init__(file_name='Drawpyo Diagram.drawio', file_path=path.join(path.expanduser('~'), 'Drawpyo Charts'))","text":"

To initiate a File object, pass in a name and path or leave it to the defaults.

Parameters:

Name Type Description Default file_name str

The name of the file.

'Drawpyo Diagram.drawio' file_path str

The location where the file will be saved.

join(expanduser('~'), 'Drawpyo Charts') Source code in src/drawpyo/file.py
def __init__(\n    self,\n    file_name=\"Drawpyo Diagram.drawio\",\n    file_path=path.join(path.expanduser(\"~\"), \"Drawpyo Charts\"),\n):\n    \"\"\"To initiate a File object, pass in a name and path or leave it to the defaults.\n\n    Args:\n        file_name (str, optional): The name of the file.\n        file_path (str, optional): The location where the file will be saved.\n    \"\"\"\n\n    super().__init__()\n\n    self.pages = []\n    self.file_name = file_name\n    self.file_path = file_path\n\n    # Attributes\n    self.host = \"Drawpyo\"\n    self.type = \"device\"\n    self.version = \"21.6.5\"  # This is the version of the Draw.io spec\n    self.xml_class = \"mxfile\"\n
"},{"location":"api/file/#src.drawpyo.file.File.add_page","title":"add_page(page)","text":"

Add a page to the file.

Parameters:

Name Type Description Default page Page

A Page object

required Source code in src/drawpyo/file.py
def add_page(self, page):\n    \"\"\"Add a page to the file.\n\n    Args:\n        page (drawpyo.diagram.Page): A Page object\n    \"\"\"\n    page._file = self\n    self.pages.append(page)\n
"},{"location":"api/file/#src.drawpyo.file.File.remove_page","title":"remove_page(page)","text":"

Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.

Parameters:

Name Type Description Default page Page or str or int

A Page object that's currently contained in the file

required Source code in src/drawpyo/file.py
def remove_page(self, page):\n    \"\"\"Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.\n\n    Args:\n        page (drawpyo.diagram.Page or str or int): A Page object that's currently contained in the file\n    \"\"\"\n    if isinstance(page, int):\n        del self.pages[page]\n    elif isinstance(page, str):\n        for pg in self.pages:\n            if pg.name == page:\n                self.pages.remove(pg)\n    elif isinstance(page, Page):\n        self.pages.remove(page)\n
"},{"location":"api/file/#src.drawpyo.file.File.write","title":"write(**kwargs)","text":"

This function write the file to disc at the path and name specified.

Parameters:

Name Type Description Default file_path (str, opt)

The path to save the file in

required file_name (str, opt)

The name of the file

required overwrite (bool, opt)

Whether to overwrite an existing file or not

required Source code in src/drawpyo/file.py
def write(self, **kwargs):\n    \"\"\"This function write the file to disc at the path and name specified.\n\n    Args:\n        file_path (str, opt): The path to save the file in\n        file_name (str, opt): The name of the file\n        overwrite (bool, opt): Whether to overwrite an existing file or not\n    \"\"\"\n\n    # Check if file_path or file_name were passed in, or are preexisting\n    self.file_path = kwargs.get(\"file_path\", self.file_path)\n\n    self.file_name = kwargs.get(\"file_name\", self.file_name)\n\n    overwrite = kwargs.get(\"overwrite\", True)\n    if overwrite:\n        write_mode = \"w\"\n    else:\n        write_mode = \"x\"\n\n    if not path.exists(self.file_path):\n        makedirs(self.file_path)\n\n    f = open(\n        path.join(self.file_path, self.file_name), write_mode, encoding=\"utf-8\"\n    )\n    f.write(self.xml)\n    f.close\n\n    return path.join(self.file_path, self.file_name)\n
"},{"location":"api/objects/","title":"Objects","text":""},{"location":"api/objects/#object-creation","title":"Object Creation","text":""},{"location":"api/objects/#object_from_library","title":"object_from_library","text":""},{"location":"api/objects/#src.drawpyo.diagram.objects.object_from_library","title":"src.drawpyo.diagram.objects.object_from_library(library, obj_name, **kwargs)","text":"

This function generates an Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.

Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. These keyword arguments will overwrite any attributes defined in the library.

Parameters:

Name Type Description Default library str or dict

The library containing the object

required obj_name str

The name of the object in the library to generate

required

Returns:

Name Type Description Object

An object with the style from the library

Source code in src/drawpyo/diagram/objects.py
def object_from_library(library, obj_name, **kwargs):\n    \"\"\"This function generates an Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n    Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. These keyword arguments will overwrite any attributes defined in the library.\n\n    Args:\n        library (str or dict): The library containing the object\n        obj_name (str): The name of the object in the library to generate\n\n    Returns:\n        Object: An object with the style from the library\n    \"\"\"\n    new_obj = Object(**kwargs)\n    new_obj.format_as_library_object(library, obj_name)\n    new_obj.apply_attribute_dict(kwargs)\n    return new_obj\n
"},{"location":"api/objects/#object","title":"Object","text":""},{"location":"api/objects/#src.drawpyo.diagram.objects.Object","title":"src.drawpyo.diagram.objects.Object","text":"

Bases: DiagramBase

The Object class is the base object for all shapes in Draw.io.

More information about objects are in the Usage documents at Usage - Objects.

Source code in src/drawpyo/diagram/objects.py
class Object(DiagramBase):\n    \"\"\"\n    The Object class is the base object for all shapes in Draw.io.\n\n    More information about objects are in the Usage documents at [Usage - Objects](../../usage/objects).\n    \"\"\"\n\n    ###########################################################\n    # Initialization Functions\n    ###########################################################\n\n    def __init__(self, value=\"\", position=(0, 0), **kwargs):\n        \"\"\"A Object can be initialized with as many or as few of its styling attributes as is desired.\n\n        Args:\n            value (str, optional): The text to fill the object with. Defaults to \"\".\n            position (tuple, optional): The position of the object in pixels, in (X, Y). Defaults to (0, 0).\n\n        Keyword Args:\n            width (int, optional): The width of the object in pixels. Defaults to 120.\n            height (int, optional): The height of the object in pixels. Defaults to 80.\n            template_object (Object, optional): Another object to copy the style_attributes from\n            aspect\n            rounded (bool, optional): Whether to round the corners of the shape\n            whiteSpace (str, optional): white space\n            fillColor (str, optional): The object fill color in a hex color code (#ffffff)\n            opacity  (int, optional): The object's opacity, 0-100\n            strokeColor: The object stroke color in a hex color code (#ffffff)\n            glass (bool, optional): Apply glass styling to  the object\n            shadow (bool, optional): Add a shadow to the object\n            sketch (bool, optional): Add sketch styling to the object\n            comic (bool, optional): Add comic styling to the object\n            line_pattern (str, optional): The stroke style of the object.\n        \"\"\"\n        super().__init__(**kwargs)\n        self._style_attributes = [\n            \"whiteSpace\",\n            \"rounded\",\n            \"fillColor\",\n            \"strokeColor\",\n            \"glass\",\n            \"shadow\",\n            \"comic\",\n            \"sketch\",\n            \"opacity\",\n            \"dashed\",\n        ]\n\n        # Geometry\n        self.geometry = Geometry(parent_object=self)\n        self.position = kwargs.get(\"position\", (0, 0))\n        self.width = kwargs.get(\"width\", 120)\n        self.height = kwargs.get(\"height\", 80)\n        self.vertex = kwargs.get(\"vertex\", 1)\n\n        # TODO enumerate to fixed\n        self.aspect = kwargs.get(\"aspect\", None)\n\n        # Content\n        self.text_format = kwargs.get(\"text_format\", TextFormat())\n        self.value = value\n\n        # Style\n        self.baseStyle = kwargs.get(\"baseStyle\", None)\n\n        self.rounded = kwargs.get(\"rounded\", 0)\n        self.whiteSpace = kwargs.get(\"whiteSpace\", \"wrap\")\n        self.opacity = kwargs.get(\"opacity\", None)\n        self.strokeColor = kwargs.get(\"strokeColor\", None)\n        self.fillColor = kwargs.get(\"fillColor\", None)\n        self.glass = kwargs.get(\"glass\", None)\n        self.shadow = kwargs.get(\"shadow\", None)\n        self.comic = kwargs.get(\"comic\", None)\n        self.sketch = kwargs.get(\"sketch\", None)\n        self.line_pattern = kwargs.get(\"line_pattern\", \"solid\")\n\n        self.out_edges = kwargs.get(\"out_edges\", [])\n        self.in_edges = kwargs.get(\"in_edges\", [])\n\n        self.xml_class = \"mxCell\"\n\n        if \"template_object\" in kwargs:\n            self.template_object = kwargs.get(\"template_object\")\n            self._apply_style_from_template(self.template_object)\n            self.width = self.template_object.width\n            self.height = self.template_object.height\n\n    def __repr__(self):\n        if self.value != \"\":\n            name_str = \"{0} object with value {1}\".format(\n                self.__class__.__name__, self.value\n            )\n        else:\n            name_str = \"{0} object\".format(self.__class__.__name__)\n        return name_str\n\n    def __str_(self):\n        return self.__repr__()\n\n    @classmethod\n    def create_from_template_object(\n        cls, template_object, value=None, position=None, page=None\n    ):\n        \"\"\"Object can be instantiated from another object. This will initialize the Object with the same formatting, then set a new position and value.\n\n        Args:\n            template_object (Object): Another drawpyo Object to use as a template\n            value (str, optional): The text contents of the object. Defaults to None.\n            position (tuple, optional): The position where the object should be placed. Defaults to (0, 0).\n            page (Page, optional): The Page object to place the object on. Defaults to None.\n\n        Returns:\n            Object: The newly created object\n        \"\"\"\n        new_obj = cls(\n            value=value,\n            page=page,\n            width=template_object.width,\n            height=template_object.height,\n            template_object=template_object,\n        )\n        if position is not None:\n            new_obj.position = position\n        if value is not None:\n            new_obj.value = value\n        return new_obj\n\n    @classmethod\n    def create_from_style_string(cls, style_string):\n        \"\"\"Objects can be instantiated from a style string. These strings are most easily found in the Draw.io app, by styling an object as desired then right-clicking and selecting \"Edit Style\". Copying that text into this function will generate an object styled the same.\n\n        Args:\n            style_string (str): A Draw.io generated style string.\n\n        Returns:\n            Object: An object formatted with the style string\n        \"\"\"\n        cls.apply_style_from_string(style_string)\n        return cls\n\n    @classmethod\n    def create_from_library(cls, library, obj_name):\n        \"\"\"This function generates a Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n        Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. However, the styling in the library will overwrite that formatting.\n\n        Args:\n            library (str or dict): The library containing the object\n            obj_name (str): The name of the object in the library to generate\n\n        Returns:\n            Object: An object with the style from the library\n        \"\"\"\n        new_obj = cls()\n        new_obj.format_as_library_object(library, obj_name)\n        return new_obj\n\n    def format_as_library_object(self, library, obj_name):\n        \"\"\"This function applies the style from a library to an existing object. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n        Args:\n            library (str or dict): The library containing the object\n            obj_name (str): The name of the object in the library to generate\n        \"\"\"\n        if type(library) == str:\n            if library in base_libraries:\n                library_dict = base_libraries[library]\n                if obj_name in library_dict:\n                    obj_dict = library_dict[obj_name]\n                    self.apply_attribute_dict(obj_dict)\n                else:\n                    raise ValueError(\n                        \"Object {0} not in Library {1}\".format(obj_name, library)\n                    )\n            else:\n                raise ValueError(\"Library {0} not in base_libraries\".format(library))\n        elif type(library) == dict:\n            obj_dict = library[obj_name]\n            self.apply_attribute_dict(obj_dict)\n        else:\n            raise ValueError(\"Unparseable libary passed in.\")\n\n    @property\n    def attributes(self):\n        return {\n            \"id\": self.id,\n            \"value\": self.value,\n            \"style\": self.style,\n            \"vertex\": self.vertex,\n            \"parent\": self.xml_parent_id,\n        }\n\n    ###########################################################\n    # Style templates\n    ###########################################################\n\n    @property\n    def line_styles(self):\n        return line_styles\n\n    @property\n    def container(self):\n        return container\n\n    ###########################################################\n    # Style properties\n    ###########################################################\n\n    @property\n    def line_pattern(self):\n        \"\"\"Two properties are enumerated together into line_pattern: dashed and dashPattern. line_pattern simplifies this with an external database that contains the dropdown options from the Draw.io app then outputs the correct combination of dashed and dashPattern.\n\n        However in some cases dashed and dashpattern need to be set individually, such as when formatting from a style string. In that case, the setters for those two attributes will disable the other.\n\n        Returns:\n            str: The line style\n        \"\"\"\n        return self._line_pattern\n\n    @line_pattern.setter\n    def line_pattern(self, value):\n        if value in line_styles.keys():\n            self._line_pattern = value\n        else:\n            raise ValueError(\n                \"{0} is not an allowed value of line_pattern\".format(value)\n            )\n\n    @property\n    def dashed(self):\n        \"\"\"This is one of the properties that defines the line style. Along with dashPattern, it can be overriden by setting line_pattern or set directly.\n\n        Returns:\n            str: Whether the object stroke is dashed.\n        \"\"\"\n        if self._line_pattern is None:\n            return self._dashed\n        else:\n            return line_styles[self._line_pattern]\n\n    @dashed.setter\n    def dashed(self, value):\n        self._line_pattern = None\n        self._dashed = value\n\n    @property\n    def dashPattern(self):\n        \"\"\"This is one of the properties that defines the line style. Along with dashed, it can be overriden by setting line_pattern or set directly.\n\n        Returns:\n            str: What style the object stroke is dashed with.\n        \"\"\"\n        if self._line_pattern is None:\n            return self._dashed\n        else:\n            return line_styles[self._line_pattern]\n\n    @dashPattern.setter\n    def dashPattern(self, value):\n        self._line_pattern = None\n        self._dashPattern = value\n\n    ###########################################################\n    # Geometry properties\n    ###########################################################\n\n    @property\n    def width(self):\n        \"\"\"This property makes geometry.width available to the owning class for ease of access.\"\"\"\n        return self.geometry.width\n\n    @width.setter\n    def width(self, value):\n        self.geometry.width = value\n\n    @property\n    def height(self):\n        \"\"\"This property makes geometry.height available to the owning class for ease of access.\"\"\"\n        return self.geometry.height\n\n    @height.setter\n    def height(self, value):\n        self.geometry.height = value\n\n    # Position property\n    @property\n    def position(self):\n        \"\"\"The position of the object on the page. This is the top left corner. It's set with a tuple of ints, X and Y respectively.\n\n        (X, Y)\n\n        Returns:\n            tuple: A tuple of ints describing the top left corner position of the object\n        \"\"\"\n        return (self.geometry.x, self.geometry.y)\n\n    @position.setter\n    def position(self, value):\n        self.geometry.x = value[0]\n        self.geometry.y = value[1]\n\n    @property\n    def center_position(self):\n        \"\"\"The position of the object on the page. This is the center of the object. It's set with a tuple of ints, X and Y respectively.\n\n        (X, Y)\n\n        Returns:\n            tuple: A tuple of ints describing the center position of the object\n        \"\"\"\n        x = self.geometry.x + self.geometry.width / 2\n        y = self.geometry.y + self.geometry.height / 2\n        return (x, y)\n\n    @center_position.setter\n    def center_position(self, position):\n        self.geometry.x = position[0] - self.geometry.width / 2\n        self.geometry.y = position[1] - self.geometry.height / 2\n\n    ###########################################################\n    # Edge Tracking\n    ###########################################################\n\n    def add_out_edge(self, edge):\n        \"\"\"Add an edge out of the object. If an edge is created with this object set as the source this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object originating at this object\n        \"\"\"\n        self.out_edges.append(edge)\n\n    def remove_out_edge(self, edge):\n        \"\"\"Remove an edge out of the object. If an edge linked to this object has the source changed or removed this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object originating at this object\n        \"\"\"\n        self.out_edges.remove(edge)\n\n    def add_in_edge(self, edge):\n        \"\"\"Add an edge into the object. If an edge is created with this object set as the target this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object ending at this object\n        \"\"\"\n        self.in_edges.append(edge)\n\n    def remove_in_edge(self, edge):\n        \"\"\"Remove an edge into the object. If an edge linked to this object has the target changed or removed this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object ending at this object\n        \"\"\"\n        self.in_edges.remove(edge)\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n\n    @property\n    def xml(self):\n        \"\"\"\n        Returns the XML object for the Object: the opening tag with the style attributes, the value, and the closing tag.\n\n        Example:\n        <class_name attribute_name=attribute_value>Text in object</class_name>\n\n        Returns:\n            str: A single XML tag containing the object name, style attributes, and a closer.\n        \"\"\"\n        tag = self.xml_open_tag + \"\\n  \" + self.geometry.xml + \"\\n\" + self.xml_close_tag\n        return tag\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.center_position","title":"center_position property writable","text":"

The position of the object on the page. This is the center of the object. It's set with a tuple of ints, X and Y respectively.

(X, Y)

Returns:

Name Type Description tuple

A tuple of ints describing the center position of the object

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.dashPattern","title":"dashPattern property writable","text":"

This is one of the properties that defines the line style. Along with dashed, it can be overriden by setting line_pattern or set directly.

Returns:

Name Type Description str

What style the object stroke is dashed with.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.dashed","title":"dashed property writable","text":"

This is one of the properties that defines the line style. Along with dashPattern, it can be overriden by setting line_pattern or set directly.

Returns:

Name Type Description str

Whether the object stroke is dashed.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.height","title":"height property writable","text":"

This property makes geometry.height available to the owning class for ease of access.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.line_pattern","title":"line_pattern property writable","text":"

Two properties are enumerated together into line_pattern: dashed and dashPattern. line_pattern simplifies this with an external database that contains the dropdown options from the Draw.io app then outputs the correct combination of dashed and dashPattern.

However in some cases dashed and dashpattern need to be set individually, such as when formatting from a style string. In that case, the setters for those two attributes will disable the other.

Returns:

Name Type Description str

The line style

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.position","title":"position property writable","text":"

The position of the object on the page. This is the top left corner. It's set with a tuple of ints, X and Y respectively.

(X, Y)

Returns:

Name Type Description tuple

A tuple of ints describing the top left corner position of the object

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.width","title":"width property writable","text":"

This property makes geometry.width available to the owning class for ease of access.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.xml","title":"xml property","text":"

Returns the XML object for the Object: the opening tag with the style attributes, the value, and the closing tag.

Example: Text in object

Returns:

Name Type Description str

A single XML tag containing the object name, style attributes, and a closer.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.__init__","title":"__init__(value='', position=(0, 0), **kwargs)","text":"

A Object can be initialized with as many or as few of its styling attributes as is desired.

Parameters:

Name Type Description Default value str

The text to fill the object with. Defaults to \"\".

'' position tuple

The position of the object in pixels, in (X, Y). Defaults to (0, 0).

(0, 0)

Other Parameters:

Name Type Description width int

The width of the object in pixels. Defaults to 120.

height int

The height of the object in pixels. Defaults to 80.

template_object Object

Another object to copy the style_attributes from

rounded bool

Whether to round the corners of the shape

whiteSpace str

white space

fillColor str

The object fill color in a hex color code (#ffffff)

opacity (int

The object's opacity, 0-100

strokeColor

The object stroke color in a hex color code (#ffffff)

glass bool

Apply glass styling to the object

shadow bool

Add a shadow to the object

sketch bool

Add sketch styling to the object

comic bool

Add comic styling to the object

line_pattern str

The stroke style of the object.

Source code in src/drawpyo/diagram/objects.py
def __init__(self, value=\"\", position=(0, 0), **kwargs):\n    \"\"\"A Object can be initialized with as many or as few of its styling attributes as is desired.\n\n    Args:\n        value (str, optional): The text to fill the object with. Defaults to \"\".\n        position (tuple, optional): The position of the object in pixels, in (X, Y). Defaults to (0, 0).\n\n    Keyword Args:\n        width (int, optional): The width of the object in pixels. Defaults to 120.\n        height (int, optional): The height of the object in pixels. Defaults to 80.\n        template_object (Object, optional): Another object to copy the style_attributes from\n        aspect\n        rounded (bool, optional): Whether to round the corners of the shape\n        whiteSpace (str, optional): white space\n        fillColor (str, optional): The object fill color in a hex color code (#ffffff)\n        opacity  (int, optional): The object's opacity, 0-100\n        strokeColor: The object stroke color in a hex color code (#ffffff)\n        glass (bool, optional): Apply glass styling to  the object\n        shadow (bool, optional): Add a shadow to the object\n        sketch (bool, optional): Add sketch styling to the object\n        comic (bool, optional): Add comic styling to the object\n        line_pattern (str, optional): The stroke style of the object.\n    \"\"\"\n    super().__init__(**kwargs)\n    self._style_attributes = [\n        \"whiteSpace\",\n        \"rounded\",\n        \"fillColor\",\n        \"strokeColor\",\n        \"glass\",\n        \"shadow\",\n        \"comic\",\n        \"sketch\",\n        \"opacity\",\n        \"dashed\",\n    ]\n\n    # Geometry\n    self.geometry = Geometry(parent_object=self)\n    self.position = kwargs.get(\"position\", (0, 0))\n    self.width = kwargs.get(\"width\", 120)\n    self.height = kwargs.get(\"height\", 80)\n    self.vertex = kwargs.get(\"vertex\", 1)\n\n    # TODO enumerate to fixed\n    self.aspect = kwargs.get(\"aspect\", None)\n\n    # Content\n    self.text_format = kwargs.get(\"text_format\", TextFormat())\n    self.value = value\n\n    # Style\n    self.baseStyle = kwargs.get(\"baseStyle\", None)\n\n    self.rounded = kwargs.get(\"rounded\", 0)\n    self.whiteSpace = kwargs.get(\"whiteSpace\", \"wrap\")\n    self.opacity = kwargs.get(\"opacity\", None)\n    self.strokeColor = kwargs.get(\"strokeColor\", None)\n    self.fillColor = kwargs.get(\"fillColor\", None)\n    self.glass = kwargs.get(\"glass\", None)\n    self.shadow = kwargs.get(\"shadow\", None)\n    self.comic = kwargs.get(\"comic\", None)\n    self.sketch = kwargs.get(\"sketch\", None)\n    self.line_pattern = kwargs.get(\"line_pattern\", \"solid\")\n\n    self.out_edges = kwargs.get(\"out_edges\", [])\n    self.in_edges = kwargs.get(\"in_edges\", [])\n\n    self.xml_class = \"mxCell\"\n\n    if \"template_object\" in kwargs:\n        self.template_object = kwargs.get(\"template_object\")\n        self._apply_style_from_template(self.template_object)\n        self.width = self.template_object.width\n        self.height = self.template_object.height\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.add_in_edge","title":"add_in_edge(edge)","text":"

Add an edge into the object. If an edge is created with this object set as the target this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object ending at this object

required Source code in src/drawpyo/diagram/objects.py
def add_in_edge(self, edge):\n    \"\"\"Add an edge into the object. If an edge is created with this object set as the target this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object ending at this object\n    \"\"\"\n    self.in_edges.append(edge)\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.add_out_edge","title":"add_out_edge(edge)","text":"

Add an edge out of the object. If an edge is created with this object set as the source this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object originating at this object

required Source code in src/drawpyo/diagram/objects.py
def add_out_edge(self, edge):\n    \"\"\"Add an edge out of the object. If an edge is created with this object set as the source this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object originating at this object\n    \"\"\"\n    self.out_edges.append(edge)\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.create_from_library","title":"create_from_library(library, obj_name) classmethod","text":"

This function generates a Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.

Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. However, the styling in the library will overwrite that formatting.

Parameters:

Name Type Description Default library str or dict

The library containing the object

required obj_name str

The name of the object in the library to generate

required

Returns:

Name Type Description Object

An object with the style from the library

Source code in src/drawpyo/diagram/objects.py
@classmethod\ndef create_from_library(cls, library, obj_name):\n    \"\"\"This function generates a Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n    Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. However, the styling in the library will overwrite that formatting.\n\n    Args:\n        library (str or dict): The library containing the object\n        obj_name (str): The name of the object in the library to generate\n\n    Returns:\n        Object: An object with the style from the library\n    \"\"\"\n    new_obj = cls()\n    new_obj.format_as_library_object(library, obj_name)\n    return new_obj\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.create_from_style_string","title":"create_from_style_string(style_string) classmethod","text":"

Objects can be instantiated from a style string. These strings are most easily found in the Draw.io app, by styling an object as desired then right-clicking and selecting \"Edit Style\". Copying that text into this function will generate an object styled the same.

Parameters:

Name Type Description Default style_string str

A Draw.io generated style string.

required

Returns:

Name Type Description Object

An object formatted with the style string

Source code in src/drawpyo/diagram/objects.py
@classmethod\ndef create_from_style_string(cls, style_string):\n    \"\"\"Objects can be instantiated from a style string. These strings are most easily found in the Draw.io app, by styling an object as desired then right-clicking and selecting \"Edit Style\". Copying that text into this function will generate an object styled the same.\n\n    Args:\n        style_string (str): A Draw.io generated style string.\n\n    Returns:\n        Object: An object formatted with the style string\n    \"\"\"\n    cls.apply_style_from_string(style_string)\n    return cls\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.create_from_template_object","title":"create_from_template_object(template_object, value=None, position=None, page=None) classmethod","text":"

Object can be instantiated from another object. This will initialize the Object with the same formatting, then set a new position and value.

Parameters:

Name Type Description Default template_object Object

Another drawpyo Object to use as a template

required value str

The text contents of the object. Defaults to None.

None position tuple

The position where the object should be placed. Defaults to (0, 0).

None page Page

The Page object to place the object on. Defaults to None.

None

Returns:

Name Type Description Object

The newly created object

Source code in src/drawpyo/diagram/objects.py
@classmethod\ndef create_from_template_object(\n    cls, template_object, value=None, position=None, page=None\n):\n    \"\"\"Object can be instantiated from another object. This will initialize the Object with the same formatting, then set a new position and value.\n\n    Args:\n        template_object (Object): Another drawpyo Object to use as a template\n        value (str, optional): The text contents of the object. Defaults to None.\n        position (tuple, optional): The position where the object should be placed. Defaults to (0, 0).\n        page (Page, optional): The Page object to place the object on. Defaults to None.\n\n    Returns:\n        Object: The newly created object\n    \"\"\"\n    new_obj = cls(\n        value=value,\n        page=page,\n        width=template_object.width,\n        height=template_object.height,\n        template_object=template_object,\n    )\n    if position is not None:\n        new_obj.position = position\n    if value is not None:\n        new_obj.value = value\n    return new_obj\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.format_as_library_object","title":"format_as_library_object(library, obj_name)","text":"

This function applies the style from a library to an existing object. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.

Parameters:

Name Type Description Default library str or dict

The library containing the object

required obj_name str

The name of the object in the library to generate

required Source code in src/drawpyo/diagram/objects.py
def format_as_library_object(self, library, obj_name):\n    \"\"\"This function applies the style from a library to an existing object. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n    Args:\n        library (str or dict): The library containing the object\n        obj_name (str): The name of the object in the library to generate\n    \"\"\"\n    if type(library) == str:\n        if library in base_libraries:\n            library_dict = base_libraries[library]\n            if obj_name in library_dict:\n                obj_dict = library_dict[obj_name]\n                self.apply_attribute_dict(obj_dict)\n            else:\n                raise ValueError(\n                    \"Object {0} not in Library {1}\".format(obj_name, library)\n                )\n        else:\n            raise ValueError(\"Library {0} not in base_libraries\".format(library))\n    elif type(library) == dict:\n        obj_dict = library[obj_name]\n        self.apply_attribute_dict(obj_dict)\n    else:\n        raise ValueError(\"Unparseable libary passed in.\")\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.remove_in_edge","title":"remove_in_edge(edge)","text":"

Remove an edge into the object. If an edge linked to this object has the target changed or removed this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object ending at this object

required Source code in src/drawpyo/diagram/objects.py
def remove_in_edge(self, edge):\n    \"\"\"Remove an edge into the object. If an edge linked to this object has the target changed or removed this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object ending at this object\n    \"\"\"\n    self.in_edges.remove(edge)\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.remove_out_edge","title":"remove_out_edge(edge)","text":"

Remove an edge out of the object. If an edge linked to this object has the source changed or removed this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object originating at this object

required Source code in src/drawpyo/diagram/objects.py
def remove_out_edge(self, edge):\n    \"\"\"Remove an edge out of the object. If an edge linked to this object has the source changed or removed this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object originating at this object\n    \"\"\"\n    self.out_edges.remove(edge)\n
"},{"location":"api/objects/#group","title":"Group","text":""},{"location":"api/objects/#src.drawpyo.diagram.objects.Group","title":"src.drawpyo.diagram.objects.Group","text":"

This class allows objects to be grouped together. It then provides a number of geometry functions and properties to move the entire group around.

Currently this object doesn't replicate any of the functionality of groups in the Draw.io app but it may be extended to have that capability in the future.

Source code in src/drawpyo/diagram/objects.py
class Group:\n    \"\"\"This class allows objects to be grouped together. It then provides a number of geometry functions and properties to move the entire group around.\n\n    Currently this object doesn't replicate any of the functionality of groups in the Draw.io app but it may be extended to have that capability in the future.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        self.objects = kwargs.get(\"objects\", [])\n        self.geometry = Geometry()\n\n    def add_object(self, object):\n        \"\"\"Adds one or more objects to the group and updates the geometry of the group.\n\n        Args:\n            object (Object or list): Object or list of objects to be added to the group\n        \"\"\"\n        if not isinstance(object, list):\n            object = [object]\n        for o in object:\n            if o not in self.objects:\n                self.objects.append(o)\n        self.update_geometry()\n\n    def update_geometry(self):\n        \"\"\"Update the geometry of the group. This includes the left and top coordinates and the width and height of the entire group.\"\"\"\n        self.geometry.x = self.left\n        self.geometry.y = self.top\n        self.geometry.width = self.width\n        self.geometry.height = self.height\n\n    ###########################################################\n    # Passive properties\n    ###########################################################\n\n    @property\n    def left(self):\n        \"\"\"The leftmost X-coordinate of the objects in the group\n\n        Returns:\n            int: Left edge of the group\n        \"\"\"\n        return min([obj.geometry.x for obj in self.objects])\n\n    @property\n    def right(self):\n        \"\"\"The rightmost X-coordinate of the objects in the group\n\n        Returns:\n            int: Right edge of the group\n        \"\"\"\n        return max([obj.geometry.x + obj.geometry.width for obj in self.objects])\n\n    @property\n    def top(self):\n        \"\"\"The topmost Y-coordinate of the objects in the group\n\n        Returns:\n            int: Top edge of the group\n        \"\"\"\n        return min([obj.geometry.y for obj in self.objects])\n\n    @property\n    def bottom(self):\n        \"\"\"The bottommost Y-coordinate of the objects in the group\n\n        Returns:\n            int: The bottom edge of the group\n        \"\"\"\n        return max([obj.geometry.y + obj.geometry.height for obj in self.objects])\n\n    @property\n    def width(self):\n        \"\"\"The width of all the objects in the group\n\n        Returns:\n            int: Width of the group\n        \"\"\"\n        return self.right - self.left\n\n    @property\n    def height(self):\n        \"\"\"The height of all the objects in the group\n\n        Returns:\n            int: Height of the group\n        \"\"\"\n        return self.bottom - self.top\n\n    @property\n    def size(self):\n        \"\"\"The size of the group. Returns a tuple of ints, with the width and height.\n\n        Returns:\n            tuple: A tuple of ints (width, height)\n        \"\"\"\n        return (self.width, self.height)\n\n    ###########################################################\n    # Position properties\n    ###########################################################\n\n    @property\n    def center_position(self):\n        \"\"\"The center position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.\n\n        Returns:\n            tuple: A tuple of ints (X, Y)\n        \"\"\"\n        return (self.left + self.width / 2, self.top + self.height / 2)\n\n    @center_position.setter\n    def center_position(self, new_center):\n        current_center = (\n            self.left + self.width / 2,\n            self.top + self.height / 2,\n        )\n        delta_x = new_center[0] - current_center[0]\n        delta_y = new_center[1] - current_center[1]\n        for obj in self.objects:\n            obj.position = (obj.geometry.x + delta_x, obj.geometry.y + delta_y)\n        self.update_geometry()\n\n    @property\n    def position(self):\n        \"\"\"The top left position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.\n\n        Returns:\n            tuple: A tuple of ints (X, Y)\n        \"\"\"\n        return (self.left, self.top)\n\n    @position.setter\n    def position(self, new_position):\n        current_position = (self.left, self.top)\n        delta_x = new_position[0] - current_position[0]\n        delta_y = new_position[1] - current_position[1]\n        for obj in self.objects:\n            obj.position = (obj.geometry.x + delta_x, obj.geometry.y + delta_y)\n        self.update_geometry()\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.bottom","title":"bottom property","text":"

The bottommost Y-coordinate of the objects in the group

Returns:

Name Type Description int

The bottom edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.center_position","title":"center_position property writable","text":"

The center position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.

Returns:

Name Type Description tuple

A tuple of ints (X, Y)

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.height","title":"height property","text":"

The height of all the objects in the group

Returns:

Name Type Description int

Height of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.left","title":"left property","text":"

The leftmost X-coordinate of the objects in the group

Returns:

Name Type Description int

Left edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.position","title":"position property writable","text":"

The top left position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.

Returns:

Name Type Description tuple

A tuple of ints (X, Y)

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.right","title":"right property","text":"

The rightmost X-coordinate of the objects in the group

Returns:

Name Type Description int

Right edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.size","title":"size property","text":"

The size of the group. Returns a tuple of ints, with the width and height.

Returns:

Name Type Description tuple

A tuple of ints (width, height)

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.top","title":"top property","text":"

The topmost Y-coordinate of the objects in the group

Returns:

Name Type Description int

Top edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.width","title":"width property","text":"

The width of all the objects in the group

Returns:

Name Type Description int

Width of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.add_object","title":"add_object(object)","text":"

Adds one or more objects to the group and updates the geometry of the group.

Parameters:

Name Type Description Default object Object or list

Object or list of objects to be added to the group

required Source code in src/drawpyo/diagram/objects.py
def add_object(self, object):\n    \"\"\"Adds one or more objects to the group and updates the geometry of the group.\n\n    Args:\n        object (Object or list): Object or list of objects to be added to the group\n    \"\"\"\n    if not isinstance(object, list):\n        object = [object]\n    for o in object:\n        if o not in self.objects:\n            self.objects.append(o)\n    self.update_geometry()\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.update_geometry","title":"update_geometry()","text":"

Update the geometry of the group. This includes the left and top coordinates and the width and height of the entire group.

Source code in src/drawpyo/diagram/objects.py
def update_geometry(self):\n    \"\"\"Update the geometry of the group. This includes the left and top coordinates and the width and height of the entire group.\"\"\"\n    self.geometry.x = self.left\n    self.geometry.y = self.top\n    self.geometry.width = self.width\n    self.geometry.height = self.height\n
"},{"location":"api/page/","title":"Page","text":""},{"location":"api/page/#src.drawpyo.page.Page","title":"src.drawpyo.page.Page","text":"

This class defines a page in a Draw.io document. It contains a list of objects and a reference to the File it's in as well as formatting attributes.

Source code in src/drawpyo/page.py
class Page:\n    \"\"\"\n    This class defines a page in a Draw.io document. It contains a list of objects and a reference to the File it's in as well as formatting attributes.\n    \"\"\"\n\n    def __init__(self, file=None, **kwargs):\n        super().__init__()\n        self.id = id(self)\n\n        self.file = file\n        self.objects = kwargs.get(\"objects\", [])\n\n        # There are two empty top level objects in every Draw.io diagram\n        self.objects.append(XMLBase(id=0, xml_class=\"mxCell\"))\n        self.objects.append(XMLBase(id=1, xml_class=\"mxCell\", xml_parent=0))\n\n        # Properties\n\n        if self.file is not None:\n            page_num = len(self.file.pages)\n        else:\n            page_num = 1\n        self.name = kwargs.get(\"name\", f\"Page-{page_num}\")\n        self.page_num = kwargs.get(\"page_num\", page_num)\n\n        self.dx = kwargs.get(\"dx\", 2037)\n        self.dy = kwargs.get(\"dy\", 830)\n        self.grid = kwargs.get(\"grid\", 1)\n        self.grid_size = kwargs.get(\"grid_size\", 10)\n        self.guides = kwargs.get(\"guides\", 1)\n        self.tooltips = kwargs.get(\"tooltips\", 1)\n        self.connect = kwargs.get(\"connect\", 1)\n        self.arrows = kwargs.get(\"arrows\", 1)\n        self.fold = kwargs.get(\"fold\", 1)\n        self.scale = kwargs.get(\"scale\", 1)\n        self.width = kwargs.get(\"width\", 850)\n        self.height = kwargs.get(\"height\", 1100)\n        self.math = kwargs.get(\"math\", 0)\n        self.shadow = kwargs.get(\"shadow\", 0)\n\n        # In the Draw.io file format, each page is actually three nested XML\n        # tags. These are defined as XMLBase subclasses below\n        self.diagram = Diagram(name=self.name)\n        self.mxGraph = mxGraph(page=self)\n        self.root = Root()\n\n    def __repr__(self):\n        return f\"drawpyo Page - {self.name}\"\n\n    def remove(self):\n        \"\"\"This function removes the Page from its linked File object then deletes itself.\"\"\"\n        if self.file is not None:\n            self.file.remove_page(self)\n        del self\n\n    def add_object(self, obj):\n        if obj not in self.objects:\n            self.objects.append(obj)\n\n    def remove_object(self, obj):\n        self.objects.remove(obj)\n\n    @property\n    def file(self):\n        return self._file\n\n    @file.setter\n    def file(self, f):\n        if f is not None:\n            f.add_page(self)\n        self._file = f\n\n    @file.deleter\n    def file(self):\n        self._file.remove_page(self)\n        self._file = None\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n    @property\n    def xml(self):\n        xml_string = self.xml_open_tag\n        for obj in self.objects:\n            xml_string = xml_string + \"\\n        \" + obj.xml\n        xml_string = xml_string + \"\\n\" + self.xml_close_tag\n        return xml_string\n\n    @property\n    def xml_open_tag(self):\n        tag = (\n            self.diagram.xml_open_tag\n            + \"\\n    \"\n            + self.mxGraph.xml_open_tag\n            + \"\\n      \"\n            + self.root.xml_open_tag\n        )\n        return tag\n\n    @property\n    def xml_close_tag(self):\n        tag = (\n            \"      \"\n            + self.root.xml_close_tag\n            + \"\\n    \"\n            + self.mxGraph.xml_close_tag\n            + \"\\n  \"\n            + self.diagram.xml_close_tag\n        )\n        return tag\n
"},{"location":"api/page/#src.drawpyo.page.Page.remove","title":"remove()","text":"

This function removes the Page from its linked File object then deletes itself.

Source code in src/drawpyo/page.py
def remove(self):\n    \"\"\"This function removes the Page from its linked File object then deletes itself.\"\"\"\n    if self.file is not None:\n        self.file.remove_page(self)\n    del self\n
"},{"location":"api/text_format/","title":"Text Format","text":""},{"location":"api/text_format/#textformat","title":"TextFormat","text":""},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat","title":"src.drawpyo.diagram.text_format.TextFormat","text":"

Bases: DiagramBase

The TextFormat class handles all of the formatting specifically around a text box or label.

Source code in src/drawpyo/diagram/text_format.py
class TextFormat(DiagramBase):\n    \"\"\"The TextFormat class handles all of the formatting specifically around a text box or label.\"\"\"\n\n    def __init__(self, **kwargs):\n        \"\"\"TextFormat objects can be initialized with no properties or any of what's listed below:\n\n        Keyword Args:\n            fontColor (int, optional): The color of the text in the object (#ffffff)\n            fontFamily (str, optional): The typeface of the text in the object (see Draw.io for available fonts)\n            fontSize (int, optional): The size of the text in the object in points\n            align (str, optional): The horizontal alignment of the text in the object ('left', 'center', or 'right')\n            verticalAlign (str, optional): The vertical alignment of the text in the object ('top', 'middle', 'bottom')\n            textOpacity (int, optional): The opacity of the text in the object\n            direction (str, optional): The direction to print the text ('vertical', 'horizontal')\n            bold (bool, optional): Whether the text in the object should be bold\n            italic (bool, optional): Whether the text in the object should be italic\n            underline (bool, optional): Whether the text in the object should be underlined\n            labelPosition (str, optional): The position of the object label ('left', 'center', or 'right')\n            labelBackgroundColor (str, optional): The background color of the object label (#ffffff)\n            labelBorderColor (str, optional): The border color of the object label (#ffffff)\n            fomrattedText (bool, optional): Whether to render the text as HTML formatted or not\n\n        \"\"\"\n        super().__init__(**kwargs)\n        self.fontFamily = kwargs.get(\"fontFamily\", None)\n        self.fontSize = kwargs.get(\"fontSize\", None)\n        self.fontColor = kwargs.get(\"fontColor\", None)\n        self.labelBorderColor = kwargs.get(\"labelBorderColor\", None)\n        self.labelBackgroundColor = kwargs.get(\"labelBackgroundColor\", None)\n        self.labelPosition = kwargs.get(\"labelPosition\", None)\n        self.textShadow = kwargs.get(\"textShadow\", None)\n        self.textOpacity = kwargs.get(\"textOpacity\", None)\n        self.spacingTop = kwargs.get(\"spacingTop\", None)\n        self.spacingLeft = kwargs.get(\"spacingLeft\", None)\n        self.spacingBottom = kwargs.get(\"spacingBottom\", None)\n        self.spacingRight = kwargs.get(\"spacingRight\", None)\n        self.spacing = kwargs.get(\"spacing\", None)\n        self.align = kwargs.get(\"align\", None)\n        self.verticalAlign = kwargs.get(\"verticalAlign\", None)\n        # These need to be enumerated\n        self.direction = kwargs.get(\"direction\", None)\n        # This is actually horizontal. 0 means vertical text, 1 or not present\n        # means horizontal\n        self.formattedText = kwargs.get(\n            \"formattedText\", None\n        )  # prints in the style string as html\n        self.bold = kwargs.get(\"bold\", False)\n        self.italic = kwargs.get(\"italic\", False)\n        self.underline = kwargs.get(\"underline\", False)\n\n        self._style_attributes = [\n            \"html\",\n            \"fontFamily\",\n            \"fontSize\",\n            \"fontColor\",\n            \"labelBorderColor\",\n            \"labelBackgroundColor\",\n            \"labelPosition\",\n            \"textShadow\",\n            \"textOpacity\",\n            \"spacingTop\",\n            \"spacingLeft\",\n            \"spacingBottom\",\n            \"spacingRight\",\n            \"spacing\",\n            \"align\",\n            \"verticalAlign\",\n            \"horizontal\",\n        ]\n\n    @property\n    def formattedText(self):\n        \"\"\"formattedText wraps the Draw.io style attribute 'html'. This controls whether the text is rendered with HTML attributes or as plain text.\"\"\"\n        return self.html\n\n    @formattedText.setter\n    def formattedText(self, value):\n        self.html = value\n\n    @formattedText.deleter\n    def formattedText(self, value):\n        self.html = None\n\n    # The direction of the text is encoded as 'horizontal' in Draw.io. This is\n    # unintuitive so I provided a direction alternate syntax.\n    @property\n    def horizontal(self):\n        return directions[self._direction]\n\n    @horizontal.setter\n    def horizontal(self, value):\n        if value in directions_inv.keys():\n            self._direction = directions_inv[value]\n        else:\n            raise ValueError(\"{0} is not an allowed value of horizontal\".format(value))\n\n    @property\n    def directions(self):\n        \"\"\"The direction controls the direction of the text and can be either horizontal or vertical.\"\"\"\n        return directions\n\n    @property\n    def direction(self):\n        return self._direction\n\n    @direction.setter\n    def direction(self, value):\n        if value in directions.keys():\n            self._direction = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of direction\".format(value))\n\n    @property\n    def font_style(self):\n        \"\"\"The font_style is a numeric format that corresponds to a combination of three other attributes: bold, italic, and underline. Any combination of them can be true.\"\"\"\n        bld = self.bold\n        ita = self.italic\n        unl = self.underline\n\n        # 0 = normal\n        # 1 = bold\n        # 2 = italic\n        # 3 = bold and italic\n        # 4 = underline\n        # 5 = bold and underlined\n        # 6 = italic and underlined\n        # 7 = bolt, italic, and underlined\n\n        if not bld and not ita and not unl:\n            return 0\n        elif bld and not ita and not unl:\n            return 1\n        elif not bld and ita and not unl:\n            return 2\n        elif bld and ita and not unl:\n            return 3\n        elif not bld and not ita and unl:\n            return 4\n        elif bld and not ita and unl:\n            return 5\n        elif not bld and ita and unl:\n            return 6\n        elif bld and ita and unl:\n            return 7\n
"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.directions","title":"directions property","text":"

The direction controls the direction of the text and can be either horizontal or vertical.

"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.font_style","title":"font_style property","text":"

The font_style is a numeric format that corresponds to a combination of three other attributes: bold, italic, and underline. Any combination of them can be true.

"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.formattedText","title":"formattedText deletable property writable","text":"

formattedText wraps the Draw.io style attribute 'html'. This controls whether the text is rendered with HTML attributes or as plain text.

"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.__init__","title":"__init__(**kwargs)","text":"

TextFormat objects can be initialized with no properties or any of what's listed below:

Other Parameters:

Name Type Description fontColor int

The color of the text in the object (#ffffff)

fontFamily str

The typeface of the text in the object (see Draw.io for available fonts)

fontSize int

The size of the text in the object in points

align str

The horizontal alignment of the text in the object ('left', 'center', or 'right')

verticalAlign str

The vertical alignment of the text in the object ('top', 'middle', 'bottom')

textOpacity int

The opacity of the text in the object

direction str

The direction to print the text ('vertical', 'horizontal')

bold bool

Whether the text in the object should be bold

italic bool

Whether the text in the object should be italic

underline bool

Whether the text in the object should be underlined

labelPosition str

The position of the object label ('left', 'center', or 'right')

labelBackgroundColor str

The background color of the object label (#ffffff)

labelBorderColor str

The border color of the object label (#ffffff)

fomrattedText bool

Whether to render the text as HTML formatted or not

Source code in src/drawpyo/diagram/text_format.py
def __init__(self, **kwargs):\n    \"\"\"TextFormat objects can be initialized with no properties or any of what's listed below:\n\n    Keyword Args:\n        fontColor (int, optional): The color of the text in the object (#ffffff)\n        fontFamily (str, optional): The typeface of the text in the object (see Draw.io for available fonts)\n        fontSize (int, optional): The size of the text in the object in points\n        align (str, optional): The horizontal alignment of the text in the object ('left', 'center', or 'right')\n        verticalAlign (str, optional): The vertical alignment of the text in the object ('top', 'middle', 'bottom')\n        textOpacity (int, optional): The opacity of the text in the object\n        direction (str, optional): The direction to print the text ('vertical', 'horizontal')\n        bold (bool, optional): Whether the text in the object should be bold\n        italic (bool, optional): Whether the text in the object should be italic\n        underline (bool, optional): Whether the text in the object should be underlined\n        labelPosition (str, optional): The position of the object label ('left', 'center', or 'right')\n        labelBackgroundColor (str, optional): The background color of the object label (#ffffff)\n        labelBorderColor (str, optional): The border color of the object label (#ffffff)\n        fomrattedText (bool, optional): Whether to render the text as HTML formatted or not\n\n    \"\"\"\n    super().__init__(**kwargs)\n    self.fontFamily = kwargs.get(\"fontFamily\", None)\n    self.fontSize = kwargs.get(\"fontSize\", None)\n    self.fontColor = kwargs.get(\"fontColor\", None)\n    self.labelBorderColor = kwargs.get(\"labelBorderColor\", None)\n    self.labelBackgroundColor = kwargs.get(\"labelBackgroundColor\", None)\n    self.labelPosition = kwargs.get(\"labelPosition\", None)\n    self.textShadow = kwargs.get(\"textShadow\", None)\n    self.textOpacity = kwargs.get(\"textOpacity\", None)\n    self.spacingTop = kwargs.get(\"spacingTop\", None)\n    self.spacingLeft = kwargs.get(\"spacingLeft\", None)\n    self.spacingBottom = kwargs.get(\"spacingBottom\", None)\n    self.spacingRight = kwargs.get(\"spacingRight\", None)\n    self.spacing = kwargs.get(\"spacing\", None)\n    self.align = kwargs.get(\"align\", None)\n    self.verticalAlign = kwargs.get(\"verticalAlign\", None)\n    # These need to be enumerated\n    self.direction = kwargs.get(\"direction\", None)\n    # This is actually horizontal. 0 means vertical text, 1 or not present\n    # means horizontal\n    self.formattedText = kwargs.get(\n        \"formattedText\", None\n    )  # prints in the style string as html\n    self.bold = kwargs.get(\"bold\", False)\n    self.italic = kwargs.get(\"italic\", False)\n    self.underline = kwargs.get(\"underline\", False)\n\n    self._style_attributes = [\n        \"html\",\n        \"fontFamily\",\n        \"fontSize\",\n        \"fontColor\",\n        \"labelBorderColor\",\n        \"labelBackgroundColor\",\n        \"labelPosition\",\n        \"textShadow\",\n        \"textOpacity\",\n        \"spacingTop\",\n        \"spacingLeft\",\n        \"spacingBottom\",\n        \"spacingRight\",\n        \"spacing\",\n        \"align\",\n        \"verticalAlign\",\n        \"horizontal\",\n    ]\n
"},{"location":"api/tree_diagram/nodeobject/","title":"NodeObject","text":""},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject","title":"src.drawpyo.diagram_types.tree.NodeObject","text":"

Bases: Object

This class defines one of the nodes on a tree graph. It inherits from Object and performs the same in most regards. It also tracks the tree-specific parameters like the tree, children, parent, etc.

Source code in src/drawpyo/diagram_types/tree.py
class NodeObject(Object):\n    \"\"\"This class defines one of the nodes on a tree graph. It inherits from Object and performs the same in most regards. It also tracks the tree-specific parameters like the tree, children, parent, etc.\"\"\"\n\n    def __init__(self, tree=None, **kwargs):\n        \"\"\"The NodeObject should be instantiated with an owning tree object. A NodeObject can only have a single parent but can have any number of children.\n\n        Args:\n            tree (TreeDiagram, optional): The owning tree diagram. Defaults to None.\n\n        Keyword Args:\n            children (list, optional): A list of other NodeObjects\n            parent (list, optional): The parent NodeObject\n        \"\"\"\n        super().__init__(**kwargs)\n        self.tree = tree\n        self.children = kwargs.get(\"children\", [])\n        self.parent = kwargs.get(\"parent\", None)\n        self.peers = []\n        # self.level = kwargs.get(\"level\", None)\n        # self.peers = kwargs.get(\"peers\", [])\n\n    @property\n    def tree(self):\n        \"\"\"The TreeDiagram that owns the NodeObject\n\n        Returns:\n            TreeDiagram\n        \"\"\"\n        return self._tree\n\n    @tree.setter\n    def tree(self, value):\n        if value is not None:\n            value.add_object(self)\n        self._tree = value\n\n    @property\n    def parent(self):\n        \"\"\"The parent NodeObject\n\n        Returns:\n            NodeObject\n        \"\"\"\n        return self._parent\n\n    @parent.setter\n    def parent(self, value):\n        if value is not None:\n            value.children.append(self)\n        self._parent = value\n\n    def add_child(self, obj):\n        \"\"\"Add a new child to the object\n\n        Args:\n            obj (NodeObject)\n        \"\"\"\n        self.children.append(obj)\n        obj._parent = self\n\n    def add_peer(self, obj):\n        if obj not in self.peers:\n            self.peers.append(obj)\n        if self not in obj.peers:\n            obj.peers.append(self)\n\n    @property\n    def size_of_level(self):\n        \"\"\"The height or the width of the level, depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.geometry.height\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.geometry.width\n\n    @property\n    def size_in_level(self):\n        \"\"\"The size of the object within its level, either its width or height depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.geometry.width\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.geometry.height\n
"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.parent","title":"parent property writable","text":"

The parent NodeObject

Returns:

Type Description

NodeObject

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.size_in_level","title":"size_in_level property","text":"

The size of the object within its level, either its width or height depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.size_of_level","title":"size_of_level property","text":"

The height or the width of the level, depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.tree","title":"tree property writable","text":"

The TreeDiagram that owns the NodeObject

Returns:

Type Description

TreeDiagram

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.__init__","title":"__init__(tree=None, **kwargs)","text":"

The NodeObject should be instantiated with an owning tree object. A NodeObject can only have a single parent but can have any number of children.

Parameters:

Name Type Description Default tree TreeDiagram

The owning tree diagram. Defaults to None.

None

Other Parameters:

Name Type Description children list

A list of other NodeObjects

parent list

The parent NodeObject

Source code in src/drawpyo/diagram_types/tree.py
def __init__(self, tree=None, **kwargs):\n    \"\"\"The NodeObject should be instantiated with an owning tree object. A NodeObject can only have a single parent but can have any number of children.\n\n    Args:\n        tree (TreeDiagram, optional): The owning tree diagram. Defaults to None.\n\n    Keyword Args:\n        children (list, optional): A list of other NodeObjects\n        parent (list, optional): The parent NodeObject\n    \"\"\"\n    super().__init__(**kwargs)\n    self.tree = tree\n    self.children = kwargs.get(\"children\", [])\n    self.parent = kwargs.get(\"parent\", None)\n    self.peers = []\n
"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.add_child","title":"add_child(obj)","text":"

Add a new child to the object

Source code in src/drawpyo/diagram_types/tree.py
def add_child(self, obj):\n    \"\"\"Add a new child to the object\n\n    Args:\n        obj (NodeObject)\n    \"\"\"\n    self.children.append(obj)\n    obj._parent = self\n
"},{"location":"api/tree_diagram/treediagram/","title":"TreeDiagram","text":""},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram","title":"src.drawpyo.diagram_types.tree.TreeDiagram","text":"

The TreeDiagram contains a File object, a Page object, and all the NodeObjects in the tree.

Source code in src/drawpyo/diagram_types/tree.py
class TreeDiagram:\n    \"\"\"The TreeDiagram contains a File object, a Page object, and all the NodeObjects in the tree.\"\"\"\n\n    def __init__(self, **kwargs):\n        \"\"\"The TreeDiagram initiates its own File and Page objects. There are a number of formatting parameters that can be set to fine tune the rendering of the tree.\n\n        Keyword Args:\n            direction (str, optional): Direction that the tree grows from the root. Options are 'up', 'down', 'left', and 'right'. Defaults to 'down'.\n            link_style (str, optional): Connection style of the edges. Options are 'orthogonal', 'straight', and 'curved'. Defaults to 'orthogonal'.\n            level_spacing (int, optional): Spacing in pixels between levels. Defaults to 60.\n            item_spacing (int, optional): Spacing in pixels between groups within a level. Defaults to 15.\n            padding (int, optional): Spacing in pixels between objects within a group. Defaults to 10.\n            file_name (str, optional): The name of the tree diagram.\n            file_path (str, optional): The path where the tree diagram should be saved.\n        \"\"\"\n        # formatting\n        self.level_spacing = kwargs.get(\"level_spacing\", 60)\n        self.item_spacing = kwargs.get(\"item_spacing\", 15)\n        self.group_spacing = kwargs.get(\"group_spacing\", 30)\n        self.direction = kwargs.get(\"direction\", \"down\")\n        self.link_style = kwargs.get(\"link_style\", \"orthogonal\")\n        self.padding = kwargs.get(\"padding\", 10)\n\n        # Set up the File and Page objects\n        self.file = File()\n        self.file_name = kwargs.get(\"file_name\", \"Heirarchical Diagram.drawio\")\n        self.file_path = kwargs.get(\"file_path\", r\"C:/\")\n        self.page = Page(file=self.file)\n\n        # Set up object and level lists\n        self.objects = []\n        self.links = []\n\n    ###########################################################\n    # properties\n    ###########################################################\n    # These setters and getters keep the file name and file path within the\n    # File object\n    @property\n    def file_name(self):\n        \"\"\"The file name of the TreeDiagram\n\n        Returns:\n            str\n        \"\"\"\n        return self.file.file_name\n\n    @file_name.setter\n    def file_name(self, fn):\n        self.file.file_name = fn\n\n    @property\n    def file_path(self):\n        \"\"\"The file path where the TreeDiagram will be saved\n\n        Returns:\n            str\n        \"\"\"\n        return self.file.file_path\n\n    @file_path.setter\n    def file_path(self, fn):\n        self.file.file_path = fn\n\n    # These setters enforce the options for direction and link_style.\n    @property\n    def direction(self):\n        \"\"\"The direction the tree diagram should grow. Options are \"up\", \"down\", \"left\", or \"right\".\n\n        Returns:\n            str\n        \"\"\"\n        return self._direction\n\n    @direction.setter\n    def direction(self, d):\n        directions = [\"up\", \"down\", \"left\", \"right\"]\n        if d in directions:\n            self._direction = d\n        else:\n            raise ValueError(\n                \"{0} is not a valid entry for direction. Must be {1}.\".format(\n                    d, \", \".join(directions)\n                )\n            )\n\n    ###########################################################\n    # Formatting Properties\n    ###########################################################\n\n    @property\n    def origin(self):\n        \"\"\"The origin points of the TreeDiagram. This is the point where the center of the top level of the TreeDiagram starts from. By default it's set to the top center of an edge of the page. Which edge depends on the direction of the tree diagram.\n\n        Returns:\n            tuple: A tuple of ints\n        \"\"\"\n        origins = {\n            \"up\": (self.page.width / 2, self.page.height - self.padding),\n            \"down\": (self.page.width / 2, self.padding),\n            \"right\": (self.padding, self.page.height / 2),\n            \"left\": (self.page.width - self.padding, self.page.height / 2),\n        }\n        return origins[self.direction]\n\n    def level_move(self, move):\n        \"\"\"The functions takes in a relative distance to move within levels. It outputs a tuple with the relative move in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            move (int): The amount to move within levels\n\n        Returns:\n            tuple: A tuple containing a 0 and the move, in the right orientation.\n        \"\"\"\n        if self.direction in [\"up\", \"down\"]:\n            return (0, move)\n        elif self.direction in [\"left\", \"right\"]:\n            return (move, 0)\n\n    def move_between_levels(self, start, move):\n        \"\"\"The functions takes in a starting position and a relative distance to move between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction == \"up\":\n            return (start[0], start[1] - move)\n        elif self.direction == \"down\":\n            return (start[0], start[1] + move)\n        elif self.direction == \"left\":\n            return (start[0] - move, start[1])\n        elif self.direction == \"right\":\n            return (start[0] + move, start[1])\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    def move_in_level(self, start, move):\n        \"\"\"The functions takes in a starting position and a relative distance to move within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction in [\"up\", \"down\"]:\n            return (start[0] + move, start[1])\n        elif self.direction in [\"left\", \"right\"]:\n            return (start[0], start[1] + move)\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    def abs_move_between_levels(self, start, position):\n        \"\"\"The functions takes in a starting position and an absolute position along the coordinates between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction == \"up\":\n            return (start[0], position)\n        elif self.direction == \"down\":\n            return (start[0], position)\n        elif self.direction == \"left\":\n            return (position, start[1])\n        elif self.direction == \"right\":\n            return (position, start[1])\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    def abs_move_in_level(self, start, position):\n        \"\"\"The functions takes in a starting position and an absolute position along the coordinates within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction in [\"up\", \"down\"]:\n            return (position, start[1])\n        elif self.direction in [\"left\", \"right\"]:\n            return (start[0], position)\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    ###########################################################\n    # Style Properties\n    ###########################################################\n\n    @property\n    def link_style(self):\n        \"\"\"The style of the links in the TreeDiagram\n\n        Returns:\n            str\n        \"\"\"\n        return self._link_style\n\n    @link_style.setter\n    def link_style(self, d):\n        link_styles = [\"orthogonal\", \"straight\", \"curved\"]\n        if d in link_styles:\n            self._link_style = d\n        else:\n            raise ValueError(\n                \"{0} is not a valid entry for link_style. Must be {1}.\".format(\n                    d, \", \".join(link_styles)\n                )\n            )\n\n    @property\n    def link_style_dict(self):\n        \"\"\"Returns the correct waypoint style for the set link_style\n\n        Returns:\n            dict: A dict with 'waypoint' as a key then the set link_style\n        \"\"\"\n        if self.link_style == \"orthogonal\":\n            return {\"waypoints\": \"orthogonal\"}\n        elif self.link_style == \"straight\":\n            return {\"waypoints\": \"straight\"}\n        elif self.link_style == \"curved\":\n            return {\"waypoints\": \"curved\"}\n\n    ###########################################################\n    # Object Linking and Sorting\n    ###########################################################\n\n    def add_object(self, obj, **kwargs):\n        if obj not in self.objects:\n            obj.page = self.page\n            if \"parent\" in kwargs:\n                obj.parent = kwargs.get(\"parent\")\n            self.objects.append(obj)\n\n    ###########################################################\n    # Layout and Output\n    ###########################################################\n\n    @property\n    def roots(self):\n        return [x for x in self.objects if x.parent is None]\n\n    def auto_layout(self):\n        def layout_child(parent):\n            grp = TreeGroup(tree=self)\n            grp.parent_object = parent\n            if len(parent.children) > 0:\n                # has children, go through each leaf and check its children\n                for leaf in parent.children:\n                    self.connect(parent, leaf)\n                    if len(leaf.children) > 0:\n                        # If this leaf has its own children then recursive call\n                        grp.add_object(layout_child(leaf))\n                    else:\n                        grp.add_object(leaf)\n\n                # layout the row\n                grp = layout_group(grp)\n                # grp = add_parent(grp, parent)\n                grp.center_parent()\n            return grp\n\n        def layout_group(grp, pos=self.origin):\n            pos = self.origin\n\n            for leaf in grp.objects:\n                if leaf is not grp.parent_object:\n                    leaf.position = pos\n                    pos = self.move_in_level(\n                        pos, leaf.size_in_level + self.item_spacing\n                    )\n            return grp\n\n        # def add_parent(grp, parent):\n        #     pos = grp.center_position\n        #     level_space = (\n        #         grp.size_of_level / 2\n        #         + self.level_spacing\n        #         + parent.size_of_level / 2\n        #     )\n        #     pos = self.move_between_levels(pos, -level_space)\n        #     parent.center_position = pos\n        #     # add the parent_object\n        #     grp.parent_object = parent\n        #     return grp\n\n        top_group = TreeGroup(tree=self)\n\n        for root in self.roots:\n            top_group.add_object(layout_child(root))\n\n        if len(top_group.objects) > 0:\n            # Position top group\n            top_group = layout_group(top_group)\n            # Center the top group\n            pos = self.origin\n            pos = self.move_between_levels(pos, top_group.size_of_level / 2)\n            top_group.center_position = pos\n\n        # lastly add peer links\n        self.connect_peers()\n\n        return top_group\n\n    def connect_peers(self):\n        peer_style = {\n            \"endArrow\": \"none\",\n            \"dashed\": 1,\n            \"html\": 1,\n            \"rounded\": 0,\n            \"exitX\": 1,\n            \"exitY\": 0.5,\n            \"exitDx\": 0,\n            \"exitDy\": 0,\n            \"entryX\": 0,\n            \"entryY\": 0.5,\n            \"entryDx\": 0,\n            \"entryDx\": 0,\n            \"edgeStyle\": \"orthogonalEdgeStyle\",\n        }\n        for obj in self.objects:\n            for peer in obj.peers:\n                link_exists = False\n                for link in self.links:\n                    if link.source == obj and link.target == peer:\n                        link_exists = True\n                    elif link.source == peer and link.target == obj:\n                        link_exists = True\n                if not link_exists:\n                    edge = Edge(page=self.page, source=obj, target=peer)\n                    edge.apply_attribute_dict(peer_style)\n                    self.links.append(edge)\n\n    def connect(self, source, target):\n        edge = Edge(page=self.page, source=source, target=target)\n        edge.apply_attribute_dict(self.link_style_dict)\n        if self.direction == \"down\":\n            # parent style\n            edge.exitX = 0.5\n            edge.exitY = 1\n            # child style\n            edge.entryX = 0.5\n            edge.entryY = 0\n        elif self.direction == \"up\":\n            # parent style\n            edge.exitX = 0.5\n            edge.exitY = 0\n            # child style\n            edge.entryX = 0.5\n            edge.entryY = 1\n        elif self.direction == \"left\":\n            # parent style\n            edge.exitX = 0\n            edge.exitY = 0.5\n            # child style\n            edge.entryX = 1\n            edge.entryY = 0.5\n        elif self.direction == \"right\":\n            # parent style\n            edge.exitX = 1\n            edge.exitY = 0.5\n            # child style\n            edge.entryX = 0\n            edge.entryY = 0.5\n        self.links.append(edge)\n\n    def draw_connections(self):\n        # Draw connections\n        for lvl in self.objects.values():\n            for obj in lvl:\n                if obj.parent is not None:\n                    self.connect(source=obj.parent, target=obj)\n\n    def write(self, **kwargs):\n        self.file.write(**kwargs)\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.direction","title":"direction property writable","text":"

The direction the tree diagram should grow. Options are \"up\", \"down\", \"left\", or \"right\".

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.file_name","title":"file_name property writable","text":"

The file name of the TreeDiagram

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.file_path","title":"file_path property writable","text":"

The file path where the TreeDiagram will be saved

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.link_style","title":"link_style property writable","text":"

The style of the links in the TreeDiagram

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.link_style_dict","title":"link_style_dict property","text":"

Returns the correct waypoint style for the set link_style

Returns:

Name Type Description dict

A dict with 'waypoint' as a key then the set link_style

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.origin","title":"origin property","text":"

The origin points of the TreeDiagram. This is the point where the center of the top level of the TreeDiagram starts from. By default it's set to the top center of an edge of the page. Which edge depends on the direction of the tree diagram.

Returns:

Name Type Description tuple

A tuple of ints

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.__init__","title":"__init__(**kwargs)","text":"

The TreeDiagram initiates its own File and Page objects. There are a number of formatting parameters that can be set to fine tune the rendering of the tree.

Other Parameters:

Name Type Description direction str

Direction that the tree grows from the root. Options are 'up', 'down', 'left', and 'right'. Defaults to 'down'.

link_style str

Connection style of the edges. Options are 'orthogonal', 'straight', and 'curved'. Defaults to 'orthogonal'.

level_spacing int

Spacing in pixels between levels. Defaults to 60.

item_spacing int

Spacing in pixels between groups within a level. Defaults to 15.

padding int

Spacing in pixels between objects within a group. Defaults to 10.

file_name str

The name of the tree diagram.

file_path str

The path where the tree diagram should be saved.

Source code in src/drawpyo/diagram_types/tree.py
def __init__(self, **kwargs):\n    \"\"\"The TreeDiagram initiates its own File and Page objects. There are a number of formatting parameters that can be set to fine tune the rendering of the tree.\n\n    Keyword Args:\n        direction (str, optional): Direction that the tree grows from the root. Options are 'up', 'down', 'left', and 'right'. Defaults to 'down'.\n        link_style (str, optional): Connection style of the edges. Options are 'orthogonal', 'straight', and 'curved'. Defaults to 'orthogonal'.\n        level_spacing (int, optional): Spacing in pixels between levels. Defaults to 60.\n        item_spacing (int, optional): Spacing in pixels between groups within a level. Defaults to 15.\n        padding (int, optional): Spacing in pixels between objects within a group. Defaults to 10.\n        file_name (str, optional): The name of the tree diagram.\n        file_path (str, optional): The path where the tree diagram should be saved.\n    \"\"\"\n    # formatting\n    self.level_spacing = kwargs.get(\"level_spacing\", 60)\n    self.item_spacing = kwargs.get(\"item_spacing\", 15)\n    self.group_spacing = kwargs.get(\"group_spacing\", 30)\n    self.direction = kwargs.get(\"direction\", \"down\")\n    self.link_style = kwargs.get(\"link_style\", \"orthogonal\")\n    self.padding = kwargs.get(\"padding\", 10)\n\n    # Set up the File and Page objects\n    self.file = File()\n    self.file_name = kwargs.get(\"file_name\", \"Heirarchical Diagram.drawio\")\n    self.file_path = kwargs.get(\"file_path\", r\"C:/\")\n    self.page = Page(file=self.file)\n\n    # Set up object and level lists\n    self.objects = []\n    self.links = []\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.abs_move_between_levels","title":"abs_move_between_levels(start, position)","text":"

The functions takes in a starting position and an absolute position along the coordinates between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def abs_move_between_levels(self, start, position):\n    \"\"\"The functions takes in a starting position and an absolute position along the coordinates between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction == \"up\":\n        return (start[0], position)\n    elif self.direction == \"down\":\n        return (start[0], position)\n    elif self.direction == \"left\":\n        return (position, start[1])\n    elif self.direction == \"right\":\n        return (position, start[1])\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.abs_move_in_level","title":"abs_move_in_level(start, position)","text":"

The functions takes in a starting position and an absolute position along the coordinates within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def abs_move_in_level(self, start, position):\n    \"\"\"The functions takes in a starting position and an absolute position along the coordinates within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction in [\"up\", \"down\"]:\n        return (position, start[1])\n    elif self.direction in [\"left\", \"right\"]:\n        return (start[0], position)\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.level_move","title":"level_move(move)","text":"

The functions takes in a relative distance to move within levels. It outputs a tuple with the relative move in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default move int

The amount to move within levels

required

Returns:

Name Type Description tuple

A tuple containing a 0 and the move, in the right orientation.

Source code in src/drawpyo/diagram_types/tree.py
def level_move(self, move):\n    \"\"\"The functions takes in a relative distance to move within levels. It outputs a tuple with the relative move in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        move (int): The amount to move within levels\n\n    Returns:\n        tuple: A tuple containing a 0 and the move, in the right orientation.\n    \"\"\"\n    if self.direction in [\"up\", \"down\"]:\n        return (0, move)\n    elif self.direction in [\"left\", \"right\"]:\n        return (move, 0)\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.move_between_levels","title":"move_between_levels(start, move)","text":"

The functions takes in a starting position and a relative distance to move between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def move_between_levels(self, start, move):\n    \"\"\"The functions takes in a starting position and a relative distance to move between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction == \"up\":\n        return (start[0], start[1] - move)\n    elif self.direction == \"down\":\n        return (start[0], start[1] + move)\n    elif self.direction == \"left\":\n        return (start[0] - move, start[1])\n    elif self.direction == \"right\":\n        return (start[0] + move, start[1])\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.move_in_level","title":"move_in_level(start, move)","text":"

The functions takes in a starting position and a relative distance to move within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def move_in_level(self, start, move):\n    \"\"\"The functions takes in a starting position and a relative distance to move within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction in [\"up\", \"down\"]:\n        return (start[0] + move, start[1])\n    elif self.direction in [\"left\", \"right\"]:\n        return (start[0], start[1] + move)\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#treegroup","title":"TreeGroup","text":""},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup","title":"src.drawpyo.diagram_types.tree.TreeGroup","text":"

Bases: Group

This class defines a group within a TreeDiagram. When a set of NodeObjects share the same parent they're grouped together for auto positioning. Each level of a TreeDiagram is a set of groups.

Source code in src/drawpyo/diagram_types/tree.py
class TreeGroup(Group):\n    \"\"\"This class defines a group within a TreeDiagram. When a set of NodeObjects share the same parent they're grouped together for auto positioning. Each level of a TreeDiagram is a set of groups.\"\"\"\n\n    def __init__(self, tree=None, parent_object=None, **kwargs):\n        \"\"\"The TreeGroup is instantiated with all the arguments of the Group. Additionally, the owning tree and the parent_object.\n\n        Args:\n            tree (TreeDiagram, optional): The TreeDiagram that owns the group. Defaults to None.\n            parent_object (NodeObject, optional): The parent object in the group. Defaults to None.\n        \"\"\"\n        super().__init__(**kwargs)\n        self.parent_object = parent_object\n        self.tree = tree\n\n    @property\n    def parent_object(self):\n        \"\"\"The object that defines the parent of the group.\n\n        Returns:\n            NodeObject\n        \"\"\"\n        return self._parent_object\n\n    @parent_object.setter\n    def parent_object(self, value):\n        if value is not None:\n            self.add_object(value)\n        self._parent_object = value\n\n    def center_parent(self):\n        \"\"\"This function centers the parent_objects along the group and then offsets it by the level spacing.\"\"\"\n        children_grp = TreeGroup(tree=self.tree)\n        for obj in self.objects:\n            if obj is not self.parent_object:\n                children_grp.add_object(obj)\n        pos = children_grp.center_position\n\n        level_space = (\n            children_grp.size_of_level / 2\n            + self.tree.level_spacing\n            + self.parent_object.size_of_level / 2\n        )\n        pos = self.tree.move_between_levels(pos, -level_space)\n        self.parent_object.center_position = pos\n\n    # I don't love that these are copy-pasted from NodeObject but the multiple\n    # inheritance was too much of a pain to have TreeGroup inherit.\n    @property\n    def size_of_level(self):\n        \"\"\"The height or the width of the level, depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.height\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.width\n\n    @property\n    def size_in_level(self):\n        \"\"\"The size of the object within its level, either its width or height depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.width\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.height\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.parent_object","title":"parent_object property writable","text":"

The object that defines the parent of the group.

Returns:

Type Description

NodeObject

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.size_in_level","title":"size_in_level property","text":"

The size of the object within its level, either its width or height depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.size_of_level","title":"size_of_level property","text":"

The height or the width of the level, depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.__init__","title":"__init__(tree=None, parent_object=None, **kwargs)","text":"

The TreeGroup is instantiated with all the arguments of the Group. Additionally, the owning tree and the parent_object.

Parameters:

Name Type Description Default tree TreeDiagram

The TreeDiagram that owns the group. Defaults to None.

None parent_object NodeObject

The parent object in the group. Defaults to None.

None Source code in src/drawpyo/diagram_types/tree.py
def __init__(self, tree=None, parent_object=None, **kwargs):\n    \"\"\"The TreeGroup is instantiated with all the arguments of the Group. Additionally, the owning tree and the parent_object.\n\n    Args:\n        tree (TreeDiagram, optional): The TreeDiagram that owns the group. Defaults to None.\n        parent_object (NodeObject, optional): The parent object in the group. Defaults to None.\n    \"\"\"\n    super().__init__(**kwargs)\n    self.parent_object = parent_object\n    self.tree = tree\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.center_parent","title":"center_parent()","text":"

This function centers the parent_objects along the group and then offsets it by the level spacing.

Source code in src/drawpyo/diagram_types/tree.py
def center_parent(self):\n    \"\"\"This function centers the parent_objects along the group and then offsets it by the level spacing.\"\"\"\n    children_grp = TreeGroup(tree=self.tree)\n    for obj in self.objects:\n        if obj is not self.parent_object:\n            children_grp.add_object(obj)\n    pos = children_grp.center_position\n\n    level_space = (\n        children_grp.size_of_level / 2\n        + self.tree.level_spacing\n        + self.parent_object.size_of_level / 2\n    )\n    pos = self.tree.move_between_levels(pos, -level_space)\n    self.parent_object.center_position = pos\n
"},{"location":"diagram_types/tree_diagrams/","title":"Tree Diagrams","text":"

These very useful diagram types are why drawpyo was written initially! The TreeDiagram module allows the easy creation of heirarchical directed trees, managing the parent and children relationships, then providing a convenient auto layout function.

"},{"location":"diagram_types/tree_diagrams/#create-a-tree","title":"Create a Tree","text":"

The two main objects to work with in drawpyo's trees are TreeDiagrams and NodeObjects. To start, create a TreeDiagram:

import drawpyo.diagram_types import TreeDiagram\n\ntree = TreeDiagram(\n    file_path = 'path/to/tree',\n    file_name = 'Tree Name.drawio',\n)\n

There are a number of configuration parameters available to fine tune the layout of the TreeDiagram. They can be passed in during initialization or later.

Parameter Effect Default direction direction that the tree grows from the root ('up', 'down', 'left', 'right') 'down' link_style Connection style of the edges ('orthogonal', 'straight', 'curved') 'orthogonal' level_spacing Spacing in pixels between levels 60 item_spacing Spacing in pixels between groups within a level 15 padding Spacing in pixels between objects within a group 10"},{"location":"diagram_types/tree_diagrams/#add-nodes","title":"Add Nodes","text":"

The custom object type that defines the nodes on the tree are called NodeObjects. Create some NodeObjects:

from drawpyo.diagram_types import NodeObject\n\n# Top object\ngrinders = NodeObject(tree=tree, value=\"Appliances for Grinding Coffee\", base_style=\"rounded rectangle\")\n\n# Main categories\nblade_grinders = NodeObject(tree=tree, value=\"Blade Grinders\", parent=grinders)\nburr_grinders = NodeObject(tree=tree, value=\"Burr Grinders\", parent=grinders)\nblunt_objects = NodeObject(tree=tree, value=\"Blunt Objects\", parent=grinders)\n

Note that the base_style was manually declared for the first object. But NodeObjects will default to \"rounded rectangle\" so it's not necessary for every one. Any NodeObject can be a parent, so you can keep adding objects down the tree:

# Other\nelec_blade = NodeObject(tree=tree, value=\"Electric Blade Grinder\", parent=blade_grinders)\nmnp = NodeObject(tree=tree, value=\"Mortar and Pestle\", parent=blunt_objects)\n\n# Conical Burrs\nconical = NodeObject(tree=tree, value=\"Conical Burrs\", parent=burr_grinders)\nelec_conical = NodeObject(tree=tree, value=\"Electric\", parent=conical)\nmanual_conical = NodeObject(tree=tree, value=\"Manual\", parent=conical)\n

Important Note: TreeDiagrams do not currently support NodeObjects with multiple parents! It may not ever as this seriously complicates the auto layout process. However, you can add links between any two objects in the tree and render them in the diagram. They just may look ugly until you manually rearrange the diagram.

Finally, before writing the diagram you'll want to run the magic penultimate step: auto layout.

tree.auto_layout()\ntree.write()\n
"},{"location":"usage/basic_usage/","title":"Basic Functionality","text":"

Drawpyo's basic functionality provides the same features as using the Draw.io app. You can create files with one or more pages, add objects to them, and position those objects. You can style objects from built-in shape libraries, manually, or from style strings. Those objects can be shapes, containers, or edges to connect them. Finally you can save your diagrams where they can be opened with the Draw.io app.

"},{"location":"usage/basic_usage/#files","title":"Files","text":""},{"location":"usage/basic_usage/#make-a-new-file","title":"Make a new file","text":"

A File object represents a Draw.io file. If no file_path is set the default path will be 'user/Drawpyo Charts' where 'user' will be an OS-specific user home folder.

diagram = drawpyo.File()\nfile.file_path = r\"C:\\drawpyo\"\nfile.file_name = \"Test Generated Edges.drawio\"\n
"},{"location":"usage/basic_usage/#write-a-file","title":"Write a file","text":"

Files can be written simply with the write() function. This function takes a few parameters to make it more flexible: | Parameter | Setting | | - | - | | file_path | This will overwrite the previously set file_path. | | file_name | This will overwrite the previously set file_name. Like file_path, useful in creating multiple copies of a diagram with slight variations | | overwrite | This boolean parameter controls whether an existing diagram should be overwritten or not. |

"},{"location":"usage/basic_usage/#pages","title":"Pages","text":""},{"location":"usage/basic_usage/#add-a-page","title":"Add a page","text":"

The Page object represents the different diagram pages that you can create in Draw.io. A Page can be created without linking it to a File but it won't be writable without a File object.

# Add a page\npage = drawpy.Page(file=file)\n
"},{"location":"usage/basic_usage/#page-parameters","title":"Page Parameters","text":"

There are a number of customizable parameter for pages:

argument description width Width of the document in pixels height Height of the document in pixels grid Enable grid (0 or 1) grid_size Side of grid squares in pixels guides Enable guides (0 or 1) tooltips Enable tooltips (0 or 1) scale Scale of the drawing"},{"location":"usage/edges/","title":"Edges","text":"

Edges are the lines and arrows that connect objects in Draw.io. There's quite a bit of variabiability in how they're created and styled so there's a bit more complexity than with objects.

"},{"location":"usage/edges/#creating-a-basic-edge","title":"Creating a basic edge","text":"

Like objects, there's a Edge object that can be easily created:

link = drawpyo.diagram.Edge(\n    page=page,\n    source=item_1,\n    target=item_2,\n    )\n
"},{"location":"usage/edges/#edge-labels","title":"Edge Labels","text":"

The value of an edge is the label that appears on it. It can be set using the label value.

The position of the label can be fine tuned with two parameters:

Parameter Effect label_position The position along the edge's axis where the label appears. This is float value between -1 and 1. 0 is neutral/in the center, -1 is at the source, and 1 is at the target. label_offset The offset in pixels perpendicular to the axis of the edge."},{"location":"usage/edges/#edge-geometry","title":"Edge Geometry","text":"

Besides the source and target, the edge geometry can be very finely tuned. There are eight parameters that control where and how the edge meets the source and target objects:

Parameter Definition entryX From where along the X axis on the source object the edge originates (0-1) entryY From where along the Y axis on the source object the edge originates (0-1) entryDx Applies an offset in pixels to the X axis entry point entryDy Applies an offset in pixels to the Y axis entry point exitX From where along the X axis on the target object the edge originates\u00a0(0-1) exitY From where along the Y axis on the target object the edge originates\u00a0(0-1) exitDx Applies an offset in pixels to the X axis exit point exitDy Applies an offset in pixels to the Y axis exit point targetPerimeterSpacing The negative or positive spacing between the target and end of the edge in points sourcePerimeterSpacing The negative or positive spacing between the source and end of the edge in points

If these parameters are set to None then the Draw.io rendering engine will place the origination and direction of the edge wherever makes the most sense based on the layout of the objects. This is the same as the behavior in the app when an edge is dragged to the center of a shape (highlighting the whole object green) instead of to a specific node on the border (and seeing just that node highlighted in green).

Other attributes for controlling the general shape of the object are:

Parameter Definition jettySize Defines the length of the straight line coming out of or into an object before the edge makes its first turn"},{"location":"usage/edges/#points","title":"Points","text":"

You can also add points to Edges to further fine tune their routing. This isn't always necessary, usually setting the entry/exit parameters handles the auto routing correctly. However this is an option, using the Edge.add_point() and Edge.add_point_pos() functions.

"},{"location":"usage/edges/#styling-edges","title":"Styling edges","text":"

Just about every edge styling option from the Draw.io app is implemented in Drawpyo. It's easiest to just play with all of the different line styling options in Draw.io to understand how they render but the major options are listed here.

"},{"location":"usage/edges/#text-styling","title":"Text Styling","text":"

The styling within an an edge label is contained inside of a TextFormat object. All styling parameters can be accessed at the attribute Edge.text_format, which contains a TextFormat object.

For more information about styling text, see Formatting Text for more information.

"},{"location":"usage/edges/#color-and-shading","title":"Color and Shading","text":"

Edge coloring can be set with a stroke and fill color, though only the stroke applies to a simple edge.

Parameter Effect opacity The opacity of the edge (0-100) strokeColor The color of the edge or the stroke around the edge shape ('default', 'none', or a hex color code) fillColor The fill color of the edge shape\u00a0('default', 'none', or a hex color code)"},{"location":"usage/edges/#effects","title":"Effects","text":"

Draw.io has four effects that can be set on an edge. They're all boolean valuable that can be enabled.

Paramater Rendered default (None) rounded shadow sketch flowAnimation*

*(this animates in Draw.io)

"},{"location":"usage/edges/#jumps","title":"Jumps","text":"

By default, when an edge crosses another edge they'll just be rendered as a cross. You can also enable line jumps; the top edge will 'jump' over the bottom edge. There are different styles of line jumps and they can have variable sizes as well.

Parameter Effect jumpStyle The style of the line jump. Can be 'arc', 'gap', 'sharp', or 'line'. jumpSize The size of the rendered line jumps in points.

The different rendered jump styles are:

Parameter Rendered default (None) arc gap sharp line"},{"location":"usage/edges/#waypoints","title":"Waypoints","text":"

The waypoint parameter controls how the line is routed from the source to the target. For example, a straight line is just point to point. A curved line tries to maintain gentle curves and perpendicularity to the source and target objects. Options are:

Parameter Rendered default (None) straight orthogonal vertical horizontal isometric isometric_vertical curved entity_relation"},{"location":"usage/edges/#connections","title":"Connections","text":"

The connection parameter is abstractly named but it controls what type of edge this is. Most edges are lines but other types are available.

Parameter Rendered default (None) line link arrow simple_arrow"},{"location":"usage/edges/#patterns","title":"Patterns","text":"

The pattern parameter controls how the line stroke is rendered. Options are:

Parameter Rendered default (None) solid dashed_small dashed_medium dashed_large dotted_small dotted_medium dotted_large"},{"location":"usage/edges/#line-ends","title":"Line Ends","text":"

The line_end_target and line_end_source parameter sets whatever is rendered where the edge meets the objects. There are secondary boolean parameters for the fill of the ends (endFill_target and endFill_source) but not all ends can be filled.

The line end size can also be adjusted with endSize and startSize parameters, both set in points.

Parameter Rendered Unfilled Rendered Filled default (None) na classic classicThin open na openThin na openAsync na block blockThin async oval diamond diamondThin dash na halfCircle na cross na circlePlus na circle na baseDash na ERone na ERmandOne na ERmany na ERoneToMany na ERzeroToOne na ERzeroToMany na doubleBlock"},{"location":"usage/objects/","title":"Objects","text":"

Though some diagram types have their own object subclasses, the main class for creating objects is the Object class.

"},{"location":"usage/objects/#creating-a-basic-object","title":"Creating a basic object","text":"
base_obj = drawpyo.diagram.Object(page=page)\n

The default object type is a rounded corner rectangle with white background and a black border just like in the Draw.io app.

The value attribute holds the text to display in the object.

base_obj.value = \"This Object's Name is Fred\"\n
"},{"location":"usage/objects/#creating-an-object-from-a-shape-library","title":"Creating an object from a shape library","text":"

Just like the built-in shape libraries in the Draw.io app, Drawpyo supports generating shapes from libraries. Currently the 'general' library from the Draw.io app is defined but more will be added in the future.

These libraries are defined in TOML files and drawpyo supports importing custom shape libraries! See Shape Libraries for more information.

To generate an object from a library:

object = drawpyo.diagram.object_from_library(\n    library=\"general\",\n    obj_name=\"process\",\n    page=page,\n    )\n

This function returns a normal Object but prestyled by the library. It can then be further styled or modified.

"},{"location":"usage/objects/#object-geometry","title":"Object Geometry","text":"

All objects contain a structure called ObjectGeometry that provides a layer of abstraction. Interacting directly with the geometry class is optional.

"},{"location":"usage/objects/#object-sizing","title":"Object Sizing","text":"

The three parameters that affect object placement are size and aspect. Size has to be set individually with the .width and .height attributes.

Object.width = 120\nObject.height = 80\nObject.aspect = 'fixed'\n

In earlier versions there was a 'size' attribute. But then it was found that 'size' was also used as a style attribute for certain shapes so the geometry size attribute was removed in favor of using width and height directly.

"},{"location":"usage/objects/#object-geometry-and-placement","title":"Object Geometry and Placement","text":"

Repositioning objects is simple but there are a few convenience features to know about. There are two attributes available for setting the position by either the top left corner or the center:

Object.position = (0, 0)\nObject.center_position = (0, 0)\n

The X and Y positions can also be accessed directly in the geometry object.

Object.geometry.x = 0\nObject.geometry.y = 0\n
"},{"location":"usage/objects/#styling-objects","title":"Styling Objects","text":"

There are infinite permutations of object formatting and styling available. There are some higher order attributes that set the template for the object. What lower order styling attributes may or may not apply in combination. Then there are attributes like size and text formatting that apply in all cases. These interactions are difficult to predict in drawpyo alone so a good way to get familiar with all of the possible options and types of customizations is just to play with the Draw.io app directly to design formatting to your taste.

Almost all styling attributes are optional (and drawpyo adds the non-optional ones automatically). If an attribute is unset or set to None then it won't be included in the file output. This will set that specific styling behavior to a default mode.

"},{"location":"usage/objects/#text-styling","title":"Text Styling","text":"

The styling within an object is contained inside of a TextFormat object. All styling parameters can be accessed at the attribute Object.text_format, which contains a TextFormat object.

For more information about styling text, see Formatting Text for mor information.

"},{"location":"usage/objects/#basestyle-and-shape","title":"BaseStyle and Shape","text":"

The highest order styling attribute in Draw.io for objects is shape. This sets how the object behaves and is rendered. Different values include:

and many more.

Confusingly there is another attribute called baseStyle that is sometimes used in combination with shape and sometimes without.

BaseStyles include:

It can be hard to predict how these two attributes will interact. To utilize them it's recommended to start in the Draw.io app, use their shape libraries or templates to get the desired style, then look at the style string to see what shape and baseStyle were used. When creating an object from a shape library these two attributes are handled automatically.

"},{"location":"usage/objects/#basic-styling-attributes","title":"Basic Styling Attributes","text":"

These attributes mostly apply to most shape/baseStyle combinations and can be set on almost any object.

"},{"location":"usage/objects/#further-styling-attributes","title":"Further Styling Attributes","text":"

As mentioned above, not all of these attributes will apply to all object shapes and types. But some commonly called include:

"},{"location":"usage/shape_libs/","title":"Shape Libraries","text":"

The Draw.io app has a lot of built-in shape libraries available. The basic library contains shapes and building blocks but there are increasingly more specific libraries such as flowcharts, wiring diagrams, and org charts. You can also export and import shape libraries into Draw.io.

To replicate this feature for drawpyo, I created a library format based on TOML. Draw.io's libraries are XML which isn't as human readable or writable and is more specification than necessary.

Supporting Draw.io's XML based library is a planned feature.

"},{"location":"usage/shape_libs/#built-in-shape-libaries","title":"Built-In Shape Libaries","text":"

Drawpyo uses these TOML shape libraries to store the default libaries. The default libraries are in /drawpyo/shape_libraries. These are the libraries that are available in the Draw.io app.

Implemented default libraries:

There is also a set of TOML databases for other formats, like all of the various combinations of edge styles and the line styles. These are stored in /drawpyo/formatting_database.

"},{"location":"usage/shape_libs/#custom-shape-libaries","title":"Custom Shape Libaries","text":"

This functionality is available to the user so you can define your own custom libraries! TOML was selected because it's a very simple and human-readable config file format. the TOML project website has a very nice high level overview. But drawpyo is hardly scratching the surface of what TOML is capable of so little expertise is needed.

"},{"location":"usage/shape_libs/#creating-a-shape-library","title":"Creating a Shape Library","text":"

To define a shape library create a .toml file. Current convention is to start with a title tag for clarity.

title = \"Custom drawpyo shapes\"\n

You can then define a custom object by naming the object in square brackets and adding whichever attributes you want:

[square]\nwidth = 80\nheight = 80\naspect = \"fixed\"\n

You can also have any shape inherit another and then either modify or extend its style:

[perfect_circle]\ninherit = \"square\"\nbaseStyle = \"ellipse\"\n

This perfect_circle will now inherit the fixed aspect and size attributes from square but with the ellipse baseStyle.

"},{"location":"usage/shape_libs/#style-attribute-types","title":"Style Attribute Types","text":"

The attributes in the TOML file can come from three sets:

"},{"location":"usage/shape_libs/#drawpyo-attributes-snake_case","title":"Drawpyo attributes (snake_case)","text":"

These are the attributes that drawpyo uses to abstract some complicated style strings, such as size instead of the Draw.io parameters of width and height.

"},{"location":"usage/shape_libs/#predefined-style-attributes","title":"Predefined style attributes","text":"

Such as any of the attributes listed in the Styling section of Objects. These will simply be overwritten with the values in the TOML file.

"},{"location":"usage/shape_libs/#any-new-style-attributes","title":"Any new style attributes","text":"

If you want to add a rare style attribute that drawpyo hasn't defined or worked with yet, no worries! When you import the TOML library if there are new style attributes defined then they'll get added to the Object and exported into the Draw.io file.

"},{"location":"usage/shape_libs/#using-a-custom-library","title":"Using a Custom Library","text":"

To use a custom shape library it just needs to be imported then passed to the object definition function:

custom_library = drawpyo.diagram.import_shape_database(\n\u00a0\u00a0\u00a0\u00a0file_name=r\"path/to/toml_lib\"\n\u00a0\u00a0\u00a0\u00a0)\n\nnew_obj = drawpyo.diagram.object_from_library(\n    library = custom_library,\n    obj_name = 'object_name_from_lib',\n    page=page,\n    )\n
"},{"location":"usage/text_format/","title":"Formatting Text","text":"

Everywhere that text appears in Draw.io has the same basic text formatting options. TO support this in drawpyo there's a custom class, TextFormat, that handles all of these options for code reusability. This also means that TextFormat objects can be created and copied into new objects or edges to make reformatting text convenient.

Any object with formattable text will have a .text_format attribute that holds a TextFormat class.

"},{"location":"usage/text_format/#type-face-attributes","title":"Type Face Attributes","text":"Attribute Data Type Description fontFamily str The typeface to use. See Draw.io for a list of font choices. fontSize int The size of the font in points fontColor str The color of the typeface bold bool Bold font italic bool Italic font underline bool Underlined font textShadow bool Whether to place a shadow underneath the text textOpacity int The transparency level of the text. 0-100"},{"location":"usage/text_format/#text-alignment-and-spacing-attributes","title":"Text Alignment and Spacing Attributes","text":"

The text is rendered inside a box and various layout and alignment choices can be made to control where and how it's positioned.

Attribute Data Type Description spacing int The global spacing to add around the text and the outside of the bounding box spacingTop int The top spacing to add around the text spacingBottom int The bottom spacing to add around the text spacingLeft int The left spacing to add around the text spacingRight int The right spacing to add around the text direction str The direction to orient the text. Can be 'horizontal' or 'vertical' align str The horizontal alignment of the text. Can be 'left', 'center', or 'right' verticalAlign str The vertical alignment of the text. Can be 'top', 'middle', or 'bottom'

Spacing Attributes

"},{"location":"usage/text_format/#label-box-attributes","title":"Label Box Attributes","text":"

Some aspects of the text bounding box itself can also be formatted.

Attribute Data Type Description labelBorderColor str The color of the border around the bounding box labelBackgroundColor str The color of the fill of the bounding box labelPosition str The position of the bounding box as it relates to the owning object"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to drawpyo","text":"

Drawpyo is a Python library for programmatically generating Draw.io charts. It enables creating a diagram object, placing and styling objects, then writing the object to a file.

"},{"location":"#historyjustification","title":"History/Justification","text":"

I love Draw.io! Compared to expensive and heavy commercial options like Visio and Miro, Draw.io's free and lightweight app allows wider and more universal distribution of diagrams. Because the files are stored in plaintext they can be versioned alongside code in a repository as documentation. Draw.io also maintains back compatibility and any diagram created in the app since it was launched can still be opened. The XML-based file format makes these diagrams semi-portable, and could easily be ported to other applications if Draw.io ever disappeared. For these reason, I think it's one of the best options for documentation diagrams.

So wen I had a need to generate heirarchical tree diagrams of requirement structures I looked to Draw.io but I was surprised to find there wasn't even a single existing Python library for working with these files. I took the project home and spent a weekend building the initial functionality. I've been adding functionality, robustness, and documentation intermittently since.

"},{"location":"#the-future-of-drawpyo","title":"The Future of Drawpyo","text":"

I will continue to tinker away with this tool, creating new functionality as I need it or find it interesting. But it's unfortunately a rather low priority so if anyone wants to contribute I would be grateful for the help! Reach out to me at xander@merriman.industries if you want to contribute.

"},{"location":"about/","title":"Conventions and Naming","text":"

This library contains quite a lot of camel case (capitalizeEachWord) attributes. While the Python convention is snake case (underscores_between_lowercase) the Draw.io style strings and attributes are camel case. Wherever possible, drawpyo uses the terminology and variable names from Draw.io to make it more intuitive to work between the two apps. However, any attribute that does not have an analogy in the Draw.io app is snake case. While this is a bit confusing I hope it helps to clarify when there's a direct analog between drawpyo and Draw.io and when the variable is a drawpyo abstraction. If this is confusing please share that feedback on the GitHub page or email and it may be changed in future versions!

"},{"location":"about/#basic-diagrams","title":"Basic Diagrams","text":"

Drawpyo's basic functionality provides the same features as using the Draw.io app. You can create files with one or more pages, add objects to them, and position those objects. You can style objects from built-in shape libraries, manually, or from style strings. Those objects can be shapes, containers, or edges to connect them. Finally you can save your diagrams where they can be opened with the Draw.io app.

See the full documentation for these functions in Basic Diagrams - Usage.

"},{"location":"about/#extended-functionality","title":"Extended Functionality","text":"

Drawpyo extends the basic functionality of the Draw.io app with custom diagram types. These custom diagrams have automated styling and layouting to make common or complex diagrams easier to generate.

"},{"location":"about/#treediagram","title":"TreeDiagram","text":"

This diagram makes creating directed tree graphs easy. Define trees, nodes, and the apply an auto layout.

Documentation

"},{"location":"api/architecture/","title":"Architecture","text":"

Drawpyo provides two high level classes to define critical methods and attributes for all exportable Draw.io objects. Primarily they define the parent and id attributes as well as a series of methods and properties for generating XML and style strings.

"},{"location":"api/architecture/#xmlbase","title":"XMLBase","text":"

XMLBase is the base class for all exportable objects in drawpyo. This class defines a few useful properties that drawpyo needs to use to generate a Draw.io file.

Source code in src/drawpyo/xml_base.py
class XMLBase:\n    \"\"\"\n    XMLBase is the base class for all exportable objects in drawpyo. This class defines a few useful properties that drawpyo needs to use to generate a Draw.io file.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        self._id = kwargs.get(\"id\", id(self))\n        self.xml_class = kwargs.get(\"xml_class\", \"xml_tag\")\n\n        # There's only one situation where XMLBase is called directly: to\n        # create the two empty mxCell objects at the beginning of every\n        # Draw.io diagram. The following declarations should be overwritten\n        # in every other use case.\n        self.xml_parent = kwargs.get(\"xml_parent\", None)\n\n    @property\n    def id(self):\n        \"\"\"\n        id is a unique identifier. Draw.io generated diagrams use an ID many more characters but the app isn't picky when parsing so drawpyo just uses Python's built-in id() function as it guarantees unique identifiers.\n\n        Returns:\n            int: A unique identifier for the Draw.io object\n        \"\"\"\n        return self._id\n\n    @property\n    def attributes(self):\n        \"\"\"\n        The most basic attributes of a Draw.io object. Extended by subclasses.\n\n        Returns:\n            dict: A dict containing an 'id' and 'xml_parent' object.\n        \"\"\"\n        return {\"id\": self.id, \"parent\": self.xml_parent}\n\n    ###########################################################\n    # XML Tags\n    ###########################################################\n\n    @property\n    def xml_open_tag(self):\n        \"\"\"\n        The open tag contains the name of the object but also the attribute tags. This property function concatenates all the attributes in the class along with the opening and closing angle brackets and returns them as a string.\n\n        Example:\n        <class_name attribute_name=attribute_value>\n\n        Returns:\n            str: The opening tag of the object with all the attributes.\n        \"\"\"\n        open_tag = \"<\" + self.xml_class\n        for att, value in self.attributes.items():\n            if value is not None:\n                xml_parameter = self.xml_ify(str(value))\n                open_tag = open_tag + \" \" + att + '=\"' + xml_parameter + '\"'\n        return open_tag + \">\"\n\n    @property\n    def xml_close_tag(self):\n        \"\"\"\n        The closing tag contains the name of the object wrapped in angle brackets.\n\n        Example:\n        </class_name>\n\n        Returns:\n            str: The closing tag of the object with all the attributes.\n        \"\"\"\n        return \"</{0}>\".format(self.xml_class)\n\n    @property\n    def xml(self):\n        \"\"\"\n        All drawpyo exportable classes contain an xml property that returns the formatted string of their XML output.\n\n        This default version of the function assumes no inner value so it just returns the opening tag closed with a '/>'. Subclasses that require more printing overload this function with their own implementation.\n\n        Example:\n        <class_name attribute_name=attribute_value/>\n\n        Returns:\n            str: A single XML tag containing the object name, style attributes, and a closer.\n        \"\"\"\n        return self.xml_open_tag[:-1] + \" />\"\n\n    def xml_ify(self, parameter_string):\n        return self.translate_txt(parameter_string, xmlize)\n\n    @staticmethod\n    def translate_txt(string, replacement_dict):\n        new_str = \"\"\n        for char in string:\n            if char in replacement_dict:\n                new_str = new_str + replacement_dict[char]\n            else:\n                new_str = new_str + char\n        return new_str\n
"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.attributes","title":"attributes property","text":"

The most basic attributes of a Draw.io object. Extended by subclasses.

Returns:

Name Type Description dict

A dict containing an 'id' and 'xml_parent' object.

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.id","title":"id property","text":"

id is a unique identifier. Draw.io generated diagrams use an ID many more characters but the app isn't picky when parsing so drawpyo just uses Python's built-in id() function as it guarantees unique identifiers.

Returns:

Name Type Description int

A unique identifier for the Draw.io object

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.xml","title":"xml property","text":"

All drawpyo exportable classes contain an xml property that returns the formatted string of their XML output.

This default version of the function assumes no inner value so it just returns the opening tag closed with a '/>'. Subclasses that require more printing overload this function with their own implementation.

Example:

Returns:

Name Type Description str

A single XML tag containing the object name, style attributes, and a closer.

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.xml_close_tag","title":"xml_close_tag property","text":"

The closing tag contains the name of the object wrapped in angle brackets.

Example:

Returns:

Name Type Description str

The closing tag of the object with all the attributes.

"},{"location":"api/architecture/#src.drawpyo.xml_base.XMLBase.xml_open_tag","title":"xml_open_tag property","text":"

The open tag contains the name of the object but also the attribute tags. This property function concatenates all the attributes in the class along with the opening and closing angle brackets and returns them as a string.

Example:

Returns:

Name Type Description str

The opening tag of the object with all the attributes.

"},{"location":"api/architecture/#diagrambase","title":"DiagramBase","text":"

Bases: XMLBase

This class is the base for all diagram objects to inherit from. It defines some general creation methods and properties to make diagram objects printable and useful.

Source code in src/drawpyo/diagram/base_diagram.py
class DiagramBase(XMLBase):\n    \"\"\"\n    This class is the base for all diagram objects to inherit from. It defines some general creation methods and properties to make diagram objects printable and useful.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self._style_attributes = [\"html\"]\n        self.page = kwargs.get(\"page\", None)\n        self.xml_parent = kwargs.get(\"xml_parent\", None)\n\n    @classmethod\n    def create_from_library(cls, library, obj):\n        return cls\n\n    # XML_parent property\n    @property\n    def xml_parent_id(self):\n        if self.xml_parent is not None:\n            return self.xml_parent.id\n        else:\n            return 1\n\n    # Parent object linking\n    @property\n    def xml_parent(self):\n        return self._xml_parent\n\n    @xml_parent.setter\n    def xml_parent(self, p):\n        if p is not None:\n            p.add_object(self)\n            self._xml_parent = p\n        else:\n            self._xml_parent = None\n\n    @xml_parent.deleter\n    def xml_parent(self):\n        self._xml_parent.remove_object(self)\n        self._xml_parent = None\n\n    # Page property\n    @property\n    def page_id(self):\n        if self.page is not None:\n            return self.page.id\n        else:\n            return 1\n\n    # page object linking\n    @property\n    def page(self):\n        return self._page\n\n    @page.setter\n    def page(self, p):\n        if p is not None:\n            p.add_object(self)\n            self._page = p\n        else:\n            self._page = None\n\n    @page.deleter\n    def page(self):\n        self._page.remove_object(self)\n        self._page = None\n\n    ###########################################################\n    # Style properties\n    ###########################################################\n    def add_style_attribute(self, style_attr):\n        if style_attr not in self._style_attributes:\n            self._style_attributes.append(style_attr)\n\n    @property\n    def style_attributes(self):\n        \"\"\"\n        The style attributes are the list of style tags that should be printed into the style XML attribute. This is a subset of the attributes defined on the object method.\n\n        Returns:\n            list: A list of the names of the style_attributes.\n        \"\"\"\n        return self._style_attributes\n\n    @style_attributes.setter\n    def style_attributes(self, value):\n        self._style_attributes = value\n\n    @property\n    def style(self):\n        \"\"\"\n        This function returns the style string of the object to be appended into the style XML attribute.\n\n        First it searches the object properties called out in\n        self.style_attributes. If the property is initialized to something\n        that isn't None or an empty string, it will add it. Otherwise it\n        searches the base_style defined by the object template.\n\n        Returns:\n            str: The style string of the object.\n\n        \"\"\"\n\n        style_str = \"\"\n        if (\n            hasattr(self, \"baseStyle\")\n            and getattr(self, \"baseStyle\") is not None\n            and getattr(self, \"baseStyle\") != \"\"\n        ):\n            style_str = getattr(self, \"baseStyle\") + \";\"\n\n        # Add style attributes\n        for attribute in self.style_attributes:\n            if hasattr(self, attribute) and getattr(self, attribute) is not None:\n                attr_val = getattr(self, attribute)\n                # reformat different datatypes to strings\n                if isinstance(attr_val, bool):\n                    attr_val = format(attr_val * 1)\n                style_str = style_str + \"{0}={1};\".format(attribute, attr_val)\n\n        # Add style objects\n        if hasattr(self, \"text_format\") and self.text_format is not None:\n            style_str = style_str + self.text_format.style\n        return style_str\n\n    def _add_and_set_style_attrib(self, attrib, value):\n        if hasattr(self, attrib):\n            setattr(self, attrib, value)\n        else:\n            setattr(self, attrib, value)\n            self.add_style_attribute(attrib)\n\n    def apply_style_string(self, style_str):\n        \"\"\"\n        This function will apply a passed in style string to the object. This style string can be obtained from the Draw.io app by selecting Edit Style from the context menu of any object. This function will iterate through the attributes in the style string and assign the corresponding property the value.\n\n        Args:\n            style_str (str): A Draw.io style string\n        \"\"\"\n        for attrib in style_str.split(\";\"):\n            if attrib == \"\":\n                pass\n            elif \"=\" in attrib:\n                a_name = attrib.split(\"=\")[0]\n                a_value = attrib.split(\"=\")[1]\n                if a_value.isdigit():\n                    if \".\" in a_value:\n                        a_value = float(a_value)\n                    else:\n                        a_value = int(a_value)\n                elif a_value == \"True\" or a_value == \"False\":\n                    a_value = bool(a_value)\n\n                self._add_and_set_style_attrib(a_name, a_value)\n            else:\n                self.baseStyle = attrib\n\n    def _apply_style_from_template(self, template):\n        for attrib in template.style_attributes:\n            value = getattr(template, attrib)\n            self._add_and_set_style_attrib(attrib, value)\n\n    def apply_attribute_dict(self, attr_dict):\n        \"\"\"\n        This function takes in a dictionary of attributes and applies them\n        to the object. These attributes can be style or properties. If the\n        attribute isn't already defined as a property of the class it's\n        assumed to be a style attribute. It will then be added as a property\n        and also appended to the .style_attributes list.\n\n        Parameters\n        ----------\n        attr_dict : dict\n            A dictionary of attributes to set or add to the object.\n\n        Returns\n        -------\n        None.\n\n        \"\"\"\n        for attr, val in attr_dict.items():\n            self._add_and_set_style_attrib(attr, val)\n\n    @classmethod\n    def from_style_string(cls, style_string):\n        \"\"\"\n        This classmethod allows the intantiation of an object from a style\n        string. This is useful since Draw.io allows copying the style string\n        out of an object in their UI. This string can then be copied into the\n        Python environment and further objects created that match the style.\n\n        Args:\n            style_string (str): A Draw.io style string\n\n        Returns:\n            BaseDiagram: A BaseDiagram or subclass instantiated with the style from the Draw.io string\n        \"\"\"\n        new_obj = cls()\n        new_obj.apply_style_string(style_string)\n        return new_obj\n
"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.style","title":"style property","text":"

This function returns the style string of the object to be appended into the style XML attribute.

First it searches the object properties called out in self.style_attributes. If the property is initialized to something that isn't None or an empty string, it will add it. Otherwise it searches the base_style defined by the object template.

Returns:

Name Type Description str

The style string of the object.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.style_attributes","title":"style_attributes property writable","text":"

The style attributes are the list of style tags that should be printed into the style XML attribute. This is a subset of the attributes defined on the object method.

Returns:

Name Type Description list

A list of the names of the style_attributes.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_attribute_dict","title":"apply_attribute_dict(attr_dict)","text":"

This function takes in a dictionary of attributes and applies them to the object. These attributes can be style or properties. If the attribute isn't already defined as a property of the class it's assumed to be a style attribute. It will then be added as a property and also appended to the .style_attributes list.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_attribute_dict--parameters","title":"Parameters","text":"

attr_dict : dict A dictionary of attributes to set or add to the object.

"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_attribute_dict--returns","title":"Returns","text":"

None.

Source code in src/drawpyo/diagram/base_diagram.py
def apply_attribute_dict(self, attr_dict):\n    \"\"\"\n    This function takes in a dictionary of attributes and applies them\n    to the object. These attributes can be style or properties. If the\n    attribute isn't already defined as a property of the class it's\n    assumed to be a style attribute. It will then be added as a property\n    and also appended to the .style_attributes list.\n\n    Parameters\n    ----------\n    attr_dict : dict\n        A dictionary of attributes to set or add to the object.\n\n    Returns\n    -------\n    None.\n\n    \"\"\"\n    for attr, val in attr_dict.items():\n        self._add_and_set_style_attrib(attr, val)\n
"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.apply_style_string","title":"apply_style_string(style_str)","text":"

This function will apply a passed in style string to the object. This style string can be obtained from the Draw.io app by selecting Edit Style from the context menu of any object. This function will iterate through the attributes in the style string and assign the corresponding property the value.

Parameters:

Name Type Description Default style_str str

A Draw.io style string

required Source code in src/drawpyo/diagram/base_diagram.py
def apply_style_string(self, style_str):\n    \"\"\"\n    This function will apply a passed in style string to the object. This style string can be obtained from the Draw.io app by selecting Edit Style from the context menu of any object. This function will iterate through the attributes in the style string and assign the corresponding property the value.\n\n    Args:\n        style_str (str): A Draw.io style string\n    \"\"\"\n    for attrib in style_str.split(\";\"):\n        if attrib == \"\":\n            pass\n        elif \"=\" in attrib:\n            a_name = attrib.split(\"=\")[0]\n            a_value = attrib.split(\"=\")[1]\n            if a_value.isdigit():\n                if \".\" in a_value:\n                    a_value = float(a_value)\n                else:\n                    a_value = int(a_value)\n            elif a_value == \"True\" or a_value == \"False\":\n                a_value = bool(a_value)\n\n            self._add_and_set_style_attrib(a_name, a_value)\n        else:\n            self.baseStyle = attrib\n
"},{"location":"api/architecture/#src.drawpyo.diagram.base_diagram.DiagramBase.from_style_string","title":"from_style_string(style_string) classmethod","text":"

This classmethod allows the intantiation of an object from a style string. This is useful since Draw.io allows copying the style string out of an object in their UI. This string can then be copied into the Python environment and further objects created that match the style.

Parameters:

Name Type Description Default style_string str

A Draw.io style string

required

Returns:

Name Type Description BaseDiagram

A BaseDiagram or subclass instantiated with the style from the Draw.io string

Source code in src/drawpyo/diagram/base_diagram.py
@classmethod\ndef from_style_string(cls, style_string):\n    \"\"\"\n    This classmethod allows the intantiation of an object from a style\n    string. This is useful since Draw.io allows copying the style string\n    out of an object in their UI. This string can then be copied into the\n    Python environment and further objects created that match the style.\n\n    Args:\n        style_string (str): A Draw.io style string\n\n    Returns:\n        BaseDiagram: A BaseDiagram or subclass instantiated with the style from the Draw.io string\n    \"\"\"\n    new_obj = cls()\n    new_obj.apply_style_string(style_string)\n    return new_obj\n
"},{"location":"api/edges/","title":"Edges","text":""},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge","title":"src.drawpyo.diagram.edges.Edge","text":"

Bases: DiagramBase

The Edge class is the simplest class for defining an edge or an arrow in a Draw.io diagram.

The three primary styling inputs are the waypoints, connections, and pattern. These are how edges are styled in the Draw.io app, with dropdown menus for each one. But it's not how the style string is assembled in the XML. To abstract this, the Edge class loads a database called edge_styles.toml. The database maps the options in each dropdown to the style strings they correspond to. The Edge class then assembles the style strings on export.

More information about edges are in the Usage documents at Usage - Edges.

Source code in src/drawpyo/diagram/edges.py
class Edge(DiagramBase):\n    \"\"\"The Edge class is the simplest class for defining an edge or an arrow in a Draw.io diagram.\n\n    The three primary styling inputs are the waypoints, connections, and pattern. These are how edges are styled in the Draw.io app, with dropdown menus for each one. But it's not how the style string is assembled in the XML. To abstract this, the Edge class loads a database called edge_styles.toml. The database maps the options in each dropdown to the style strings they correspond to. The Edge class then assembles the style strings on export.\n\n    More information about edges are in the Usage documents at [Usage - Edges](../../usage/edges).\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        \"\"\"Edges can be initialized with almost all styling parameters as args.\n        See [Usage - Edges](../../usage/edges) for more information and the options for each parameter.\n\n        Args:\n            source (DiagramBase): The Draw.io object that the edge originates from\n            target (DiagramBase): The Draw.io object that the edge points to\n            label (str): The text to place on the edge.\n            label_position (float): Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center\n            label_offset (int): How far the label is offset away from the axis of the edge in pixels\n            waypoints (str): How the edge should be styled in Draw.io\n            connection (str): What type of style the edge should be rendered with\n            pattern (str): How the line of the edge should be rendered\n            shadow (bool, optional): Add a shadow to the edge\n            rounded (bool): Whether the corner of the line should be rounded\n            flowAnimation (bool): Add a marching ants animation along the edge\n            sketch (bool, optional): Add sketch styling to the edge\n            line_end_target (str): What graphic the edge should be rendered with at the target\n            line_end_source (str): What graphic the edge should be rendered with at the source\n            endFill_target (boolean): Whether the target graphic should be filled\n            endFill_source (boolean): Whether the source graphic should be filled\n            endSize (int): The size of the end arrow in points\n            startSize (int): The size of the start arrow in points\n            jettySize (str or int): Length of the straight sections at the end of the edge. \"auto\" or a number\n            targetPerimeterSpacing (int): The negative or positive spacing between the target and end of the edge (points)\n            sourcePerimeterSpacing (int): The negative or positive spacing between the source and end of the edge (points)\n            entryX (int): From where along the X axis on the source object the edge originates (0-1)\n            entryY (int): From where along the Y axis on the source object the edge originates (0-1)\n            entryDx (int): Applies an offset in pixels to the X axis entry point\n            entryDy (int): Applies an offset in pixels to the Y axis entry point\n            exitX (int): From where along the X axis on the target object the edge originates (0-1)\n            exitY (int): From where along the Y axis on the target object the edge originates (0-1)\n            exitDx (int): Applies an offset in pixels to the X axis exit point\n            exitDy (int): Applies an offset in pixels to the Y axis exit point\n            strokeColor (str): The color of the border of the edge ('none', 'default', or hex color code)\n            fillColor (str): The color of the fill of the edge ('none', 'default', or hex color code)\n            jumpStyle (str): The line jump style ('arc', 'gap', 'sharp', 'line')\n            jumpSize (int): The size of the line jumps in points.\n            opacity (int): The opacity of the edge (0-100)\n        \"\"\"\n        super().__init__(**kwargs)\n        self.xml_class = \"mxCell\"\n\n        # Style\n        self.text_format = kwargs.get(\"text_format\", TextFormat())\n        self.waypoints = kwargs.get(\"waypoints\", \"orthogonal\")\n        self.connection = kwargs.get(\"connection\", \"line\")\n        self.pattern = kwargs.get(\"pattern\", \"solid\")\n        self.opacity = kwargs.get(\"opacity\", None)\n        self.strokeColor = kwargs.get(\"strokeColor\", None)\n        self.fillColor = kwargs.get(\"fillColor\", None)\n\n        # Line end\n        self.line_end_target = kwargs.get(\"line_end_target\", None)\n        self.line_end_source = kwargs.get(\"line_end_source\", None)\n        self.endFill_target = kwargs.get(\"endFill_target\", False)\n        self.endFill_source = kwargs.get(\"endFill_source\", False)\n        self.endSize = kwargs.get(\"endSize\", None)\n        self.startSize = kwargs.get(\"startSize\", None)\n\n        self.rounded = kwargs.get(\"rounded\", 0)\n        self.sketch = kwargs.get(\"sketch\", None)\n        self.shadow = kwargs.get(\"shadow\", None)\n        self.flowAnimation = kwargs.get(\"flowAnimation\", None)\n\n        self.jumpStyle = kwargs.get(\"jumpStyle\", None)\n        self.jumpSize = kwargs.get(\"jumpSize\", None)\n\n        # Connection and geometry\n        self.jettySize = kwargs.get(\"jettySize\", \"auto\")\n        self.geometry = EdgeGeometry()\n        self.edge = kwargs.get(\"edge\", 1)\n        self.targetPerimeterSpacing = kwargs.get(\"targetPerimeterSpacing\", None)\n        self.sourcePerimeterSpacing = kwargs.get(\"sourcePerimeterSpacing\", None)\n        self.source = kwargs.get(\"source\", None)\n        self.target = kwargs.get(\"target\", None)\n        self.entryX = kwargs.get(\"entryX\", None)\n        self.entryY = kwargs.get(\"entryY\", None)\n        self.entryDx = kwargs.get(\"entryDx\", None)\n        self.entryDy = kwargs.get(\"entryDy\", None)\n        self.exitX = kwargs.get(\"exitX\", None)\n        self.exitY = kwargs.get(\"exitY\", None)\n        self.exitDx = kwargs.get(\"exitDx\", None)\n        self.exitDy = kwargs.get(\"exitDy\", None)\n\n        # Label\n        self.label = kwargs.get(\"label\", None)\n        self.edge_axis_offset = kwargs.get(\"edge_offset\", None)\n        self.label_offset = kwargs.get(\"label_offset\", None)\n        self.label_position = kwargs.get(\"label_position\", None)\n\n    def __repr__(self):\n        name_str = \"{0} edge from {1} to {2}\".format(\n            self.__class__.__name__, self.source, self.target\n        )\n        return name_str\n\n    def __str__(self):\n        return self.__repr__()\n\n    def remove(self):\n        \"\"\"This function removes references to the Edge from its source and target objects then deletes the Edge.\"\"\"\n        if self.source is not None:\n            self.source.remove_out_edge(self)\n        if self.target is not None:\n            self.target.remove_in_edge(self)\n        del self\n\n    @property\n    def attributes(self):\n        \"\"\"Returns the XML attributes to be added to the tag for the object\n\n        Returns:\n            dict: Dictionary of object attributes and their values\n        \"\"\"\n        base_attr_dict = {\n            \"id\": self.id,\n            \"style\": self.style,\n            \"edge\": self.edge,\n            \"parent\": self.xml_parent_id,\n            \"source\": self.source_id,\n            \"target\": self.target_id,\n        }\n        if self.value is not None:\n            base_attr_dict[\"value\"] = self.value\n        return base_attr_dict\n\n    ###########################################################\n    # Source and Target Linking\n    ###########################################################\n\n    # Source\n    @property\n    def source(self):\n        \"\"\"The source object of the edge. Automatically adds the edge to the object when set and removes it when deleted.\n\n        Returns:\n            BaseDiagram: source object of the edge\n        \"\"\"\n        return self._source\n\n    @source.setter\n    def source(self, f):\n        if f is not None:\n            f.add_out_edge(self)\n            self._source = f\n\n    @source.deleter\n    def source(self):\n        self._source.remove_out_edge(self)\n        self._source = None\n\n    @property\n    def source_id(self):\n        \"\"\"The ID of the source object or 1 if no source is set\n\n        Returns:\n            int: Source object ID\n        \"\"\"\n        if self.source is not None:\n            return self.source.id\n        else:\n            return 1\n\n    # Target\n    @property\n    def target(self):\n        \"\"\"The target object of the edge. Automatically adds the edge to the object when set and removes it when deleted.\n\n        Returns:\n            BaseDiagram: target object of the edge\n        \"\"\"\n        return self._target\n\n    @target.setter\n    def target(self, f):\n        if f is not None:\n            f.add_in_edge(self)\n            self._target = f\n\n    @target.deleter\n    def target(self):\n        self._target.remove_in_edge(self)\n        self._target = None\n\n    @property\n    def target_id(self):\n        \"\"\"The ID of the target object or 1 if no target is set\n\n        Returns:\n            int: Target object ID\n        \"\"\"\n        if self.target is not None:\n            return self.target.id\n        else:\n            return 1\n\n    def add_point(self, x, y):\n        \"\"\"Add a point to the edge\n\n        Args:\n            x (int): The x coordinate of the point in pixels\n            y (int): The y coordinate of the point in pixels\n        \"\"\"\n        self.geometry.points.append(Point(x=x, y=y))\n\n    def add_point_pos(self, position):\n        \"\"\"Add a point to the edge by position tuple\n\n        Args:\n            position (tuple): A tuple of ints describing the x and y coordinates in pixels\n        \"\"\"\n        self.geometry.points.append(Point(x=position[0], y=position[1]))\n\n    ###########################################################\n    # Style properties\n    ###########################################################\n\n    @property\n    def style_attributes(self):\n        \"\"\"The style attributes to add to the style tag in the XML\n\n        Returns:\n            list: A list of style attributes\n        \"\"\"\n        return [\n            \"rounded\",\n            \"sketch\",\n            \"shadow\",\n            \"flowAnimation\",\n            \"jettySize\",\n            \"entryX\",\n            \"entryY\",\n            \"entryDx\",\n            \"entryDy\",\n            \"exitX\",\n            \"exitY\",\n            \"exitDx\",\n            \"exitDy\",\n            \"startArrow\",\n            \"endArrow\",\n            \"startFill\",\n            \"endFill\",\n            \"strokeColor\",\n            \"fillColor\",\n            \"jumpStyle\",\n            \"jumpSize\",\n            \"targetPerimeterSpacing\",\n            \"sourcePerimeterSpacing\",\n            \"endSize\",\n            \"startSize\",\n            \"opacity\",\n        ]\n\n    @property\n    def baseStyle(self):\n        \"\"\"Generates the baseStyle string from the connection style, waypoint style, pattern style, and base style string.\n\n        Returns:\n            str: Concatenated baseStyle string\n        \"\"\"\n        style_str = []\n        connection_style = style_str_from_dict(connection_db[self.connection])\n        if connection_style is not None and connection_style != \"\":\n            style_str.append(connection_style)\n\n        waypoint_style = style_str_from_dict(waypoints_db[self.waypoints])\n        if waypoint_style is not None and waypoint_style != \"\":\n            style_str.append(waypoint_style)\n\n        pattern_style = style_str_from_dict(pattern_db[self.pattern])\n        if pattern_style is not None and pattern_style != \"\":\n            style_str.append(pattern_style)\n\n        if len(style_str) == 0:\n            return None\n        else:\n            return \";\".join(style_str)\n\n    @property\n    def startArrow(self):\n        \"\"\"What graphic the edge should be rendered with at the source\n\n        Returns:\n            str: The source edge graphic\n        \"\"\"\n        return self.line_end_source\n\n    @startArrow.setter\n    def startArrow(self, val):\n        self.line_end_source = val\n\n    @property\n    def startFill(self):\n        \"\"\"Whether the graphic at the source should be filled\n\n        Returns:\n            bool: The source graphic fill\n        \"\"\"\n        if line_ends_db[self.line_end_source][\"fillable\"]:\n            return self.endFill_source\n        else:\n            return None\n\n    @property\n    def endArrow(self):\n        \"\"\"What graphic the edge should be rendered with at the target\n\n        Returns:\n            str: The target edge graphic\n        \"\"\"\n        return self.line_end_target\n\n    @endArrow.setter\n    def endArrow(self, val):\n        self.line_end_target = val\n\n    @property\n    def endFill(self):\n        \"\"\"Whether the graphic at the target should be filled\n\n        Returns:\n            bool: The target graphic fill\n        \"\"\"\n        if line_ends_db[self.line_end_target][\"fillable\"]:\n            return self.endFill_target\n        else:\n            return None\n\n    # Base Line Style\n\n    # Waypoints\n    @property\n    def waypoints(self):\n        \"\"\"The waypoint style. Checks if the passed in value is in the TOML database of waypoints before setting and throws a ValueError if not.\n\n        Returns:\n            str: The style of the waypoints\n        \"\"\"\n        return self._waypoints\n\n    @waypoints.setter\n    def waypoints(self, value):\n        if value in waypoints_db.keys():\n            self._waypoints = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of waypoints\")\n\n    # Connection\n    @property\n    def connection(self):\n        \"\"\"The connection style. Checks if the passed in value is in the TOML database of connections before setting and throws a ValueError if not.\n\n        Returns:\n            str: The style of the connections\n        \"\"\"\n        return self._connection\n\n    @connection.setter\n    def connection(self, value):\n        if value in connection_db.keys():\n            self._connection = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of connection\".format(value))\n\n    # Pattern\n    @property\n    def pattern(self):\n        \"\"\"The pattern style. Checks if the passed in value is in the TOML database of patterns before setting and throws a ValueError if not.\n\n        Returns:\n            str: The style of the patterns\n        \"\"\"\n        return self._pattern\n\n    @pattern.setter\n    def pattern(self, value):\n        if value in pattern_db.keys():\n            self._pattern = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of pattern\")\n\n    # Color properties (enforce value)\n    ## strokeColor\n    @property\n    def strokeColor(self):\n        return self._strokeColor\n\n    @strokeColor.setter\n    def strokeColor(self, value):\n        self._strokeColor = color_input_check(value)\n\n    @strokeColor.deleter\n    def strokeColor(self):\n        self._strokeColor = None\n\n    # fillColor\n    @property\n    def fillColor(self):\n        return self._fillColor\n\n    @fillColor.setter\n    def fillColor(self, value):\n        self._fillColor = color_input_check(value)\n\n    @fillColor.deleter\n    def fillColor(self):\n        self._fillColor = None\n\n    # Jump style (enforce value)\n    @property\n    def jumpStyle(self):\n        return self._jumpStyle\n\n    @jumpStyle.setter\n    def jumpStyle(self, value):\n        if value in [None, \"arc\", \"gap\", \"sharp\", \"line\"]:\n            self._jumpStyle = value\n        else:\n            raise ValueError(f\"'{value}' is not a permitted jumpStyle value!\")\n\n    @jumpStyle.deleter\n    def jumpStyle(self):\n        self._jumpStyle = None\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n\n    @property\n    def label(self):\n        \"\"\"The text to place on the label, aka its value.\"\"\"\n        return self.value\n\n    @label.setter\n    def label(self, value):\n        self.value = value\n\n    @label.deleter\n    def label(self):\n        self.value = None\n\n    @property\n    def label_offset(self):\n        \"\"\"How far the label is offset away from the axis of the edge in pixels\"\"\"\n        return self.geometry.y\n\n    @label_offset.setter\n    def label_offset(self, value):\n        self.geometry.y = value\n\n    @label_offset.deleter\n    def label_offset(self):\n        self.geometry.y = None\n\n    @property\n    def label_position(self):\n        \"\"\"Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center.\"\"\"\n        return self.geometry.x\n\n    @label_position.setter\n    def label_position(self, value):\n        self.geometry.x = value\n\n    @label_position.deleter\n    def label_position(self):\n        self.geometry.x = None\n\n    @property\n    def xml(self):\n        \"\"\"The opening and closing XML tags with the styling attributes included.\n\n        Returns:\n            str: _description_\n        \"\"\"\n        tag = self.xml_open_tag + \"\\n  \" + self.geometry.xml + \"\\n\" + self.xml_close_tag\n        return tag\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.attributes","title":"attributes property","text":"

Returns the XML attributes to be added to the tag for the object

Returns:

Name Type Description dict

Dictionary of object attributes and their values

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.baseStyle","title":"baseStyle property","text":"

Generates the baseStyle string from the connection style, waypoint style, pattern style, and base style string.

Returns:

Name Type Description str

Concatenated baseStyle string

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.connection","title":"connection property writable","text":"

The connection style. Checks if the passed in value is in the TOML database of connections before setting and throws a ValueError if not.

Returns:

Name Type Description str

The style of the connections

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.endArrow","title":"endArrow property writable","text":"

What graphic the edge should be rendered with at the target

Returns:

Name Type Description str

The target edge graphic

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.endFill","title":"endFill property","text":"

Whether the graphic at the target should be filled

Returns:

Name Type Description bool

The target graphic fill

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.label","title":"label deletable property writable","text":"

The text to place on the label, aka its value.

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.label_offset","title":"label_offset deletable property writable","text":"

How far the label is offset away from the axis of the edge in pixels

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.label_position","title":"label_position deletable property writable","text":"

Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center.

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.pattern","title":"pattern property writable","text":"

The pattern style. Checks if the passed in value is in the TOML database of patterns before setting and throws a ValueError if not.

Returns:

Name Type Description str

The style of the patterns

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.source","title":"source deletable property writable","text":"

The source object of the edge. Automatically adds the edge to the object when set and removes it when deleted.

Returns:

Name Type Description BaseDiagram

source object of the edge

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.source_id","title":"source_id property","text":"

The ID of the source object or 1 if no source is set

Returns:

Name Type Description int

Source object ID

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.startArrow","title":"startArrow property writable","text":"

What graphic the edge should be rendered with at the source

Returns:

Name Type Description str

The source edge graphic

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.startFill","title":"startFill property","text":"

Whether the graphic at the source should be filled

Returns:

Name Type Description bool

The source graphic fill

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.style_attributes","title":"style_attributes property","text":"

The style attributes to add to the style tag in the XML

Returns:

Name Type Description list

A list of style attributes

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.target","title":"target deletable property writable","text":"

The target object of the edge. Automatically adds the edge to the object when set and removes it when deleted.

Returns:

Name Type Description BaseDiagram

target object of the edge

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.target_id","title":"target_id property","text":"

The ID of the target object or 1 if no target is set

Returns:

Name Type Description int

Target object ID

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.waypoints","title":"waypoints property writable","text":"

The waypoint style. Checks if the passed in value is in the TOML database of waypoints before setting and throws a ValueError if not.

Returns:

Name Type Description str

The style of the waypoints

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.xml","title":"xml property","text":"

The opening and closing XML tags with the styling attributes included.

Returns:

Name Type Description str

description

"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.__init__","title":"__init__(**kwargs)","text":"

Edges can be initialized with almost all styling parameters as args. See Usage - Edges for more information and the options for each parameter.

Parameters:

Name Type Description Default source DiagramBase

The Draw.io object that the edge originates from

required target DiagramBase

The Draw.io object that the edge points to

required label str

The text to place on the edge.

required label_position float

Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center

required label_offset int

How far the label is offset away from the axis of the edge in pixels

required waypoints str

How the edge should be styled in Draw.io

required connection str

What type of style the edge should be rendered with

required pattern str

How the line of the edge should be rendered

required shadow bool

Add a shadow to the edge

required rounded bool

Whether the corner of the line should be rounded

required flowAnimation bool

Add a marching ants animation along the edge

required sketch bool

Add sketch styling to the edge

required line_end_target str

What graphic the edge should be rendered with at the target

required line_end_source str

What graphic the edge should be rendered with at the source

required endFill_target boolean

Whether the target graphic should be filled

required endFill_source boolean

Whether the source graphic should be filled

required endSize int

The size of the end arrow in points

required startSize int

The size of the start arrow in points

required jettySize str or int

Length of the straight sections at the end of the edge. \"auto\" or a number

required targetPerimeterSpacing int

The negative or positive spacing between the target and end of the edge (points)

required sourcePerimeterSpacing int

The negative or positive spacing between the source and end of the edge (points)

required entryX int

From where along the X axis on the source object the edge originates (0-1)

required entryY int

From where along the Y axis on the source object the edge originates (0-1)

required entryDx int

Applies an offset in pixels to the X axis entry point

required entryDy int

Applies an offset in pixels to the Y axis entry point

required exitX int

From where along the X axis on the target object the edge originates (0-1)

required exitY int

From where along the Y axis on the target object the edge originates (0-1)

required exitDx int

Applies an offset in pixels to the X axis exit point

required exitDy int

Applies an offset in pixels to the Y axis exit point

required strokeColor str

The color of the border of the edge ('none', 'default', or hex color code)

required fillColor str

The color of the fill of the edge ('none', 'default', or hex color code)

required jumpStyle str

The line jump style ('arc', 'gap', 'sharp', 'line')

required jumpSize int

The size of the line jumps in points.

required opacity int

The opacity of the edge (0-100)

required Source code in src/drawpyo/diagram/edges.py
def __init__(self, **kwargs):\n    \"\"\"Edges can be initialized with almost all styling parameters as args.\n    See [Usage - Edges](../../usage/edges) for more information and the options for each parameter.\n\n    Args:\n        source (DiagramBase): The Draw.io object that the edge originates from\n        target (DiagramBase): The Draw.io object that the edge points to\n        label (str): The text to place on the edge.\n        label_position (float): Where along the edge the label is positioned. -1 is the source, 1 is the target, 0 is the center\n        label_offset (int): How far the label is offset away from the axis of the edge in pixels\n        waypoints (str): How the edge should be styled in Draw.io\n        connection (str): What type of style the edge should be rendered with\n        pattern (str): How the line of the edge should be rendered\n        shadow (bool, optional): Add a shadow to the edge\n        rounded (bool): Whether the corner of the line should be rounded\n        flowAnimation (bool): Add a marching ants animation along the edge\n        sketch (bool, optional): Add sketch styling to the edge\n        line_end_target (str): What graphic the edge should be rendered with at the target\n        line_end_source (str): What graphic the edge should be rendered with at the source\n        endFill_target (boolean): Whether the target graphic should be filled\n        endFill_source (boolean): Whether the source graphic should be filled\n        endSize (int): The size of the end arrow in points\n        startSize (int): The size of the start arrow in points\n        jettySize (str or int): Length of the straight sections at the end of the edge. \"auto\" or a number\n        targetPerimeterSpacing (int): The negative or positive spacing between the target and end of the edge (points)\n        sourcePerimeterSpacing (int): The negative or positive spacing between the source and end of the edge (points)\n        entryX (int): From where along the X axis on the source object the edge originates (0-1)\n        entryY (int): From where along the Y axis on the source object the edge originates (0-1)\n        entryDx (int): Applies an offset in pixels to the X axis entry point\n        entryDy (int): Applies an offset in pixels to the Y axis entry point\n        exitX (int): From where along the X axis on the target object the edge originates (0-1)\n        exitY (int): From where along the Y axis on the target object the edge originates (0-1)\n        exitDx (int): Applies an offset in pixels to the X axis exit point\n        exitDy (int): Applies an offset in pixels to the Y axis exit point\n        strokeColor (str): The color of the border of the edge ('none', 'default', or hex color code)\n        fillColor (str): The color of the fill of the edge ('none', 'default', or hex color code)\n        jumpStyle (str): The line jump style ('arc', 'gap', 'sharp', 'line')\n        jumpSize (int): The size of the line jumps in points.\n        opacity (int): The opacity of the edge (0-100)\n    \"\"\"\n    super().__init__(**kwargs)\n    self.xml_class = \"mxCell\"\n\n    # Style\n    self.text_format = kwargs.get(\"text_format\", TextFormat())\n    self.waypoints = kwargs.get(\"waypoints\", \"orthogonal\")\n    self.connection = kwargs.get(\"connection\", \"line\")\n    self.pattern = kwargs.get(\"pattern\", \"solid\")\n    self.opacity = kwargs.get(\"opacity\", None)\n    self.strokeColor = kwargs.get(\"strokeColor\", None)\n    self.fillColor = kwargs.get(\"fillColor\", None)\n\n    # Line end\n    self.line_end_target = kwargs.get(\"line_end_target\", None)\n    self.line_end_source = kwargs.get(\"line_end_source\", None)\n    self.endFill_target = kwargs.get(\"endFill_target\", False)\n    self.endFill_source = kwargs.get(\"endFill_source\", False)\n    self.endSize = kwargs.get(\"endSize\", None)\n    self.startSize = kwargs.get(\"startSize\", None)\n\n    self.rounded = kwargs.get(\"rounded\", 0)\n    self.sketch = kwargs.get(\"sketch\", None)\n    self.shadow = kwargs.get(\"shadow\", None)\n    self.flowAnimation = kwargs.get(\"flowAnimation\", None)\n\n    self.jumpStyle = kwargs.get(\"jumpStyle\", None)\n    self.jumpSize = kwargs.get(\"jumpSize\", None)\n\n    # Connection and geometry\n    self.jettySize = kwargs.get(\"jettySize\", \"auto\")\n    self.geometry = EdgeGeometry()\n    self.edge = kwargs.get(\"edge\", 1)\n    self.targetPerimeterSpacing = kwargs.get(\"targetPerimeterSpacing\", None)\n    self.sourcePerimeterSpacing = kwargs.get(\"sourcePerimeterSpacing\", None)\n    self.source = kwargs.get(\"source\", None)\n    self.target = kwargs.get(\"target\", None)\n    self.entryX = kwargs.get(\"entryX\", None)\n    self.entryY = kwargs.get(\"entryY\", None)\n    self.entryDx = kwargs.get(\"entryDx\", None)\n    self.entryDy = kwargs.get(\"entryDy\", None)\n    self.exitX = kwargs.get(\"exitX\", None)\n    self.exitY = kwargs.get(\"exitY\", None)\n    self.exitDx = kwargs.get(\"exitDx\", None)\n    self.exitDy = kwargs.get(\"exitDy\", None)\n\n    # Label\n    self.label = kwargs.get(\"label\", None)\n    self.edge_axis_offset = kwargs.get(\"edge_offset\", None)\n    self.label_offset = kwargs.get(\"label_offset\", None)\n    self.label_position = kwargs.get(\"label_position\", None)\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.add_point","title":"add_point(x, y)","text":"

Add a point to the edge

Parameters:

Name Type Description Default x int

The x coordinate of the point in pixels

required y int

The y coordinate of the point in pixels

required Source code in src/drawpyo/diagram/edges.py
def add_point(self, x, y):\n    \"\"\"Add a point to the edge\n\n    Args:\n        x (int): The x coordinate of the point in pixels\n        y (int): The y coordinate of the point in pixels\n    \"\"\"\n    self.geometry.points.append(Point(x=x, y=y))\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.add_point_pos","title":"add_point_pos(position)","text":"

Add a point to the edge by position tuple

Parameters:

Name Type Description Default position tuple

A tuple of ints describing the x and y coordinates in pixels

required Source code in src/drawpyo/diagram/edges.py
def add_point_pos(self, position):\n    \"\"\"Add a point to the edge by position tuple\n\n    Args:\n        position (tuple): A tuple of ints describing the x and y coordinates in pixels\n    \"\"\"\n    self.geometry.points.append(Point(x=position[0], y=position[1]))\n
"},{"location":"api/edges/#src.drawpyo.diagram.edges.Edge.remove","title":"remove()","text":"

This function removes references to the Edge from its source and target objects then deletes the Edge.

Source code in src/drawpyo/diagram/edges.py
def remove(self):\n    \"\"\"This function removes references to the Edge from its source and target objects then deletes the Edge.\"\"\"\n    if self.source is not None:\n        self.source.remove_out_edge(self)\n    if self.target is not None:\n        self.target.remove_in_edge(self)\n    del self\n
"},{"location":"api/file/","title":"File","text":""},{"location":"api/file/#src.drawpyo.file.File","title":"src.drawpyo.file.File","text":"

Bases: XMLBase

The File class defines a Draw.io file, its properties, and the methods required for saving it.

Source code in src/drawpyo/file.py
class File(XMLBase):\n    \"\"\"The File class defines a Draw.io file, its properties, and the methods required for saving it.\"\"\"\n\n    def __init__(\n        self,\n        file_name=\"Drawpyo Diagram.drawio\",\n        file_path=path.join(path.expanduser(\"~\"), \"Drawpyo Charts\"),\n    ):\n        \"\"\"To initiate a File object, pass in a name and path or leave it to the defaults.\n\n        Args:\n            file_name (str, optional): The name of the file.\n            file_path (str, optional): The location where the file will be saved.\n        \"\"\"\n\n        super().__init__()\n\n        self.pages = []\n        self.file_name = file_name\n        self.file_path = file_path\n\n        # Attributes\n        self.host = \"Drawpyo\"\n        self.type = \"device\"\n        self.version = \"21.6.5\"  # This is the version of the Draw.io spec\n        self.xml_class = \"mxfile\"\n\n    def __repr__(self):\n        return f\"drawpyo File - {self.file_name}\"\n\n    @property\n    def attributes(self):\n        return {\n            \"host\": self.host,\n            \"modified\": self.modified,\n            \"agent\": self.agent,\n            \"etag\": self.etag,\n            \"version\": self.version,\n            \"type\": self.type,\n        }\n\n    def add_page(self, page):\n        \"\"\"Add a page to the file.\n\n        Args:\n            page (drawpyo.diagram.Page): A Page object\n        \"\"\"\n        page._file = self\n        self.pages.append(page)\n\n    def remove_page(self, page):\n        \"\"\"Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.\n\n        Args:\n            page (drawpyo.diagram.Page or str or int): A Page object that's currently contained in the file\n        \"\"\"\n        if isinstance(page, int):\n            del self.pages[page]\n        elif isinstance(page, str):\n            for pg in self.pages:\n                if pg.name == page:\n                    self.pages.remove(pg)\n        elif isinstance(page, Page):\n            self.pages.remove(page)\n\n    ###########################################################\n    # File Properties\n    ###########################################################\n\n    @property\n    def modified(self):\n        return datetime.now().strftime(\"%Y-%m-%dT%H:%M:%S\")\n\n    @property\n    def agent(self):\n        python_version = f\"{version_info.major}.{version_info.minor}\"\n        drawpyo_version = f\"0.01\"\n        return f\"Python {python_version}, Drawpyo {drawpyo_version}\"\n\n    @property\n    def etag(self):\n        # etag is in the Draw.io spec but not sure how it's used or if I need to create it\n        return None\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n\n    @property\n    def xml(self):\n        \"\"\"This function goes through each page in the file, retrieves its XML, and appends it to a list, then wraps that list in the file's open and close tags.\n\n        Returns:\n            str: The XML data for the file and all the pages in it\n        \"\"\"\n        xml_string = self.xml_open_tag\n        for diag in self.pages:\n            xml_string = xml_string + \"\\n  \" + diag.xml\n        xml_string = xml_string + \"\\n\" + self.xml_close_tag\n        return xml_string\n\n    ###########################################################\n    # File Handling\n    ###########################################################\n    def write(self, **kwargs):\n        \"\"\"This function write the file to disc at the path and name specified.\n\n        Args:\n            file_path (str, opt): The path to save the file in\n            file_name (str, opt): The name of the file\n            overwrite (bool, opt): Whether to overwrite an existing file or not\n        \"\"\"\n\n        # Check if file_path or file_name were passed in, or are preexisting\n        self.file_path = kwargs.get(\"file_path\", self.file_path)\n\n        self.file_name = kwargs.get(\"file_name\", self.file_name)\n\n        overwrite = kwargs.get(\"overwrite\", True)\n        if overwrite:\n            write_mode = \"w\"\n        else:\n            write_mode = \"x\"\n\n        if not path.exists(self.file_path):\n            makedirs(self.file_path)\n\n        f = open(\n            path.join(self.file_path, self.file_name), write_mode, encoding=\"utf-8\"\n        )\n        f.write(self.xml)\n        f.close\n\n        return path.join(self.file_path, self.file_name)\n
"},{"location":"api/file/#src.drawpyo.file.File.xml","title":"xml property","text":"

This function goes through each page in the file, retrieves its XML, and appends it to a list, then wraps that list in the file's open and close tags.

Returns:

Name Type Description str

The XML data for the file and all the pages in it

"},{"location":"api/file/#src.drawpyo.file.File.__init__","title":"__init__(file_name='Drawpyo Diagram.drawio', file_path=path.join(path.expanduser('~'), 'Drawpyo Charts'))","text":"

To initiate a File object, pass in a name and path or leave it to the defaults.

Parameters:

Name Type Description Default file_name str

The name of the file.

'Drawpyo Diagram.drawio' file_path str

The location where the file will be saved.

join(expanduser('~'), 'Drawpyo Charts') Source code in src/drawpyo/file.py
def __init__(\n    self,\n    file_name=\"Drawpyo Diagram.drawio\",\n    file_path=path.join(path.expanduser(\"~\"), \"Drawpyo Charts\"),\n):\n    \"\"\"To initiate a File object, pass in a name and path or leave it to the defaults.\n\n    Args:\n        file_name (str, optional): The name of the file.\n        file_path (str, optional): The location where the file will be saved.\n    \"\"\"\n\n    super().__init__()\n\n    self.pages = []\n    self.file_name = file_name\n    self.file_path = file_path\n\n    # Attributes\n    self.host = \"Drawpyo\"\n    self.type = \"device\"\n    self.version = \"21.6.5\"  # This is the version of the Draw.io spec\n    self.xml_class = \"mxfile\"\n
"},{"location":"api/file/#src.drawpyo.file.File.add_page","title":"add_page(page)","text":"

Add a page to the file.

Parameters:

Name Type Description Default page Page

A Page object

required Source code in src/drawpyo/file.py
def add_page(self, page):\n    \"\"\"Add a page to the file.\n\n    Args:\n        page (drawpyo.diagram.Page): A Page object\n    \"\"\"\n    page._file = self\n    self.pages.append(page)\n
"},{"location":"api/file/#src.drawpyo.file.File.remove_page","title":"remove_page(page)","text":"

Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.

Parameters:

Name Type Description Default page Page or str or int

A Page object that's currently contained in the file

required Source code in src/drawpyo/file.py
def remove_page(self, page):\n    \"\"\"Remove a page from the file. The page argument can be either a Page object, the integer number of the page, or the string name of the page.\n\n    Args:\n        page (drawpyo.diagram.Page or str or int): A Page object that's currently contained in the file\n    \"\"\"\n    if isinstance(page, int):\n        del self.pages[page]\n    elif isinstance(page, str):\n        for pg in self.pages:\n            if pg.name == page:\n                self.pages.remove(pg)\n    elif isinstance(page, Page):\n        self.pages.remove(page)\n
"},{"location":"api/file/#src.drawpyo.file.File.write","title":"write(**kwargs)","text":"

This function write the file to disc at the path and name specified.

Parameters:

Name Type Description Default file_path (str, opt)

The path to save the file in

required file_name (str, opt)

The name of the file

required overwrite (bool, opt)

Whether to overwrite an existing file or not

required Source code in src/drawpyo/file.py
def write(self, **kwargs):\n    \"\"\"This function write the file to disc at the path and name specified.\n\n    Args:\n        file_path (str, opt): The path to save the file in\n        file_name (str, opt): The name of the file\n        overwrite (bool, opt): Whether to overwrite an existing file or not\n    \"\"\"\n\n    # Check if file_path or file_name were passed in, or are preexisting\n    self.file_path = kwargs.get(\"file_path\", self.file_path)\n\n    self.file_name = kwargs.get(\"file_name\", self.file_name)\n\n    overwrite = kwargs.get(\"overwrite\", True)\n    if overwrite:\n        write_mode = \"w\"\n    else:\n        write_mode = \"x\"\n\n    if not path.exists(self.file_path):\n        makedirs(self.file_path)\n\n    f = open(\n        path.join(self.file_path, self.file_name), write_mode, encoding=\"utf-8\"\n    )\n    f.write(self.xml)\n    f.close\n\n    return path.join(self.file_path, self.file_name)\n
"},{"location":"api/objects/","title":"Objects","text":""},{"location":"api/objects/#object-creation","title":"Object Creation","text":""},{"location":"api/objects/#object_from_library","title":"object_from_library","text":""},{"location":"api/objects/#src.drawpyo.diagram.objects.object_from_library","title":"src.drawpyo.diagram.objects.object_from_library(library, obj_name, **kwargs)","text":"

This function generates an Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.

Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. These keyword arguments will overwrite any attributes defined in the library.

Parameters:

Name Type Description Default library str or dict

The library containing the object

required obj_name str

The name of the object in the library to generate

required

Returns:

Name Type Description Object

An object with the style from the library

Source code in src/drawpyo/diagram/objects.py
def object_from_library(library, obj_name, **kwargs):\n    \"\"\"This function generates an Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n    Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. These keyword arguments will overwrite any attributes defined in the library.\n\n    Args:\n        library (str or dict): The library containing the object\n        obj_name (str): The name of the object in the library to generate\n\n    Returns:\n        Object: An object with the style from the library\n    \"\"\"\n    new_obj = Object(**kwargs)\n    new_obj.format_as_library_object(library, obj_name)\n    new_obj.apply_attribute_dict(kwargs)\n    return new_obj\n
"},{"location":"api/objects/#object","title":"Object","text":""},{"location":"api/objects/#src.drawpyo.diagram.objects.Object","title":"src.drawpyo.diagram.objects.Object","text":"

Bases: DiagramBase

The Object class is the base object for all shapes in Draw.io.

More information about objects are in the Usage documents at Usage - Objects.

Source code in src/drawpyo/diagram/objects.py
class Object(DiagramBase):\n    \"\"\"\n    The Object class is the base object for all shapes in Draw.io.\n\n    More information about objects are in the Usage documents at [Usage - Objects](../../usage/objects).\n    \"\"\"\n\n    ###########################################################\n    # Initialization Functions\n    ###########################################################\n\n    def __init__(self, value=\"\", position=(0, 0), **kwargs):\n        \"\"\"A Object can be initialized with as many or as few of its styling attributes as is desired.\n\n        Args:\n            value (str, optional): The text to fill the object with. Defaults to \"\".\n            position (tuple, optional): The position of the object in pixels, in (X, Y). Defaults to (0, 0).\n\n        Keyword Args:\n            width (int, optional): The width of the object in pixels. Defaults to 120.\n            height (int, optional): The height of the object in pixels. Defaults to 80.\n            template_object (Object, optional): Another object to copy the style_attributes from\n            aspect\n            rounded (bool, optional): Whether to round the corners of the shape\n            whiteSpace (str, optional): white space\n            fillColor (str, optional): The object fill color in a hex color code (#ffffff)\n            opacity  (int, optional): The object's opacity, 0-100\n            strokeColor: The object stroke color in a hex color code (#ffffff)\n            glass (bool, optional): Apply glass styling to  the object\n            shadow (bool, optional): Add a shadow to the object\n            sketch (bool, optional): Add sketch styling to the object\n            comic (bool, optional): Add comic styling to the object\n            line_pattern (str, optional): The stroke style of the object.\n        \"\"\"\n        super().__init__(**kwargs)\n        self._style_attributes = [\n            \"whiteSpace\",\n            \"rounded\",\n            \"fillColor\",\n            \"strokeColor\",\n            \"glass\",\n            \"shadow\",\n            \"comic\",\n            \"sketch\",\n            \"opacity\",\n            \"dashed\",\n        ]\n\n        # Geometry\n        self.geometry = Geometry(parent_object=self)\n        self.position = kwargs.get(\"position\", (0, 0))\n        self.width = kwargs.get(\"width\", 120)\n        self.height = kwargs.get(\"height\", 80)\n        self.vertex = kwargs.get(\"vertex\", 1)\n\n        # TODO enumerate to fixed\n        self.aspect = kwargs.get(\"aspect\", None)\n\n        # Content\n        self.text_format = kwargs.get(\"text_format\", TextFormat())\n        self.value = value\n\n        # Style\n        self.baseStyle = kwargs.get(\"baseStyle\", None)\n\n        self.rounded = kwargs.get(\"rounded\", 0)\n        self.whiteSpace = kwargs.get(\"whiteSpace\", \"wrap\")\n        self.opacity = kwargs.get(\"opacity\", None)\n        self.strokeColor = kwargs.get(\"strokeColor\", None)\n        self.fillColor = kwargs.get(\"fillColor\", None)\n        self.glass = kwargs.get(\"glass\", None)\n        self.shadow = kwargs.get(\"shadow\", None)\n        self.comic = kwargs.get(\"comic\", None)\n        self.sketch = kwargs.get(\"sketch\", None)\n        self.line_pattern = kwargs.get(\"line_pattern\", \"solid\")\n\n        self.out_edges = kwargs.get(\"out_edges\", [])\n        self.in_edges = kwargs.get(\"in_edges\", [])\n\n        self.xml_class = \"mxCell\"\n\n        if \"template_object\" in kwargs:\n            self.template_object = kwargs.get(\"template_object\")\n            self._apply_style_from_template(self.template_object)\n            self.width = self.template_object.width\n            self.height = self.template_object.height\n\n    def __repr__(self):\n        if self.value != \"\":\n            name_str = \"{0} object with value {1}\".format(\n                self.__class__.__name__, self.value\n            )\n        else:\n            name_str = \"{0} object\".format(self.__class__.__name__)\n        return name_str\n\n    def __str_(self):\n        return self.__repr__()\n\n    @classmethod\n    def create_from_template_object(\n        cls, template_object, value=None, position=None, page=None\n    ):\n        \"\"\"Object can be instantiated from another object. This will initialize the Object with the same formatting, then set a new position and value.\n\n        Args:\n            template_object (Object): Another drawpyo Object to use as a template\n            value (str, optional): The text contents of the object. Defaults to None.\n            position (tuple, optional): The position where the object should be placed. Defaults to (0, 0).\n            page (Page, optional): The Page object to place the object on. Defaults to None.\n\n        Returns:\n            Object: The newly created object\n        \"\"\"\n        new_obj = cls(\n            value=value,\n            page=page,\n            width=template_object.width,\n            height=template_object.height,\n            template_object=template_object,\n        )\n        if position is not None:\n            new_obj.position = position\n        if value is not None:\n            new_obj.value = value\n        return new_obj\n\n    @classmethod\n    def create_from_style_string(cls, style_string):\n        \"\"\"Objects can be instantiated from a style string. These strings are most easily found in the Draw.io app, by styling an object as desired then right-clicking and selecting \"Edit Style\". Copying that text into this function will generate an object styled the same.\n\n        Args:\n            style_string (str): A Draw.io generated style string.\n\n        Returns:\n            Object: An object formatted with the style string\n        \"\"\"\n        cls.apply_style_from_string(style_string)\n        return cls\n\n    @classmethod\n    def create_from_library(cls, library, obj_name):\n        \"\"\"This function generates a Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n        Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. However, the styling in the library will overwrite that formatting.\n\n        Args:\n            library (str or dict): The library containing the object\n            obj_name (str): The name of the object in the library to generate\n\n        Returns:\n            Object: An object with the style from the library\n        \"\"\"\n        new_obj = cls()\n        new_obj.format_as_library_object(library, obj_name)\n        return new_obj\n\n    def format_as_library_object(self, library, obj_name):\n        \"\"\"This function applies the style from a library to an existing object. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n        Args:\n            library (str or dict): The library containing the object\n            obj_name (str): The name of the object in the library to generate\n        \"\"\"\n        if type(library) == str:\n            if library in base_libraries:\n                library_dict = base_libraries[library]\n                if obj_name in library_dict:\n                    obj_dict = library_dict[obj_name]\n                    self.apply_attribute_dict(obj_dict)\n                else:\n                    raise ValueError(\n                        \"Object {0} not in Library {1}\".format(obj_name, library)\n                    )\n            else:\n                raise ValueError(\"Library {0} not in base_libraries\".format(library))\n        elif type(library) == dict:\n            obj_dict = library[obj_name]\n            self.apply_attribute_dict(obj_dict)\n        else:\n            raise ValueError(\"Unparseable libary passed in.\")\n\n    @property\n    def attributes(self):\n        return {\n            \"id\": self.id,\n            \"value\": self.value,\n            \"style\": self.style,\n            \"vertex\": self.vertex,\n            \"parent\": self.xml_parent_id,\n        }\n\n    ###########################################################\n    # Style templates\n    ###########################################################\n\n    @property\n    def line_styles(self):\n        return line_styles\n\n    @property\n    def container(self):\n        return container\n\n    ###########################################################\n    # Style properties\n    ###########################################################\n\n    @property\n    def line_pattern(self):\n        \"\"\"Two properties are enumerated together into line_pattern: dashed and dashPattern. line_pattern simplifies this with an external database that contains the dropdown options from the Draw.io app then outputs the correct combination of dashed and dashPattern.\n\n        However in some cases dashed and dashpattern need to be set individually, such as when formatting from a style string. In that case, the setters for those two attributes will disable the other.\n\n        Returns:\n            str: The line style\n        \"\"\"\n        return self._line_pattern\n\n    @line_pattern.setter\n    def line_pattern(self, value):\n        if value in line_styles.keys():\n            self._line_pattern = value\n        else:\n            raise ValueError(\n                \"{0} is not an allowed value of line_pattern\".format(value)\n            )\n\n    @property\n    def dashed(self):\n        \"\"\"This is one of the properties that defines the line style. Along with dashPattern, it can be overriden by setting line_pattern or set directly.\n\n        Returns:\n            str: Whether the object stroke is dashed.\n        \"\"\"\n        if self._line_pattern is None:\n            return self._dashed\n        else:\n            return line_styles[self._line_pattern]\n\n    @dashed.setter\n    def dashed(self, value):\n        self._line_pattern = None\n        self._dashed = value\n\n    @property\n    def dashPattern(self):\n        \"\"\"This is one of the properties that defines the line style. Along with dashed, it can be overriden by setting line_pattern or set directly.\n\n        Returns:\n            str: What style the object stroke is dashed with.\n        \"\"\"\n        if self._line_pattern is None:\n            return self._dashed\n        else:\n            return line_styles[self._line_pattern]\n\n    @dashPattern.setter\n    def dashPattern(self, value):\n        self._line_pattern = None\n        self._dashPattern = value\n\n    ###########################################################\n    # Geometry properties\n    ###########################################################\n\n    @property\n    def width(self):\n        \"\"\"This property makes geometry.width available to the owning class for ease of access.\"\"\"\n        return self.geometry.width\n\n    @width.setter\n    def width(self, value):\n        self.geometry.width = value\n\n    @property\n    def height(self):\n        \"\"\"This property makes geometry.height available to the owning class for ease of access.\"\"\"\n        return self.geometry.height\n\n    @height.setter\n    def height(self, value):\n        self.geometry.height = value\n\n    # Position property\n    @property\n    def position(self):\n        \"\"\"The position of the object on the page. This is the top left corner. It's set with a tuple of ints, X and Y respectively.\n\n        (X, Y)\n\n        Returns:\n            tuple: A tuple of ints describing the top left corner position of the object\n        \"\"\"\n        return (self.geometry.x, self.geometry.y)\n\n    @position.setter\n    def position(self, value):\n        self.geometry.x = value[0]\n        self.geometry.y = value[1]\n\n    @property\n    def center_position(self):\n        \"\"\"The position of the object on the page. This is the center of the object. It's set with a tuple of ints, X and Y respectively.\n\n        (X, Y)\n\n        Returns:\n            tuple: A tuple of ints describing the center position of the object\n        \"\"\"\n        x = self.geometry.x + self.geometry.width / 2\n        y = self.geometry.y + self.geometry.height / 2\n        return (x, y)\n\n    @center_position.setter\n    def center_position(self, position):\n        self.geometry.x = position[0] - self.geometry.width / 2\n        self.geometry.y = position[1] - self.geometry.height / 2\n\n    ###########################################################\n    # Edge Tracking\n    ###########################################################\n\n    def add_out_edge(self, edge):\n        \"\"\"Add an edge out of the object. If an edge is created with this object set as the source this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object originating at this object\n        \"\"\"\n        self.out_edges.append(edge)\n\n    def remove_out_edge(self, edge):\n        \"\"\"Remove an edge out of the object. If an edge linked to this object has the source changed or removed this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object originating at this object\n        \"\"\"\n        self.out_edges.remove(edge)\n\n    def add_in_edge(self, edge):\n        \"\"\"Add an edge into the object. If an edge is created with this object set as the target this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object ending at this object\n        \"\"\"\n        self.in_edges.append(edge)\n\n    def remove_in_edge(self, edge):\n        \"\"\"Remove an edge into the object. If an edge linked to this object has the target changed or removed this function will be called automatically.\n\n        Args:\n            edge (Edge): An Edge object ending at this object\n        \"\"\"\n        self.in_edges.remove(edge)\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n\n    @property\n    def xml(self):\n        \"\"\"\n        Returns the XML object for the Object: the opening tag with the style attributes, the value, and the closing tag.\n\n        Example:\n        <class_name attribute_name=attribute_value>Text in object</class_name>\n\n        Returns:\n            str: A single XML tag containing the object name, style attributes, and a closer.\n        \"\"\"\n        tag = self.xml_open_tag + \"\\n  \" + self.geometry.xml + \"\\n\" + self.xml_close_tag\n        return tag\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.center_position","title":"center_position property writable","text":"

The position of the object on the page. This is the center of the object. It's set with a tuple of ints, X and Y respectively.

(X, Y)

Returns:

Name Type Description tuple

A tuple of ints describing the center position of the object

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.dashPattern","title":"dashPattern property writable","text":"

This is one of the properties that defines the line style. Along with dashed, it can be overriden by setting line_pattern or set directly.

Returns:

Name Type Description str

What style the object stroke is dashed with.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.dashed","title":"dashed property writable","text":"

This is one of the properties that defines the line style. Along with dashPattern, it can be overriden by setting line_pattern or set directly.

Returns:

Name Type Description str

Whether the object stroke is dashed.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.height","title":"height property writable","text":"

This property makes geometry.height available to the owning class for ease of access.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.line_pattern","title":"line_pattern property writable","text":"

Two properties are enumerated together into line_pattern: dashed and dashPattern. line_pattern simplifies this with an external database that contains the dropdown options from the Draw.io app then outputs the correct combination of dashed and dashPattern.

However in some cases dashed and dashpattern need to be set individually, such as when formatting from a style string. In that case, the setters for those two attributes will disable the other.

Returns:

Name Type Description str

The line style

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.position","title":"position property writable","text":"

The position of the object on the page. This is the top left corner. It's set with a tuple of ints, X and Y respectively.

(X, Y)

Returns:

Name Type Description tuple

A tuple of ints describing the top left corner position of the object

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.width","title":"width property writable","text":"

This property makes geometry.width available to the owning class for ease of access.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.xml","title":"xml property","text":"

Returns the XML object for the Object: the opening tag with the style attributes, the value, and the closing tag.

Example: Text in object

Returns:

Name Type Description str

A single XML tag containing the object name, style attributes, and a closer.

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.__init__","title":"__init__(value='', position=(0, 0), **kwargs)","text":"

A Object can be initialized with as many or as few of its styling attributes as is desired.

Parameters:

Name Type Description Default value str

The text to fill the object with. Defaults to \"\".

'' position tuple

The position of the object in pixels, in (X, Y). Defaults to (0, 0).

(0, 0)

Other Parameters:

Name Type Description width int

The width of the object in pixels. Defaults to 120.

height int

The height of the object in pixels. Defaults to 80.

template_object Object

Another object to copy the style_attributes from

rounded bool

Whether to round the corners of the shape

whiteSpace str

white space

fillColor str

The object fill color in a hex color code (#ffffff)

opacity (int

The object's opacity, 0-100

strokeColor

The object stroke color in a hex color code (#ffffff)

glass bool

Apply glass styling to the object

shadow bool

Add a shadow to the object

sketch bool

Add sketch styling to the object

comic bool

Add comic styling to the object

line_pattern str

The stroke style of the object.

Source code in src/drawpyo/diagram/objects.py
def __init__(self, value=\"\", position=(0, 0), **kwargs):\n    \"\"\"A Object can be initialized with as many or as few of its styling attributes as is desired.\n\n    Args:\n        value (str, optional): The text to fill the object with. Defaults to \"\".\n        position (tuple, optional): The position of the object in pixels, in (X, Y). Defaults to (0, 0).\n\n    Keyword Args:\n        width (int, optional): The width of the object in pixels. Defaults to 120.\n        height (int, optional): The height of the object in pixels. Defaults to 80.\n        template_object (Object, optional): Another object to copy the style_attributes from\n        aspect\n        rounded (bool, optional): Whether to round the corners of the shape\n        whiteSpace (str, optional): white space\n        fillColor (str, optional): The object fill color in a hex color code (#ffffff)\n        opacity  (int, optional): The object's opacity, 0-100\n        strokeColor: The object stroke color in a hex color code (#ffffff)\n        glass (bool, optional): Apply glass styling to  the object\n        shadow (bool, optional): Add a shadow to the object\n        sketch (bool, optional): Add sketch styling to the object\n        comic (bool, optional): Add comic styling to the object\n        line_pattern (str, optional): The stroke style of the object.\n    \"\"\"\n    super().__init__(**kwargs)\n    self._style_attributes = [\n        \"whiteSpace\",\n        \"rounded\",\n        \"fillColor\",\n        \"strokeColor\",\n        \"glass\",\n        \"shadow\",\n        \"comic\",\n        \"sketch\",\n        \"opacity\",\n        \"dashed\",\n    ]\n\n    # Geometry\n    self.geometry = Geometry(parent_object=self)\n    self.position = kwargs.get(\"position\", (0, 0))\n    self.width = kwargs.get(\"width\", 120)\n    self.height = kwargs.get(\"height\", 80)\n    self.vertex = kwargs.get(\"vertex\", 1)\n\n    # TODO enumerate to fixed\n    self.aspect = kwargs.get(\"aspect\", None)\n\n    # Content\n    self.text_format = kwargs.get(\"text_format\", TextFormat())\n    self.value = value\n\n    # Style\n    self.baseStyle = kwargs.get(\"baseStyle\", None)\n\n    self.rounded = kwargs.get(\"rounded\", 0)\n    self.whiteSpace = kwargs.get(\"whiteSpace\", \"wrap\")\n    self.opacity = kwargs.get(\"opacity\", None)\n    self.strokeColor = kwargs.get(\"strokeColor\", None)\n    self.fillColor = kwargs.get(\"fillColor\", None)\n    self.glass = kwargs.get(\"glass\", None)\n    self.shadow = kwargs.get(\"shadow\", None)\n    self.comic = kwargs.get(\"comic\", None)\n    self.sketch = kwargs.get(\"sketch\", None)\n    self.line_pattern = kwargs.get(\"line_pattern\", \"solid\")\n\n    self.out_edges = kwargs.get(\"out_edges\", [])\n    self.in_edges = kwargs.get(\"in_edges\", [])\n\n    self.xml_class = \"mxCell\"\n\n    if \"template_object\" in kwargs:\n        self.template_object = kwargs.get(\"template_object\")\n        self._apply_style_from_template(self.template_object)\n        self.width = self.template_object.width\n        self.height = self.template_object.height\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.add_in_edge","title":"add_in_edge(edge)","text":"

Add an edge into the object. If an edge is created with this object set as the target this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object ending at this object

required Source code in src/drawpyo/diagram/objects.py
def add_in_edge(self, edge):\n    \"\"\"Add an edge into the object. If an edge is created with this object set as the target this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object ending at this object\n    \"\"\"\n    self.in_edges.append(edge)\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.add_out_edge","title":"add_out_edge(edge)","text":"

Add an edge out of the object. If an edge is created with this object set as the source this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object originating at this object

required Source code in src/drawpyo/diagram/objects.py
def add_out_edge(self, edge):\n    \"\"\"Add an edge out of the object. If an edge is created with this object set as the source this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object originating at this object\n    \"\"\"\n    self.out_edges.append(edge)\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.create_from_library","title":"create_from_library(library, obj_name) classmethod","text":"

This function generates a Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.

Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. However, the styling in the library will overwrite that formatting.

Parameters:

Name Type Description Default library str or dict

The library containing the object

required obj_name str

The name of the object in the library to generate

required

Returns:

Name Type Description Object

An object with the style from the library

Source code in src/drawpyo/diagram/objects.py
@classmethod\ndef create_from_library(cls, library, obj_name):\n    \"\"\"This function generates a Object from a library. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n    Any keyword arguments that can be passed in to a Object creation can be passed into this function and it will format the base object. However, the styling in the library will overwrite that formatting.\n\n    Args:\n        library (str or dict): The library containing the object\n        obj_name (str): The name of the object in the library to generate\n\n    Returns:\n        Object: An object with the style from the library\n    \"\"\"\n    new_obj = cls()\n    new_obj.format_as_library_object(library, obj_name)\n    return new_obj\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.create_from_style_string","title":"create_from_style_string(style_string) classmethod","text":"

Objects can be instantiated from a style string. These strings are most easily found in the Draw.io app, by styling an object as desired then right-clicking and selecting \"Edit Style\". Copying that text into this function will generate an object styled the same.

Parameters:

Name Type Description Default style_string str

A Draw.io generated style string.

required

Returns:

Name Type Description Object

An object formatted with the style string

Source code in src/drawpyo/diagram/objects.py
@classmethod\ndef create_from_style_string(cls, style_string):\n    \"\"\"Objects can be instantiated from a style string. These strings are most easily found in the Draw.io app, by styling an object as desired then right-clicking and selecting \"Edit Style\". Copying that text into this function will generate an object styled the same.\n\n    Args:\n        style_string (str): A Draw.io generated style string.\n\n    Returns:\n        Object: An object formatted with the style string\n    \"\"\"\n    cls.apply_style_from_string(style_string)\n    return cls\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.create_from_template_object","title":"create_from_template_object(template_object, value=None, position=None, page=None) classmethod","text":"

Object can be instantiated from another object. This will initialize the Object with the same formatting, then set a new position and value.

Parameters:

Name Type Description Default template_object Object

Another drawpyo Object to use as a template

required value str

The text contents of the object. Defaults to None.

None position tuple

The position where the object should be placed. Defaults to (0, 0).

None page Page

The Page object to place the object on. Defaults to None.

None

Returns:

Name Type Description Object

The newly created object

Source code in src/drawpyo/diagram/objects.py
@classmethod\ndef create_from_template_object(\n    cls, template_object, value=None, position=None, page=None\n):\n    \"\"\"Object can be instantiated from another object. This will initialize the Object with the same formatting, then set a new position and value.\n\n    Args:\n        template_object (Object): Another drawpyo Object to use as a template\n        value (str, optional): The text contents of the object. Defaults to None.\n        position (tuple, optional): The position where the object should be placed. Defaults to (0, 0).\n        page (Page, optional): The Page object to place the object on. Defaults to None.\n\n    Returns:\n        Object: The newly created object\n    \"\"\"\n    new_obj = cls(\n        value=value,\n        page=page,\n        width=template_object.width,\n        height=template_object.height,\n        template_object=template_object,\n    )\n    if position is not None:\n        new_obj.position = position\n    if value is not None:\n        new_obj.value = value\n    return new_obj\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.format_as_library_object","title":"format_as_library_object(library, obj_name)","text":"

This function applies the style from a library to an existing object. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.

Parameters:

Name Type Description Default library str or dict

The library containing the object

required obj_name str

The name of the object in the library to generate

required Source code in src/drawpyo/diagram/objects.py
def format_as_library_object(self, library, obj_name):\n    \"\"\"This function applies the style from a library to an existing object. The library can either be custom imported from a TOML or the name of one of the built-in Draw.io libraries.\n\n    Args:\n        library (str or dict): The library containing the object\n        obj_name (str): The name of the object in the library to generate\n    \"\"\"\n    if type(library) == str:\n        if library in base_libraries:\n            library_dict = base_libraries[library]\n            if obj_name in library_dict:\n                obj_dict = library_dict[obj_name]\n                self.apply_attribute_dict(obj_dict)\n            else:\n                raise ValueError(\n                    \"Object {0} not in Library {1}\".format(obj_name, library)\n                )\n        else:\n            raise ValueError(\"Library {0} not in base_libraries\".format(library))\n    elif type(library) == dict:\n        obj_dict = library[obj_name]\n        self.apply_attribute_dict(obj_dict)\n    else:\n        raise ValueError(\"Unparseable libary passed in.\")\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.remove_in_edge","title":"remove_in_edge(edge)","text":"

Remove an edge into the object. If an edge linked to this object has the target changed or removed this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object ending at this object

required Source code in src/drawpyo/diagram/objects.py
def remove_in_edge(self, edge):\n    \"\"\"Remove an edge into the object. If an edge linked to this object has the target changed or removed this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object ending at this object\n    \"\"\"\n    self.in_edges.remove(edge)\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.remove_out_edge","title":"remove_out_edge(edge)","text":"

Remove an edge out of the object. If an edge linked to this object has the source changed or removed this function will be called automatically.

Parameters:

Name Type Description Default edge Edge

An Edge object originating at this object

required Source code in src/drawpyo/diagram/objects.py
def remove_out_edge(self, edge):\n    \"\"\"Remove an edge out of the object. If an edge linked to this object has the source changed or removed this function will be called automatically.\n\n    Args:\n        edge (Edge): An Edge object originating at this object\n    \"\"\"\n    self.out_edges.remove(edge)\n
"},{"location":"api/objects/#group","title":"Group","text":""},{"location":"api/objects/#src.drawpyo.diagram.objects.Group","title":"src.drawpyo.diagram.objects.Group","text":"

This class allows objects to be grouped together. It then provides a number of geometry functions and properties to move the entire group around.

Currently this object doesn't replicate any of the functionality of groups in the Draw.io app but it may be extended to have that capability in the future.

Source code in src/drawpyo/diagram/objects.py
class Group:\n    \"\"\"This class allows objects to be grouped together. It then provides a number of geometry functions and properties to move the entire group around.\n\n    Currently this object doesn't replicate any of the functionality of groups in the Draw.io app but it may be extended to have that capability in the future.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        self.objects = kwargs.get(\"objects\", [])\n        self.geometry = Geometry()\n\n    def add_object(self, object):\n        \"\"\"Adds one or more objects to the group and updates the geometry of the group.\n\n        Args:\n            object (Object or list): Object or list of objects to be added to the group\n        \"\"\"\n        if not isinstance(object, list):\n            object = [object]\n        for o in object:\n            if o not in self.objects:\n                self.objects.append(o)\n        self.update_geometry()\n\n    def update_geometry(self):\n        \"\"\"Update the geometry of the group. This includes the left and top coordinates and the width and height of the entire group.\"\"\"\n        self.geometry.x = self.left\n        self.geometry.y = self.top\n        self.geometry.width = self.width\n        self.geometry.height = self.height\n\n    ###########################################################\n    # Passive properties\n    ###########################################################\n\n    @property\n    def left(self):\n        \"\"\"The leftmost X-coordinate of the objects in the group\n\n        Returns:\n            int: Left edge of the group\n        \"\"\"\n        return min([obj.geometry.x for obj in self.objects])\n\n    @property\n    def right(self):\n        \"\"\"The rightmost X-coordinate of the objects in the group\n\n        Returns:\n            int: Right edge of the group\n        \"\"\"\n        return max([obj.geometry.x + obj.geometry.width for obj in self.objects])\n\n    @property\n    def top(self):\n        \"\"\"The topmost Y-coordinate of the objects in the group\n\n        Returns:\n            int: Top edge of the group\n        \"\"\"\n        return min([obj.geometry.y for obj in self.objects])\n\n    @property\n    def bottom(self):\n        \"\"\"The bottommost Y-coordinate of the objects in the group\n\n        Returns:\n            int: The bottom edge of the group\n        \"\"\"\n        return max([obj.geometry.y + obj.geometry.height for obj in self.objects])\n\n    @property\n    def width(self):\n        \"\"\"The width of all the objects in the group\n\n        Returns:\n            int: Width of the group\n        \"\"\"\n        return self.right - self.left\n\n    @property\n    def height(self):\n        \"\"\"The height of all the objects in the group\n\n        Returns:\n            int: Height of the group\n        \"\"\"\n        return self.bottom - self.top\n\n    @property\n    def size(self):\n        \"\"\"The size of the group. Returns a tuple of ints, with the width and height.\n\n        Returns:\n            tuple: A tuple of ints (width, height)\n        \"\"\"\n        return (self.width, self.height)\n\n    ###########################################################\n    # Position properties\n    ###########################################################\n\n    @property\n    def center_position(self):\n        \"\"\"The center position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.\n\n        Returns:\n            tuple: A tuple of ints (X, Y)\n        \"\"\"\n        return (self.left + self.width / 2, self.top + self.height / 2)\n\n    @center_position.setter\n    def center_position(self, new_center):\n        current_center = (\n            self.left + self.width / 2,\n            self.top + self.height / 2,\n        )\n        delta_x = new_center[0] - current_center[0]\n        delta_y = new_center[1] - current_center[1]\n        for obj in self.objects:\n            obj.position = (obj.geometry.x + delta_x, obj.geometry.y + delta_y)\n        self.update_geometry()\n\n    @property\n    def position(self):\n        \"\"\"The top left position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.\n\n        Returns:\n            tuple: A tuple of ints (X, Y)\n        \"\"\"\n        return (self.left, self.top)\n\n    @position.setter\n    def position(self, new_position):\n        current_position = (self.left, self.top)\n        delta_x = new_position[0] - current_position[0]\n        delta_y = new_position[1] - current_position[1]\n        for obj in self.objects:\n            obj.position = (obj.geometry.x + delta_x, obj.geometry.y + delta_y)\n        self.update_geometry()\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.bottom","title":"bottom property","text":"

The bottommost Y-coordinate of the objects in the group

Returns:

Name Type Description int

The bottom edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.center_position","title":"center_position property writable","text":"

The center position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.

Returns:

Name Type Description tuple

A tuple of ints (X, Y)

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.height","title":"height property","text":"

The height of all the objects in the group

Returns:

Name Type Description int

Height of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.left","title":"left property","text":"

The leftmost X-coordinate of the objects in the group

Returns:

Name Type Description int

Left edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.position","title":"position property writable","text":"

The top left position of the group. Returns a tuple of ints, with the X and Y coordinate. When this property is set, the coordinates of every object in the group are updated.

Returns:

Name Type Description tuple

A tuple of ints (X, Y)

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.right","title":"right property","text":"

The rightmost X-coordinate of the objects in the group

Returns:

Name Type Description int

Right edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.size","title":"size property","text":"

The size of the group. Returns a tuple of ints, with the width and height.

Returns:

Name Type Description tuple

A tuple of ints (width, height)

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.top","title":"top property","text":"

The topmost Y-coordinate of the objects in the group

Returns:

Name Type Description int

Top edge of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.width","title":"width property","text":"

The width of all the objects in the group

Returns:

Name Type Description int

Width of the group

"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.add_object","title":"add_object(object)","text":"

Adds one or more objects to the group and updates the geometry of the group.

Parameters:

Name Type Description Default object Object or list

Object or list of objects to be added to the group

required Source code in src/drawpyo/diagram/objects.py
def add_object(self, object):\n    \"\"\"Adds one or more objects to the group and updates the geometry of the group.\n\n    Args:\n        object (Object or list): Object or list of objects to be added to the group\n    \"\"\"\n    if not isinstance(object, list):\n        object = [object]\n    for o in object:\n        if o not in self.objects:\n            self.objects.append(o)\n    self.update_geometry()\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Group.update_geometry","title":"update_geometry()","text":"

Update the geometry of the group. This includes the left and top coordinates and the width and height of the entire group.

Source code in src/drawpyo/diagram/objects.py
def update_geometry(self):\n    \"\"\"Update the geometry of the group. This includes the left and top coordinates and the width and height of the entire group.\"\"\"\n    self.geometry.x = self.left\n    self.geometry.y = self.top\n    self.geometry.width = self.width\n    self.geometry.height = self.height\n
"},{"location":"api/page/","title":"Page","text":""},{"location":"api/page/#src.drawpyo.page.Page","title":"src.drawpyo.page.Page","text":"

This class defines a page in a Draw.io document. It contains a list of objects and a reference to the File it's in as well as formatting attributes.

Source code in src/drawpyo/page.py
class Page:\n    \"\"\"\n    This class defines a page in a Draw.io document. It contains a list of objects and a reference to the File it's in as well as formatting attributes.\n    \"\"\"\n\n    def __init__(self, file=None, **kwargs):\n        super().__init__()\n        self.id = id(self)\n\n        self.file = file\n        self.objects = kwargs.get(\"objects\", [])\n\n        # There are two empty top level objects in every Draw.io diagram\n        self.objects.append(XMLBase(id=0, xml_class=\"mxCell\"))\n        self.objects.append(XMLBase(id=1, xml_class=\"mxCell\", xml_parent=0))\n\n        # Properties\n\n        if self.file is not None:\n            page_num = len(self.file.pages)\n        else:\n            page_num = 1\n        self.name = kwargs.get(\"name\", f\"Page-{page_num}\")\n        self.page_num = kwargs.get(\"page_num\", page_num)\n\n        self.dx = kwargs.get(\"dx\", 2037)\n        self.dy = kwargs.get(\"dy\", 830)\n        self.grid = kwargs.get(\"grid\", 1)\n        self.grid_size = kwargs.get(\"grid_size\", 10)\n        self.guides = kwargs.get(\"guides\", 1)\n        self.tooltips = kwargs.get(\"tooltips\", 1)\n        self.connect = kwargs.get(\"connect\", 1)\n        self.arrows = kwargs.get(\"arrows\", 1)\n        self.fold = kwargs.get(\"fold\", 1)\n        self.scale = kwargs.get(\"scale\", 1)\n        self.width = kwargs.get(\"width\", 850)\n        self.height = kwargs.get(\"height\", 1100)\n        self.math = kwargs.get(\"math\", 0)\n        self.shadow = kwargs.get(\"shadow\", 0)\n\n        # In the Draw.io file format, each page is actually three nested XML\n        # tags. These are defined as XMLBase subclasses below\n        self.diagram = Diagram(name=self.name)\n        self.mxGraph = mxGraph(page=self)\n        self.root = Root()\n\n    def __repr__(self):\n        return f\"drawpyo Page - {self.name}\"\n\n    def remove(self):\n        \"\"\"This function removes the Page from its linked File object then deletes itself.\"\"\"\n        if self.file is not None:\n            self.file.remove_page(self)\n        del self\n\n    def add_object(self, obj):\n        if obj not in self.objects:\n            self.objects.append(obj)\n\n    def remove_object(self, obj):\n        self.objects.remove(obj)\n\n    @property\n    def file(self):\n        return self._file\n\n    @file.setter\n    def file(self, f):\n        if f is not None:\n            f.add_page(self)\n        self._file = f\n\n    @file.deleter\n    def file(self):\n        self._file.remove_page(self)\n        self._file = None\n\n    ###########################################################\n    # XML Generation\n    ###########################################################\n    @property\n    def xml(self):\n        xml_string = self.xml_open_tag\n        for obj in self.objects:\n            xml_string = xml_string + \"\\n        \" + obj.xml\n        xml_string = xml_string + \"\\n\" + self.xml_close_tag\n        return xml_string\n\n    @property\n    def xml_open_tag(self):\n        tag = (\n            self.diagram.xml_open_tag\n            + \"\\n    \"\n            + self.mxGraph.xml_open_tag\n            + \"\\n      \"\n            + self.root.xml_open_tag\n        )\n        return tag\n\n    @property\n    def xml_close_tag(self):\n        tag = (\n            \"      \"\n            + self.root.xml_close_tag\n            + \"\\n    \"\n            + self.mxGraph.xml_close_tag\n            + \"\\n  \"\n            + self.diagram.xml_close_tag\n        )\n        return tag\n
"},{"location":"api/page/#src.drawpyo.page.Page.remove","title":"remove()","text":"

This function removes the Page from its linked File object then deletes itself.

Source code in src/drawpyo/page.py
def remove(self):\n    \"\"\"This function removes the Page from its linked File object then deletes itself.\"\"\"\n    if self.file is not None:\n        self.file.remove_page(self)\n    del self\n
"},{"location":"api/text_format/","title":"Text Format","text":""},{"location":"api/text_format/#textformat","title":"TextFormat","text":""},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat","title":"src.drawpyo.diagram.text_format.TextFormat","text":"

Bases: DiagramBase

The TextFormat class handles all of the formatting specifically around a text box or label.

Source code in src/drawpyo/diagram/text_format.py
class TextFormat(DiagramBase):\n    \"\"\"The TextFormat class handles all of the formatting specifically around a text box or label.\"\"\"\n\n    def __init__(self, **kwargs):\n        \"\"\"TextFormat objects can be initialized with no properties or any of what's listed below:\n\n        Keyword Args:\n            fontColor (int, optional): The color of the text in the object (#ffffff)\n            fontFamily (str, optional): The typeface of the text in the object (see Draw.io for available fonts)\n            fontSize (int, optional): The size of the text in the object in points\n            align (str, optional): The horizontal alignment of the text in the object ('left', 'center', or 'right')\n            verticalAlign (str, optional): The vertical alignment of the text in the object ('top', 'middle', 'bottom')\n            textOpacity (int, optional): The opacity of the text in the object\n            direction (str, optional): The direction to print the text ('vertical', 'horizontal')\n            bold (bool, optional): Whether the text in the object should be bold\n            italic (bool, optional): Whether the text in the object should be italic\n            underline (bool, optional): Whether the text in the object should be underlined\n            labelPosition (str, optional): The position of the object label ('left', 'center', or 'right')\n            labelBackgroundColor (str, optional): The background color of the object label (#ffffff)\n            labelBorderColor (str, optional): The border color of the object label (#ffffff)\n            fomrattedText (bool, optional): Whether to render the text as HTML formatted or not\n\n        \"\"\"\n        super().__init__(**kwargs)\n        self.fontFamily = kwargs.get(\"fontFamily\", None)\n        self.fontSize = kwargs.get(\"fontSize\", None)\n        self.fontColor = kwargs.get(\"fontColor\", None)\n        self.labelBorderColor = kwargs.get(\"labelBorderColor\", None)\n        self.labelBackgroundColor = kwargs.get(\"labelBackgroundColor\", None)\n        self.labelPosition = kwargs.get(\"labelPosition\", None)\n        self.textShadow = kwargs.get(\"textShadow\", None)\n        self.textOpacity = kwargs.get(\"textOpacity\", None)\n        self.spacingTop = kwargs.get(\"spacingTop\", None)\n        self.spacingLeft = kwargs.get(\"spacingLeft\", None)\n        self.spacingBottom = kwargs.get(\"spacingBottom\", None)\n        self.spacingRight = kwargs.get(\"spacingRight\", None)\n        self.spacing = kwargs.get(\"spacing\", None)\n        self.align = kwargs.get(\"align\", None)\n        self.verticalAlign = kwargs.get(\"verticalAlign\", None)\n        # These need to be enumerated\n        self.direction = kwargs.get(\"direction\", None)\n        # This is actually horizontal. 0 means vertical text, 1 or not present\n        # means horizontal\n        self.formattedText = kwargs.get(\n            \"formattedText\", None\n        )  # prints in the style string as html\n        self.bold = kwargs.get(\"bold\", False)\n        self.italic = kwargs.get(\"italic\", False)\n        self.underline = kwargs.get(\"underline\", False)\n\n        self._style_attributes = [\n            \"html\",\n            \"fontFamily\",\n            \"fontSize\",\n            \"fontColor\",\n            \"labelBorderColor\",\n            \"labelBackgroundColor\",\n            \"labelPosition\",\n            \"textShadow\",\n            \"textOpacity\",\n            \"spacingTop\",\n            \"spacingLeft\",\n            \"spacingBottom\",\n            \"spacingRight\",\n            \"spacing\",\n            \"align\",\n            \"verticalAlign\",\n            \"horizontal\",\n        ]\n\n    @property\n    def formattedText(self):\n        \"\"\"formattedText wraps the Draw.io style attribute 'html'. This controls whether the text is rendered with HTML attributes or as plain text.\"\"\"\n        return self.html\n\n    @formattedText.setter\n    def formattedText(self, value):\n        self.html = value\n\n    @formattedText.deleter\n    def formattedText(self, value):\n        self.html = None\n\n    # The direction of the text is encoded as 'horizontal' in Draw.io. This is\n    # unintuitive so I provided a direction alternate syntax.\n    @property\n    def horizontal(self):\n        return directions[self._direction]\n\n    @horizontal.setter\n    def horizontal(self, value):\n        if value in directions_inv.keys():\n            self._direction = directions_inv[value]\n        else:\n            raise ValueError(\"{0} is not an allowed value of horizontal\".format(value))\n\n    @property\n    def directions(self):\n        \"\"\"The direction controls the direction of the text and can be either horizontal or vertical.\"\"\"\n        return directions\n\n    @property\n    def direction(self):\n        return self._direction\n\n    @direction.setter\n    def direction(self, value):\n        if value in directions.keys():\n            self._direction = value\n        else:\n            raise ValueError(\"{0} is not an allowed value of direction\".format(value))\n\n    @property\n    def font_style(self):\n        \"\"\"The font_style is a numeric format that corresponds to a combination of three other attributes: bold, italic, and underline. Any combination of them can be true.\"\"\"\n        bld = self.bold\n        ita = self.italic\n        unl = self.underline\n\n        # 0 = normal\n        # 1 = bold\n        # 2 = italic\n        # 3 = bold and italic\n        # 4 = underline\n        # 5 = bold and underlined\n        # 6 = italic and underlined\n        # 7 = bolt, italic, and underlined\n\n        if not bld and not ita and not unl:\n            return 0\n        elif bld and not ita and not unl:\n            return 1\n        elif not bld and ita and not unl:\n            return 2\n        elif bld and ita and not unl:\n            return 3\n        elif not bld and not ita and unl:\n            return 4\n        elif bld and not ita and unl:\n            return 5\n        elif not bld and ita and unl:\n            return 6\n        elif bld and ita and unl:\n            return 7\n
"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.directions","title":"directions property","text":"

The direction controls the direction of the text and can be either horizontal or vertical.

"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.font_style","title":"font_style property","text":"

The font_style is a numeric format that corresponds to a combination of three other attributes: bold, italic, and underline. Any combination of them can be true.

"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.formattedText","title":"formattedText deletable property writable","text":"

formattedText wraps the Draw.io style attribute 'html'. This controls whether the text is rendered with HTML attributes or as plain text.

"},{"location":"api/text_format/#src.drawpyo.diagram.text_format.TextFormat.__init__","title":"__init__(**kwargs)","text":"

TextFormat objects can be initialized with no properties or any of what's listed below:

Other Parameters:

Name Type Description fontColor int

The color of the text in the object (#ffffff)

fontFamily str

The typeface of the text in the object (see Draw.io for available fonts)

fontSize int

The size of the text in the object in points

align str

The horizontal alignment of the text in the object ('left', 'center', or 'right')

verticalAlign str

The vertical alignment of the text in the object ('top', 'middle', 'bottom')

textOpacity int

The opacity of the text in the object

direction str

The direction to print the text ('vertical', 'horizontal')

bold bool

Whether the text in the object should be bold

italic bool

Whether the text in the object should be italic

underline bool

Whether the text in the object should be underlined

labelPosition str

The position of the object label ('left', 'center', or 'right')

labelBackgroundColor str

The background color of the object label (#ffffff)

labelBorderColor str

The border color of the object label (#ffffff)

fomrattedText bool

Whether to render the text as HTML formatted or not

Source code in src/drawpyo/diagram/text_format.py
def __init__(self, **kwargs):\n    \"\"\"TextFormat objects can be initialized with no properties or any of what's listed below:\n\n    Keyword Args:\n        fontColor (int, optional): The color of the text in the object (#ffffff)\n        fontFamily (str, optional): The typeface of the text in the object (see Draw.io for available fonts)\n        fontSize (int, optional): The size of the text in the object in points\n        align (str, optional): The horizontal alignment of the text in the object ('left', 'center', or 'right')\n        verticalAlign (str, optional): The vertical alignment of the text in the object ('top', 'middle', 'bottom')\n        textOpacity (int, optional): The opacity of the text in the object\n        direction (str, optional): The direction to print the text ('vertical', 'horizontal')\n        bold (bool, optional): Whether the text in the object should be bold\n        italic (bool, optional): Whether the text in the object should be italic\n        underline (bool, optional): Whether the text in the object should be underlined\n        labelPosition (str, optional): The position of the object label ('left', 'center', or 'right')\n        labelBackgroundColor (str, optional): The background color of the object label (#ffffff)\n        labelBorderColor (str, optional): The border color of the object label (#ffffff)\n        fomrattedText (bool, optional): Whether to render the text as HTML formatted or not\n\n    \"\"\"\n    super().__init__(**kwargs)\n    self.fontFamily = kwargs.get(\"fontFamily\", None)\n    self.fontSize = kwargs.get(\"fontSize\", None)\n    self.fontColor = kwargs.get(\"fontColor\", None)\n    self.labelBorderColor = kwargs.get(\"labelBorderColor\", None)\n    self.labelBackgroundColor = kwargs.get(\"labelBackgroundColor\", None)\n    self.labelPosition = kwargs.get(\"labelPosition\", None)\n    self.textShadow = kwargs.get(\"textShadow\", None)\n    self.textOpacity = kwargs.get(\"textOpacity\", None)\n    self.spacingTop = kwargs.get(\"spacingTop\", None)\n    self.spacingLeft = kwargs.get(\"spacingLeft\", None)\n    self.spacingBottom = kwargs.get(\"spacingBottom\", None)\n    self.spacingRight = kwargs.get(\"spacingRight\", None)\n    self.spacing = kwargs.get(\"spacing\", None)\n    self.align = kwargs.get(\"align\", None)\n    self.verticalAlign = kwargs.get(\"verticalAlign\", None)\n    # These need to be enumerated\n    self.direction = kwargs.get(\"direction\", None)\n    # This is actually horizontal. 0 means vertical text, 1 or not present\n    # means horizontal\n    self.formattedText = kwargs.get(\n        \"formattedText\", None\n    )  # prints in the style string as html\n    self.bold = kwargs.get(\"bold\", False)\n    self.italic = kwargs.get(\"italic\", False)\n    self.underline = kwargs.get(\"underline\", False)\n\n    self._style_attributes = [\n        \"html\",\n        \"fontFamily\",\n        \"fontSize\",\n        \"fontColor\",\n        \"labelBorderColor\",\n        \"labelBackgroundColor\",\n        \"labelPosition\",\n        \"textShadow\",\n        \"textOpacity\",\n        \"spacingTop\",\n        \"spacingLeft\",\n        \"spacingBottom\",\n        \"spacingRight\",\n        \"spacing\",\n        \"align\",\n        \"verticalAlign\",\n        \"horizontal\",\n    ]\n
"},{"location":"api/tree_diagram/nodeobject/","title":"NodeObject","text":""},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject","title":"src.drawpyo.diagram_types.tree.NodeObject","text":"

Bases: Object

This class defines one of the nodes on a tree graph. It inherits from Object and performs the same in most regards. It also tracks the tree-specific parameters like the tree, children, parent, etc.

Source code in src/drawpyo/diagram_types/tree.py
class NodeObject(Object):\n    \"\"\"This class defines one of the nodes on a tree graph. It inherits from Object and performs the same in most regards. It also tracks the tree-specific parameters like the tree, children, parent, etc.\"\"\"\n\n    def __init__(self, tree=None, **kwargs):\n        \"\"\"The NodeObject should be instantiated with an owning tree object. A NodeObject can only have a single parent but can have any number of children.\n\n        Args:\n            tree (TreeDiagram, optional): The owning tree diagram. Defaults to None.\n\n        Keyword Args:\n            children (list, optional): A list of other NodeObjects\n            parent (list, optional): The parent NodeObject\n        \"\"\"\n        super().__init__(**kwargs)\n        self.tree = tree\n        self.children = kwargs.get(\"children\", [])\n        self.parent = kwargs.get(\"parent\", None)\n        self.peers = []\n        # self.level = kwargs.get(\"level\", None)\n        # self.peers = kwargs.get(\"peers\", [])\n\n    @property\n    def tree(self):\n        \"\"\"The TreeDiagram that owns the NodeObject\n\n        Returns:\n            TreeDiagram\n        \"\"\"\n        return self._tree\n\n    @tree.setter\n    def tree(self, value):\n        if value is not None:\n            value.add_object(self)\n        self._tree = value\n\n    @property\n    def parent(self):\n        \"\"\"The parent NodeObject\n\n        Returns:\n            NodeObject\n        \"\"\"\n        return self._parent\n\n    @parent.setter\n    def parent(self, value):\n        if value is not None:\n            value.children.append(self)\n        self._parent = value\n\n    def add_child(self, obj):\n        \"\"\"Add a new child to the object\n\n        Args:\n            obj (NodeObject)\n        \"\"\"\n        self.children.append(obj)\n        obj._parent = self\n\n    def add_peer(self, obj):\n        if obj not in self.peers:\n            self.peers.append(obj)\n        if self not in obj.peers:\n            obj.peers.append(self)\n\n    @property\n    def size_of_level(self):\n        \"\"\"The height or the width of the level, depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.geometry.height\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.geometry.width\n\n    @property\n    def size_in_level(self):\n        \"\"\"The size of the object within its level, either its width or height depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.geometry.width\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.geometry.height\n
"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.parent","title":"parent property writable","text":"

The parent NodeObject

Returns:

Type Description

NodeObject

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.size_in_level","title":"size_in_level property","text":"

The size of the object within its level, either its width or height depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.size_of_level","title":"size_of_level property","text":"

The height or the width of the level, depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.tree","title":"tree property writable","text":"

The TreeDiagram that owns the NodeObject

Returns:

Type Description

TreeDiagram

"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.__init__","title":"__init__(tree=None, **kwargs)","text":"

The NodeObject should be instantiated with an owning tree object. A NodeObject can only have a single parent but can have any number of children.

Parameters:

Name Type Description Default tree TreeDiagram

The owning tree diagram. Defaults to None.

None

Other Parameters:

Name Type Description children list

A list of other NodeObjects

parent list

The parent NodeObject

Source code in src/drawpyo/diagram_types/tree.py
def __init__(self, tree=None, **kwargs):\n    \"\"\"The NodeObject should be instantiated with an owning tree object. A NodeObject can only have a single parent but can have any number of children.\n\n    Args:\n        tree (TreeDiagram, optional): The owning tree diagram. Defaults to None.\n\n    Keyword Args:\n        children (list, optional): A list of other NodeObjects\n        parent (list, optional): The parent NodeObject\n    \"\"\"\n    super().__init__(**kwargs)\n    self.tree = tree\n    self.children = kwargs.get(\"children\", [])\n    self.parent = kwargs.get(\"parent\", None)\n    self.peers = []\n
"},{"location":"api/tree_diagram/nodeobject/#src.drawpyo.diagram_types.tree.NodeObject.add_child","title":"add_child(obj)","text":"

Add a new child to the object

Source code in src/drawpyo/diagram_types/tree.py
def add_child(self, obj):\n    \"\"\"Add a new child to the object\n\n    Args:\n        obj (NodeObject)\n    \"\"\"\n    self.children.append(obj)\n    obj._parent = self\n
"},{"location":"api/tree_diagram/treediagram/","title":"TreeDiagram","text":""},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram","title":"src.drawpyo.diagram_types.tree.TreeDiagram","text":"

The TreeDiagram contains a File object, a Page object, and all the NodeObjects in the tree.

Source code in src/drawpyo/diagram_types/tree.py
class TreeDiagram:\n    \"\"\"The TreeDiagram contains a File object, a Page object, and all the NodeObjects in the tree.\"\"\"\n\n    def __init__(self, **kwargs):\n        \"\"\"The TreeDiagram initiates its own File and Page objects. There are a number of formatting parameters that can be set to fine tune the rendering of the tree.\n\n        Keyword Args:\n            direction (str, optional): Direction that the tree grows from the root. Options are 'up', 'down', 'left', and 'right'. Defaults to 'down'.\n            link_style (str, optional): Connection style of the edges. Options are 'orthogonal', 'straight', and 'curved'. Defaults to 'orthogonal'.\n            level_spacing (int, optional): Spacing in pixels between levels. Defaults to 60.\n            item_spacing (int, optional): Spacing in pixels between groups within a level. Defaults to 15.\n            padding (int, optional): Spacing in pixels between objects within a group. Defaults to 10.\n            file_name (str, optional): The name of the tree diagram.\n            file_path (str, optional): The path where the tree diagram should be saved.\n        \"\"\"\n        # formatting\n        self.level_spacing = kwargs.get(\"level_spacing\", 60)\n        self.item_spacing = kwargs.get(\"item_spacing\", 15)\n        self.group_spacing = kwargs.get(\"group_spacing\", 30)\n        self.direction = kwargs.get(\"direction\", \"down\")\n        self.link_style = kwargs.get(\"link_style\", \"orthogonal\")\n        self.padding = kwargs.get(\"padding\", 10)\n\n        # Set up the File and Page objects\n        self.file = File()\n        self.file_name = kwargs.get(\"file_name\", \"Heirarchical Diagram.drawio\")\n        self.file_path = kwargs.get(\"file_path\", r\"C:/\")\n        self.page = Page(file=self.file)\n\n        # Set up object and level lists\n        self.objects = []\n        self.links = []\n\n    ###########################################################\n    # properties\n    ###########################################################\n    # These setters and getters keep the file name and file path within the\n    # File object\n    @property\n    def file_name(self):\n        \"\"\"The file name of the TreeDiagram\n\n        Returns:\n            str\n        \"\"\"\n        return self.file.file_name\n\n    @file_name.setter\n    def file_name(self, fn):\n        self.file.file_name = fn\n\n    @property\n    def file_path(self):\n        \"\"\"The file path where the TreeDiagram will be saved\n\n        Returns:\n            str\n        \"\"\"\n        return self.file.file_path\n\n    @file_path.setter\n    def file_path(self, fn):\n        self.file.file_path = fn\n\n    # These setters enforce the options for direction and link_style.\n    @property\n    def direction(self):\n        \"\"\"The direction the tree diagram should grow. Options are \"up\", \"down\", \"left\", or \"right\".\n\n        Returns:\n            str\n        \"\"\"\n        return self._direction\n\n    @direction.setter\n    def direction(self, d):\n        directions = [\"up\", \"down\", \"left\", \"right\"]\n        if d in directions:\n            self._direction = d\n        else:\n            raise ValueError(\n                \"{0} is not a valid entry for direction. Must be {1}.\".format(\n                    d, \", \".join(directions)\n                )\n            )\n\n    ###########################################################\n    # Formatting Properties\n    ###########################################################\n\n    @property\n    def origin(self):\n        \"\"\"The origin points of the TreeDiagram. This is the point where the center of the top level of the TreeDiagram starts from. By default it's set to the top center of an edge of the page. Which edge depends on the direction of the tree diagram.\n\n        Returns:\n            tuple: A tuple of ints\n        \"\"\"\n        origins = {\n            \"up\": (self.page.width / 2, self.page.height - self.padding),\n            \"down\": (self.page.width / 2, self.padding),\n            \"right\": (self.padding, self.page.height / 2),\n            \"left\": (self.page.width - self.padding, self.page.height / 2),\n        }\n        return origins[self.direction]\n\n    def level_move(self, move):\n        \"\"\"The functions takes in a relative distance to move within levels. It outputs a tuple with the relative move in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            move (int): The amount to move within levels\n\n        Returns:\n            tuple: A tuple containing a 0 and the move, in the right orientation.\n        \"\"\"\n        if self.direction in [\"up\", \"down\"]:\n            return (0, move)\n        elif self.direction in [\"left\", \"right\"]:\n            return (move, 0)\n\n    def move_between_levels(self, start, move):\n        \"\"\"The functions takes in a starting position and a relative distance to move between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction == \"up\":\n            return (start[0], start[1] - move)\n        elif self.direction == \"down\":\n            return (start[0], start[1] + move)\n        elif self.direction == \"left\":\n            return (start[0] - move, start[1])\n        elif self.direction == \"right\":\n            return (start[0] + move, start[1])\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    def move_in_level(self, start, move):\n        \"\"\"The functions takes in a starting position and a relative distance to move within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction in [\"up\", \"down\"]:\n            return (start[0] + move, start[1])\n        elif self.direction in [\"left\", \"right\"]:\n            return (start[0], start[1] + move)\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    def abs_move_between_levels(self, start, position):\n        \"\"\"The functions takes in a starting position and an absolute position along the coordinates between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction == \"up\":\n            return (start[0], position)\n        elif self.direction == \"down\":\n            return (start[0], position)\n        elif self.direction == \"left\":\n            return (position, start[1])\n        elif self.direction == \"right\":\n            return (position, start[1])\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    def abs_move_in_level(self, start, position):\n        \"\"\"The functions takes in a starting position and an absolute position along the coordinates within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n        Args:\n            start (tuple): The starting position, a tuple of ints\n            move (int): The direction to move between levels.\n\n        Raises:\n            ValueError: \"No direction defined!\"\n\n        Returns:\n            tuple: The final position, a tuple of ints\n        \"\"\"\n        if self.direction in [\"up\", \"down\"]:\n            return (position, start[1])\n        elif self.direction in [\"left\", \"right\"]:\n            return (start[0], position)\n        else:\n            raise ValueError(\"No direction defined!\")\n\n    ###########################################################\n    # Style Properties\n    ###########################################################\n\n    @property\n    def link_style(self):\n        \"\"\"The style of the links in the TreeDiagram\n\n        Returns:\n            str\n        \"\"\"\n        return self._link_style\n\n    @link_style.setter\n    def link_style(self, d):\n        link_styles = [\"orthogonal\", \"straight\", \"curved\"]\n        if d in link_styles:\n            self._link_style = d\n        else:\n            raise ValueError(\n                \"{0} is not a valid entry for link_style. Must be {1}.\".format(\n                    d, \", \".join(link_styles)\n                )\n            )\n\n    @property\n    def link_style_dict(self):\n        \"\"\"Returns the correct waypoint style for the set link_style\n\n        Returns:\n            dict: A dict with 'waypoint' as a key then the set link_style\n        \"\"\"\n        if self.link_style == \"orthogonal\":\n            return {\"waypoints\": \"orthogonal\"}\n        elif self.link_style == \"straight\":\n            return {\"waypoints\": \"straight\"}\n        elif self.link_style == \"curved\":\n            return {\"waypoints\": \"curved\"}\n\n    ###########################################################\n    # Object Linking and Sorting\n    ###########################################################\n\n    def add_object(self, obj, **kwargs):\n        if obj not in self.objects:\n            obj.page = self.page\n            if \"parent\" in kwargs:\n                obj.parent = kwargs.get(\"parent\")\n            self.objects.append(obj)\n\n    ###########################################################\n    # Layout and Output\n    ###########################################################\n\n    @property\n    def roots(self):\n        return [x for x in self.objects if x.parent is None]\n\n    def auto_layout(self):\n        def layout_child(parent):\n            grp = TreeGroup(tree=self)\n            grp.parent_object = parent\n            if len(parent.children) > 0:\n                # has children, go through each leaf and check its children\n                for leaf in parent.children:\n                    self.connect(parent, leaf)\n                    if len(leaf.children) > 0:\n                        # If this leaf has its own children then recursive call\n                        grp.add_object(layout_child(leaf))\n                    else:\n                        grp.add_object(leaf)\n\n                # layout the row\n                grp = layout_group(grp)\n                # grp = add_parent(grp, parent)\n                grp.center_parent()\n            return grp\n\n        def layout_group(grp, pos=self.origin):\n            pos = self.origin\n\n            for leaf in grp.objects:\n                if leaf is not grp.parent_object:\n                    leaf.position = pos\n                    pos = self.move_in_level(\n                        pos, leaf.size_in_level + self.item_spacing\n                    )\n            return grp\n\n        # def add_parent(grp, parent):\n        #     pos = grp.center_position\n        #     level_space = (\n        #         grp.size_of_level / 2\n        #         + self.level_spacing\n        #         + parent.size_of_level / 2\n        #     )\n        #     pos = self.move_between_levels(pos, -level_space)\n        #     parent.center_position = pos\n        #     # add the parent_object\n        #     grp.parent_object = parent\n        #     return grp\n\n        top_group = TreeGroup(tree=self)\n\n        for root in self.roots:\n            top_group.add_object(layout_child(root))\n\n        if len(top_group.objects) > 0:\n            # Position top group\n            top_group = layout_group(top_group)\n            # Center the top group\n            pos = self.origin\n            pos = self.move_between_levels(pos, top_group.size_of_level / 2)\n            top_group.center_position = pos\n\n        # lastly add peer links\n        self.connect_peers()\n\n        return top_group\n\n    def connect_peers(self):\n        peer_style = {\n            \"endArrow\": \"none\",\n            \"dashed\": 1,\n            \"html\": 1,\n            \"rounded\": 0,\n            \"exitX\": 1,\n            \"exitY\": 0.5,\n            \"exitDx\": 0,\n            \"exitDy\": 0,\n            \"entryX\": 0,\n            \"entryY\": 0.5,\n            \"entryDx\": 0,\n            \"entryDx\": 0,\n            \"edgeStyle\": \"orthogonalEdgeStyle\",\n        }\n        for obj in self.objects:\n            for peer in obj.peers:\n                link_exists = False\n                for link in self.links:\n                    if link.source == obj and link.target == peer:\n                        link_exists = True\n                    elif link.source == peer and link.target == obj:\n                        link_exists = True\n                if not link_exists:\n                    edge = Edge(page=self.page, source=obj, target=peer)\n                    edge.apply_attribute_dict(peer_style)\n                    self.links.append(edge)\n\n    def connect(self, source, target):\n        edge = Edge(page=self.page, source=source, target=target)\n        edge.apply_attribute_dict(self.link_style_dict)\n        if self.direction == \"down\":\n            # parent style\n            edge.exitX = 0.5\n            edge.exitY = 1\n            # child style\n            edge.entryX = 0.5\n            edge.entryY = 0\n        elif self.direction == \"up\":\n            # parent style\n            edge.exitX = 0.5\n            edge.exitY = 0\n            # child style\n            edge.entryX = 0.5\n            edge.entryY = 1\n        elif self.direction == \"left\":\n            # parent style\n            edge.exitX = 0\n            edge.exitY = 0.5\n            # child style\n            edge.entryX = 1\n            edge.entryY = 0.5\n        elif self.direction == \"right\":\n            # parent style\n            edge.exitX = 1\n            edge.exitY = 0.5\n            # child style\n            edge.entryX = 0\n            edge.entryY = 0.5\n        self.links.append(edge)\n\n    def draw_connections(self):\n        # Draw connections\n        for lvl in self.objects.values():\n            for obj in lvl:\n                if obj.parent is not None:\n                    self.connect(source=obj.parent, target=obj)\n\n    def write(self, **kwargs):\n        self.file.write(**kwargs)\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.direction","title":"direction property writable","text":"

The direction the tree diagram should grow. Options are \"up\", \"down\", \"left\", or \"right\".

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.file_name","title":"file_name property writable","text":"

The file name of the TreeDiagram

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.file_path","title":"file_path property writable","text":"

The file path where the TreeDiagram will be saved

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.link_style","title":"link_style property writable","text":"

The style of the links in the TreeDiagram

Returns:

Type Description

str

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.link_style_dict","title":"link_style_dict property","text":"

Returns the correct waypoint style for the set link_style

Returns:

Name Type Description dict

A dict with 'waypoint' as a key then the set link_style

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.origin","title":"origin property","text":"

The origin points of the TreeDiagram. This is the point where the center of the top level of the TreeDiagram starts from. By default it's set to the top center of an edge of the page. Which edge depends on the direction of the tree diagram.

Returns:

Name Type Description tuple

A tuple of ints

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.__init__","title":"__init__(**kwargs)","text":"

The TreeDiagram initiates its own File and Page objects. There are a number of formatting parameters that can be set to fine tune the rendering of the tree.

Other Parameters:

Name Type Description direction str

Direction that the tree grows from the root. Options are 'up', 'down', 'left', and 'right'. Defaults to 'down'.

link_style str

Connection style of the edges. Options are 'orthogonal', 'straight', and 'curved'. Defaults to 'orthogonal'.

level_spacing int

Spacing in pixels between levels. Defaults to 60.

item_spacing int

Spacing in pixels between groups within a level. Defaults to 15.

padding int

Spacing in pixels between objects within a group. Defaults to 10.

file_name str

The name of the tree diagram.

file_path str

The path where the tree diagram should be saved.

Source code in src/drawpyo/diagram_types/tree.py
def __init__(self, **kwargs):\n    \"\"\"The TreeDiagram initiates its own File and Page objects. There are a number of formatting parameters that can be set to fine tune the rendering of the tree.\n\n    Keyword Args:\n        direction (str, optional): Direction that the tree grows from the root. Options are 'up', 'down', 'left', and 'right'. Defaults to 'down'.\n        link_style (str, optional): Connection style of the edges. Options are 'orthogonal', 'straight', and 'curved'. Defaults to 'orthogonal'.\n        level_spacing (int, optional): Spacing in pixels between levels. Defaults to 60.\n        item_spacing (int, optional): Spacing in pixels between groups within a level. Defaults to 15.\n        padding (int, optional): Spacing in pixels between objects within a group. Defaults to 10.\n        file_name (str, optional): The name of the tree diagram.\n        file_path (str, optional): The path where the tree diagram should be saved.\n    \"\"\"\n    # formatting\n    self.level_spacing = kwargs.get(\"level_spacing\", 60)\n    self.item_spacing = kwargs.get(\"item_spacing\", 15)\n    self.group_spacing = kwargs.get(\"group_spacing\", 30)\n    self.direction = kwargs.get(\"direction\", \"down\")\n    self.link_style = kwargs.get(\"link_style\", \"orthogonal\")\n    self.padding = kwargs.get(\"padding\", 10)\n\n    # Set up the File and Page objects\n    self.file = File()\n    self.file_name = kwargs.get(\"file_name\", \"Heirarchical Diagram.drawio\")\n    self.file_path = kwargs.get(\"file_path\", r\"C:/\")\n    self.page = Page(file=self.file)\n\n    # Set up object and level lists\n    self.objects = []\n    self.links = []\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.abs_move_between_levels","title":"abs_move_between_levels(start, position)","text":"

The functions takes in a starting position and an absolute position along the coordinates between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def abs_move_between_levels(self, start, position):\n    \"\"\"The functions takes in a starting position and an absolute position along the coordinates between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction == \"up\":\n        return (start[0], position)\n    elif self.direction == \"down\":\n        return (start[0], position)\n    elif self.direction == \"left\":\n        return (position, start[1])\n    elif self.direction == \"right\":\n        return (position, start[1])\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.abs_move_in_level","title":"abs_move_in_level(start, position)","text":"

The functions takes in a starting position and an absolute position along the coordinates within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def abs_move_in_level(self, start, position):\n    \"\"\"The functions takes in a starting position and an absolute position along the coordinates within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction in [\"up\", \"down\"]:\n        return (position, start[1])\n    elif self.direction in [\"left\", \"right\"]:\n        return (start[0], position)\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.level_move","title":"level_move(move)","text":"

The functions takes in a relative distance to move within levels. It outputs a tuple with the relative move in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default move int

The amount to move within levels

required

Returns:

Name Type Description tuple

A tuple containing a 0 and the move, in the right orientation.

Source code in src/drawpyo/diagram_types/tree.py
def level_move(self, move):\n    \"\"\"The functions takes in a relative distance to move within levels. It outputs a tuple with the relative move in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        move (int): The amount to move within levels\n\n    Returns:\n        tuple: A tuple containing a 0 and the move, in the right orientation.\n    \"\"\"\n    if self.direction in [\"up\", \"down\"]:\n        return (0, move)\n    elif self.direction in [\"left\", \"right\"]:\n        return (move, 0)\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.move_between_levels","title":"move_between_levels(start, move)","text":"

The functions takes in a starting position and a relative distance to move between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def move_between_levels(self, start, move):\n    \"\"\"The functions takes in a starting position and a relative distance to move between levels. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction == \"up\":\n        return (start[0], start[1] - move)\n    elif self.direction == \"down\":\n        return (start[0], start[1] + move)\n    elif self.direction == \"left\":\n        return (start[0] - move, start[1])\n    elif self.direction == \"right\":\n        return (start[0] + move, start[1])\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeDiagram.move_in_level","title":"move_in_level(start, move)","text":"

The functions takes in a starting position and a relative distance to move within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.

Parameters:

Name Type Description Default start tuple

The starting position, a tuple of ints

required move int

The direction to move between levels.

required

Raises:

Type Description ValueError

\"No direction defined!\"

Returns:

Name Type Description tuple

The final position, a tuple of ints

Source code in src/drawpyo/diagram_types/tree.py
def move_in_level(self, start, move):\n    \"\"\"The functions takes in a starting position and a relative distance to move within a level. It outputs a tuple with the final absolute position in the correct direction (horizontal or vertical) depending on the direction of the tree diagram.\n\n    Args:\n        start (tuple): The starting position, a tuple of ints\n        move (int): The direction to move between levels.\n\n    Raises:\n        ValueError: \"No direction defined!\"\n\n    Returns:\n        tuple: The final position, a tuple of ints\n    \"\"\"\n    if self.direction in [\"up\", \"down\"]:\n        return (start[0] + move, start[1])\n    elif self.direction in [\"left\", \"right\"]:\n        return (start[0], start[1] + move)\n    else:\n        raise ValueError(\"No direction defined!\")\n
"},{"location":"api/tree_diagram/treediagram/#treegroup","title":"TreeGroup","text":""},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup","title":"src.drawpyo.diagram_types.tree.TreeGroup","text":"

Bases: Group

This class defines a group within a TreeDiagram. When a set of NodeObjects share the same parent they're grouped together for auto positioning. Each level of a TreeDiagram is a set of groups.

Source code in src/drawpyo/diagram_types/tree.py
class TreeGroup(Group):\n    \"\"\"This class defines a group within a TreeDiagram. When a set of NodeObjects share the same parent they're grouped together for auto positioning. Each level of a TreeDiagram is a set of groups.\"\"\"\n\n    def __init__(self, tree=None, parent_object=None, **kwargs):\n        \"\"\"The TreeGroup is instantiated with all the arguments of the Group. Additionally, the owning tree and the parent_object.\n\n        Args:\n            tree (TreeDiagram, optional): The TreeDiagram that owns the group. Defaults to None.\n            parent_object (NodeObject, optional): The parent object in the group. Defaults to None.\n        \"\"\"\n        super().__init__(**kwargs)\n        self.parent_object = parent_object\n        self.tree = tree\n\n    @property\n    def parent_object(self):\n        \"\"\"The object that defines the parent of the group.\n\n        Returns:\n            NodeObject\n        \"\"\"\n        return self._parent_object\n\n    @parent_object.setter\n    def parent_object(self, value):\n        if value is not None:\n            self.add_object(value)\n        self._parent_object = value\n\n    def center_parent(self):\n        \"\"\"This function centers the parent_objects along the group and then offsets it by the level spacing.\"\"\"\n        children_grp = TreeGroup(tree=self.tree)\n        for obj in self.objects:\n            if obj is not self.parent_object:\n                children_grp.add_object(obj)\n        pos = children_grp.center_position\n\n        level_space = (\n            children_grp.size_of_level / 2\n            + self.tree.level_spacing\n            + self.parent_object.size_of_level / 2\n        )\n        pos = self.tree.move_between_levels(pos, -level_space)\n        self.parent_object.center_position = pos\n\n    # I don't love that these are copy-pasted from NodeObject but the multiple\n    # inheritance was too much of a pain to have TreeGroup inherit.\n    @property\n    def size_of_level(self):\n        \"\"\"The height or the width of the level, depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.height\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.width\n\n    @property\n    def size_in_level(self):\n        \"\"\"The size of the object within its level, either its width or height depending on tree orientation.\n\n        Returns:\n            int\n        \"\"\"\n        if self.tree is not None:\n            if self.tree.direction in [\"up\", \"down\"]:\n                return self.width\n            elif self.tree.direction in [\"left\", \"right\"]:\n                return self.height\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.parent_object","title":"parent_object property writable","text":"

The object that defines the parent of the group.

Returns:

Type Description

NodeObject

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.size_in_level","title":"size_in_level property","text":"

The size of the object within its level, either its width or height depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.size_of_level","title":"size_of_level property","text":"

The height or the width of the level, depending on tree orientation.

Returns:

Type Description

int

"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.__init__","title":"__init__(tree=None, parent_object=None, **kwargs)","text":"

The TreeGroup is instantiated with all the arguments of the Group. Additionally, the owning tree and the parent_object.

Parameters:

Name Type Description Default tree TreeDiagram

The TreeDiagram that owns the group. Defaults to None.

None parent_object NodeObject

The parent object in the group. Defaults to None.

None Source code in src/drawpyo/diagram_types/tree.py
def __init__(self, tree=None, parent_object=None, **kwargs):\n    \"\"\"The TreeGroup is instantiated with all the arguments of the Group. Additionally, the owning tree and the parent_object.\n\n    Args:\n        tree (TreeDiagram, optional): The TreeDiagram that owns the group. Defaults to None.\n        parent_object (NodeObject, optional): The parent object in the group. Defaults to None.\n    \"\"\"\n    super().__init__(**kwargs)\n    self.parent_object = parent_object\n    self.tree = tree\n
"},{"location":"api/tree_diagram/treediagram/#src.drawpyo.diagram_types.tree.TreeGroup.center_parent","title":"center_parent()","text":"

This function centers the parent_objects along the group and then offsets it by the level spacing.

Source code in src/drawpyo/diagram_types/tree.py
def center_parent(self):\n    \"\"\"This function centers the parent_objects along the group and then offsets it by the level spacing.\"\"\"\n    children_grp = TreeGroup(tree=self.tree)\n    for obj in self.objects:\n        if obj is not self.parent_object:\n            children_grp.add_object(obj)\n    pos = children_grp.center_position\n\n    level_space = (\n        children_grp.size_of_level / 2\n        + self.tree.level_spacing\n        + self.parent_object.size_of_level / 2\n    )\n    pos = self.tree.move_between_levels(pos, -level_space)\n    self.parent_object.center_position = pos\n
"},{"location":"diagram_types/tree_diagrams/","title":"Tree Diagrams","text":"

These very useful diagram types are why drawpyo was written initially! The TreeDiagram module allows the easy creation of heirarchical directed trees, managing the parent and children relationships, then providing a convenient auto layout function.

"},{"location":"diagram_types/tree_diagrams/#create-a-tree","title":"Create a Tree","text":"

The two main objects to work with in drawpyo's trees are TreeDiagrams and NodeObjects. To start, create a TreeDiagram:

import drawpyo.diagram_types import TreeDiagram\n\ntree = TreeDiagram(\n    file_path = 'path/to/tree',\n    file_name = 'Tree Name.drawio',\n)\n

There are a number of configuration parameters available to fine tune the layout of the TreeDiagram. They can be passed in during initialization or later.

Parameter Effect Default direction direction that the tree grows from the root ('up', 'down', 'left', 'right') 'down' link_style Connection style of the edges ('orthogonal', 'straight', 'curved') 'orthogonal' level_spacing Spacing in pixels between levels 60 item_spacing Spacing in pixels between groups within a level 15 padding Spacing in pixels between objects within a group 10"},{"location":"diagram_types/tree_diagrams/#add-nodes","title":"Add Nodes","text":"

The custom object type that defines the nodes on the tree are called NodeObjects. Create some NodeObjects:

from drawpyo.diagram_types import NodeObject\n\n# Top object\ngrinders = NodeObject(tree=tree, value=\"Appliances for Grinding Coffee\", base_style=\"rounded rectangle\")\n\n# Main categories\nblade_grinders = NodeObject(tree=tree, value=\"Blade Grinders\", parent=grinders)\nburr_grinders = NodeObject(tree=tree, value=\"Burr Grinders\", parent=grinders)\nblunt_objects = NodeObject(tree=tree, value=\"Blunt Objects\", parent=grinders)\n

Note that the base_style was manually declared for the first object. But NodeObjects will default to \"rounded rectangle\" so it's not necessary for every one. Any NodeObject can be a parent, so you can keep adding objects down the tree:

# Other\nelec_blade = NodeObject(tree=tree, value=\"Electric Blade Grinder\", parent=blade_grinders)\nmnp = NodeObject(tree=tree, value=\"Mortar and Pestle\", parent=blunt_objects)\n\n# Conical Burrs\nconical = NodeObject(tree=tree, value=\"Conical Burrs\", parent=burr_grinders)\nelec_conical = NodeObject(tree=tree, value=\"Electric\", parent=conical)\nmanual_conical = NodeObject(tree=tree, value=\"Manual\", parent=conical)\n

Important Note: TreeDiagrams do not currently support NodeObjects with multiple parents! It may not ever as this seriously complicates the auto layout process. However, you can add links between any two objects in the tree and render them in the diagram. They just may look ugly until you manually rearrange the diagram.

Finally, before writing the diagram you'll want to run the magic penultimate step: auto layout.

tree.auto_layout()\ntree.write()\n

With some more additions, the resulting diagram renders as:

"},{"location":"usage/basic_usage/","title":"Basic Functionality","text":"

Drawpyo's basic functionality provides the same features as using the Draw.io app. You can create files with one or more pages, add objects to them, and position those objects. You can style objects from built-in shape libraries, manually, or from style strings. Those objects can be shapes, containers, or edges to connect them. Finally you can save your diagrams where they can be opened with the Draw.io app.

"},{"location":"usage/basic_usage/#files","title":"Files","text":""},{"location":"usage/basic_usage/#make-a-new-file","title":"Make a new file","text":"

A File object represents a Draw.io file. If no file_path is set the default path will be 'user/Drawpyo Charts' where 'user' will be an OS-specific user home folder.

diagram = drawpyo.File()\nfile.file_path = r\"C:\\drawpyo\"\nfile.file_name = \"Test Generated Edges.drawio\"\n
"},{"location":"usage/basic_usage/#write-a-file","title":"Write a file","text":"

Files can be written simply with the write() function. This function takes a few parameters to make it more flexible: | Parameter | Setting | | - | - | | file_path | This will overwrite the previously set file_path. | | file_name | This will overwrite the previously set file_name. Like file_path, useful in creating multiple copies of a diagram with slight variations | | overwrite | This boolean parameter controls whether an existing diagram should be overwritten or not. |

"},{"location":"usage/basic_usage/#pages","title":"Pages","text":""},{"location":"usage/basic_usage/#add-a-page","title":"Add a page","text":"

The Page object represents the different diagram pages that you can create in Draw.io. A Page can be created without linking it to a File but it won't be writable without a File object.

# Add a page\npage = drawpy.Page(file=file)\n
"},{"location":"usage/basic_usage/#page-parameters","title":"Page Parameters","text":"

There are a number of customizable parameter for pages:

argument description width Width of the document in pixels height Height of the document in pixels grid Enable grid (0 or 1) grid_size Side of grid squares in pixels guides Enable guides (0 or 1) tooltips Enable tooltips (0 or 1) scale Scale of the drawing"},{"location":"usage/edges/","title":"Edges","text":"

Edges are the lines and arrows that connect objects in Draw.io. There's quite a bit of variabiability in how they're created and styled so there's a bit more complexity than with objects.

"},{"location":"usage/edges/#creating-a-basic-edge","title":"Creating a basic edge","text":"

Like objects, there's a Edge object that can be easily created:

link = drawpyo.diagram.Edge(\n    page=page,\n    source=item_1,\n    target=item_2,\n    )\n
"},{"location":"usage/edges/#edge-labels","title":"Edge Labels","text":"

The value of an edge is the label that appears on it. It can be set using the label value.

The position of the label can be fine tuned with two parameters:

Parameter Effect label_position The position along the edge's axis where the label appears. This is float value between -1 and 1. 0 is neutral/in the center, -1 is at the source, and 1 is at the target. label_offset The offset in pixels perpendicular to the axis of the edge."},{"location":"usage/edges/#label-positions-rendered","title":"Label Positions Rendered","text":""},{"location":"usage/edges/#edge-geometry","title":"Edge Geometry","text":"

Besides the source and target, the edge geometry can be very finely tuned. There are eight parameters that control where and how the edge meets the source and target objects:

Parameter Definition entryX From where along the X axis on the source object the edge originates (0-1) entryY From where along the Y axis on the source object the edge originates (0-1) entryDx Applies an offset in pixels to the X axis entry point entryDy Applies an offset in pixels to the Y axis entry point exitX From where along the X axis on the target object the edge originates\u00a0(0-1) exitY From where along the Y axis on the target object the edge originates\u00a0(0-1) exitDx Applies an offset in pixels to the X axis exit point exitDy Applies an offset in pixels to the Y axis exit point targetPerimeterSpacing The negative or positive spacing between the target and end of the edge in points sourcePerimeterSpacing The negative or positive spacing between the source and end of the edge in points

If these parameters are set to None then the Draw.io rendering engine will place the origination and direction of the edge wherever makes the most sense based on the layout of the objects. This is the same as the behavior in the app when an edge is dragged to the center of a shape (highlighting the whole object green) instead of to a specific node on the border (and seeing just that node highlighted in green).

They can also be set to X and Y coordinates designating where on the source and target objects the edge will meet it. The rest of the routing will be handled automatically.

Some examples of different coordinate settings:

Other attributes for controlling the general shape of the object are:

Parameter Definition jettySize Defines the length of the straight line coming out of or into an object before the edge makes its first turn"},{"location":"usage/edges/#points","title":"Points","text":"

You can also add points to Edges to further fine tune their routing. This isn't always necessary, usually setting the entry/exit parameters handles the auto routing correctly. However this is an option, using the Edge.add_point() and Edge.add_point_pos() functions. The edge will then route through those points but auto layout otherwise.

"},{"location":"usage/edges/#styling-edges","title":"Styling edges","text":"

Just about every edge styling option from the Draw.io app is implemented in Drawpyo. It's easiest to just play with all of the different line styling options in Draw.io to understand how they render but the major options are listed here.

"},{"location":"usage/edges/#text-styling","title":"Text Styling","text":"

The styling within an an edge label is contained inside of a TextFormat object. All styling parameters can be accessed at the attribute Edge.text_format, which contains a TextFormat object.

For more information about styling text, see Formatting Text for more information.

"},{"location":"usage/edges/#color-and-shading","title":"Color and Shading","text":"

Edge coloring can be set with a stroke and fill color, though only the stroke applies to a simple edge.

Parameter Effect opacity The opacity of the edge (0-100) strokeColor The color of the edge or the stroke around the edge shape ('default', 'none', or a hex color code) fillColor The fill color of the edge shape\u00a0('default', 'none', or a hex color code)"},{"location":"usage/edges/#effects","title":"Effects","text":"

Draw.io has four effects that can be set on an edge. They're all boolean valuable that can be enabled.

Paramater Rendered default (None) rounded shadow sketch flowAnimation*

*(this animates in Draw.io)

"},{"location":"usage/edges/#jumps","title":"Jumps","text":"

By default, when an edge crosses another edge they'll just be rendered as a cross. You can also enable line jumps; the top edge will 'jump' over the bottom edge. There are different styles of line jumps and they can have variable sizes as well.

Parameter Effect jumpStyle The style of the line jump. Can be 'arc', 'gap', 'sharp', or 'line'. jumpSize The size of the rendered line jumps in points.

The different rendered jump styles are:

Parameter Rendered default (None) arc gap sharp line"},{"location":"usage/edges/#waypoints","title":"Waypoints","text":"

The waypoint parameter controls how the line is routed from the source to the target. For example, a straight line is just point to point. A curved line tries to maintain gentle curves and perpendicularity to the source and target objects. Options are:

Parameter Rendered default (None) straight orthogonal vertical horizontal isometric isometric_vertical curved entity_relation"},{"location":"usage/edges/#connections","title":"Connections","text":"

The connection parameter is abstractly named but it controls what type of edge this is. Most edges are lines but other types are available.

Parameter Rendered default (None) line link arrow simple_arrow"},{"location":"usage/edges/#patterns","title":"Patterns","text":"

The pattern parameter controls how the line stroke is rendered. Options are:

Parameter Rendered default (None) solid dashed_small dashed_medium dashed_large dotted_small dotted_medium dotted_large"},{"location":"usage/edges/#line-ends","title":"Line Ends","text":"

The line_end_target and line_end_source parameter sets whatever is rendered where the edge meets the objects. There are secondary boolean parameters for the fill of the ends (endFill_target and endFill_source) but not all ends can be filled.

The line end size can also be adjusted with endSize and startSize parameters, both set in points.

Parameter Rendered Unfilled Rendered Filled default (None) na classic classicThin open na openThin na openAsync na block blockThin async oval diamond diamondThin dash na halfCircle na cross na circlePlus na circle na baseDash na ERone na ERmandOne na ERmany na ERoneToMany na ERzeroToOne na ERzeroToMany na doubleBlock"},{"location":"usage/objects/","title":"Objects","text":"

Though some diagram types have their own object subclasses, the main class for creating objects is the Object class.

"},{"location":"usage/objects/#creating-a-basic-object","title":"Creating a basic object","text":"
base_obj = drawpyo.diagram.Object(page=page)\n

The default object type is a rounded corner rectangle with white background and a black border just like in the Draw.io app.

The value attribute holds the text to display in the object.

base_obj.value = \"This Object's Name is Fred\"\n

"},{"location":"usage/objects/#creating-an-object-from-a-shape-library","title":"Creating an object from a shape library","text":"

Just like the built-in shape libraries in the Draw.io app, Drawpyo supports generating shapes from libraries. Currently the 'general' and 'flowchart' libraries from the Draw.io app is defined but more will be added in the future.

These libraries are defined in TOML files and drawpyo supports importing custom shape libraries! See Shape Libraries for more information.

To generate an object from a library:

object = drawpyo.diagram.object_from_library(\n    library=\"general\",\n    obj_name=\"process\",\n    page=page,\n    )\n

This function returns a normal Object but prestyled by the library. It can then be further styled or modified.

"},{"location":"usage/objects/#object-geometry","title":"Object Geometry","text":"

All objects contain a structure called ObjectGeometry that provides a layer of abstraction. Interacting directly with the geometry class is optional.

"},{"location":"usage/objects/#object-sizing","title":"Object Sizing","text":"

The three parameters that affect object placement are size and aspect. Size has to be set individually with the .width and .height attributes.

Object.width = 120\nObject.height = 80\nObject.aspect = 'fixed'\n

In earlier versions there was a 'size' attribute. But then it was found that 'size' was also used as a style attribute for certain shapes so the geometry size attribute was removed in favor of using width and height directly.

"},{"location":"usage/objects/#object-geometry-and-placement","title":"Object Geometry and Placement","text":"

Repositioning objects is simple but there are a few convenience features to know about. There are two attributes available for setting the position by either the top left corner or the center:

Object.position = (0, 0)\nObject.center_position = (0, 0)\n

The X and Y positions can also be accessed directly in the geometry object.

Object.geometry.x = 0\nObject.geometry.y = 0\n
"},{"location":"usage/objects/#styling-objects","title":"Styling Objects","text":""},{"location":"usage/objects/#generating-from-a-style-string","title":"Generating from a style string","text":"

While styling an object from scratch in drawpyo is possible, you're probably using drawpyo because Draw.io exists and is a great UI so use it! The easiest workflow is to style objects in Draw.io, or at least play with the different parameters to understand how they'll render visually.

Once you have an object styled in Draw.io how you like it, you can replicate the styling attributes you want manually or just copy the style string.

To do this, first style an object as much as you want:

Then right click on the object and select 'Edit Style:'. The following pop-up will show the exact style string:

This style string can be copied into the drawpyo function apply_style_string:

style_str_obj = drawpyo.diagram.Object(page=page)\n\nstyle_str_obj.apply_style_string(\n    \"rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#63B6FF;glass=1;strokeWidth=5;shadow=1;\"\n)\n

The style_str_obj will now have all of the custom styled attributes. It can also be used as a template object for others.

"},{"location":"usage/objects/#styling-manually","title":"Styling Manually","text":"

There are infinite permutations of object formatting and styling available. There are some higher order attributes that set the template for the object. What lower order styling attributes may or may not apply in combination. Then there are attributes like size and text formatting that apply in all cases. These interactions are difficult to predict in drawpyo alone so a good way to get familiar with all of the possible options and types of customizations is just to play with the Draw.io app directly to design formatting to your taste.

Almost all styling attributes are optional (and drawpyo adds the non-optional ones automatically). If an attribute is unset or set to None then it won't be included in the file output. This will set that specific styling behavior to a default mode.

"},{"location":"usage/objects/#text-styling","title":"Text Styling","text":"

The styling within an object is contained inside of a TextFormat object. All styling parameters can be accessed at the attribute Object.text_format, which contains a TextFormat object.

For more information about styling text, see Formatting Text for more information.

"},{"location":"usage/objects/#basestyle-and-shape","title":"BaseStyle and Shape","text":"

The highest order styling attribute in Draw.io for objects is shape. This sets how the object behaves and is rendered. Different values include:

and many more.

Confusingly there is another attribute called baseStyle that is sometimes used in combination with shape and sometimes without.

BaseStyles include:

It can be hard to predict how these two attributes will interact. To utilize them it's recommended to start in the Draw.io app, use their shape libraries or templates to get the desired style, then look at the style string to see what shape and baseStyle were used. When creating an object from a shape library these two attributes are handled automatically.

"},{"location":"usage/objects/#basic-styling-attributes","title":"Basic Styling Attributes","text":"

These attributes mostly apply to most shape/baseStyle combinations and can be set on almost any object.

"},{"location":"usage/objects/#further-styling-attributes","title":"Further Styling Attributes","text":"

As mentioned above, not all of these attributes will apply to all object shapes and types. But some commonly called include:

"},{"location":"usage/shape_libs/","title":"Shape Libraries","text":"

The Draw.io app has a lot of built-in shape libraries available. The basic library contains shapes and building blocks but there are increasingly more specific libraries such as flowcharts, wiring diagrams, and org charts. You can also export and import shape libraries into Draw.io.

To replicate this feature for drawpyo, I created a library format based on TOML. Draw.io's libraries are XML which isn't as human readable or writable and is more specification than necessary.

Supporting Draw.io's XML based library is a planned feature.

"},{"location":"usage/shape_libs/#built-in-shape-libaries","title":"Built-In Shape Libaries","text":"

Drawpyo uses these TOML shape libraries to store the default libaries. The default libraries are in /drawpyo/shape_libraries. These are the libraries that are available in the Draw.io app.

Implemented default libraries:

There is also a set of TOML databases for other formats, like all of the various combinations of edge styles and the line styles. These are stored in /drawpyo/formatting_database.

"},{"location":"usage/shape_libs/#custom-shape-libaries","title":"Custom Shape Libaries","text":"

This functionality is available to the user so you can define your own custom libraries! TOML was selected because it's a very simple and human-readable config file format. the TOML project website has a very nice high level overview. But drawpyo is hardly scratching the surface of what TOML is capable of so little expertise is needed.

"},{"location":"usage/shape_libs/#creating-a-shape-library","title":"Creating a Shape Library","text":"

To define a shape library create a .toml file. Current convention is to start with a title tag for clarity.

title = \"Custom drawpyo shapes\"\n

You can then define a custom object by naming the object in square brackets and adding whichever attributes you want:

[square]\nwidth = 80\nheight = 80\naspect = \"fixed\"\n

You can also have any shape inherit another and then either modify or extend its style:

[perfect_circle]\ninherit = \"square\"\nbaseStyle = \"ellipse\"\n

This perfect_circle will now inherit the fixed aspect and size attributes from square but with the ellipse baseStyle.

"},{"location":"usage/shape_libs/#style-attribute-types","title":"Style Attribute Types","text":"

The attributes in the TOML file can come from three sets:

"},{"location":"usage/shape_libs/#drawpyo-attributes-snake_case","title":"Drawpyo attributes (snake_case)","text":"

These are the attributes that drawpyo uses to abstract some complicated style strings, such as size instead of the Draw.io parameters of width and height.

"},{"location":"usage/shape_libs/#predefined-style-attributes","title":"Predefined style attributes","text":"

Such as any of the attributes listed in the Styling section of Objects. These will simply be overwritten with the values in the TOML file.

"},{"location":"usage/shape_libs/#any-new-style-attributes","title":"Any new style attributes","text":"

If you want to add a rare style attribute that drawpyo hasn't defined or worked with yet, no worries! When you import the TOML library if there are new style attributes defined then they'll get added to the Object and exported into the Draw.io file.

"},{"location":"usage/shape_libs/#using-a-custom-library","title":"Using a Custom Library","text":"

To use a custom shape library it just needs to be imported then passed to the object definition function:

custom_library = drawpyo.diagram.import_shape_database(\n\u00a0\u00a0\u00a0\u00a0file_name=r\"path/to/toml_lib\"\n\u00a0\u00a0\u00a0\u00a0)\n\nnew_obj = drawpyo.diagram.object_from_library(\n    library = custom_library,\n    obj_name = 'object_name_from_lib',\n    page=page,\n    )\n
"},{"location":"usage/text_format/","title":"Formatting Text","text":"

Everywhere that text appears in Draw.io has the same basic text formatting options. TO support this in drawpyo there's a custom class, TextFormat, that handles all of these options for code reusability. This also means that TextFormat objects can be created and copied into new objects or edges to make reformatting text convenient.

Any object with formattable text will have a .text_format attribute that holds a TextFormat class.

"},{"location":"usage/text_format/#type-face-attributes","title":"Type Face Attributes","text":"Attribute Data Type Description fontFamily str The typeface to use. See Draw.io for a list of font choices. fontSize int The size of the font in points fontColor str The color of the typeface bold bool Bold font italic bool Italic font underline bool Underlined font textShadow bool Whether to place a shadow underneath the text textOpacity int The transparency level of the text. 0-100"},{"location":"usage/text_format/#text-alignment-and-spacing-attributes","title":"Text Alignment and Spacing Attributes","text":"

The text is rendered inside a box and various layout and alignment choices can be made to control where and how it's positioned.

Attribute Data Type Description spacing int The global spacing to add around the text and the outside of the bounding box spacingTop int The top spacing to add around the text spacingBottom int The bottom spacing to add around the text spacingLeft int The left spacing to add around the text spacingRight int The right spacing to add around the text direction str The direction to orient the text. Can be 'horizontal' or 'vertical' align str The horizontal alignment of the text. Can be 'left', 'center', or 'right' verticalAlign str The vertical alignment of the text. Can be 'top', 'middle', or 'bottom'

Spacing Attributes

"},{"location":"usage/text_format/#label-box-attributes","title":"Label Box Attributes","text":"

Some aspects of the text bounding box itself can also be formatted.

Attribute Data Type Description labelBorderColor str The color of the border around the bounding box labelBackgroundColor str The color of the fill of the bounding box labelPosition str The position of the bounding box as it relates to the owning object"}]} \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 45aa037..88a1337 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ diff --git a/usage/edges/index.html b/usage/edges/index.html index fdb170a..74f8f5e 100644 --- a/usage/edges/index.html +++ b/usage/edges/index.html @@ -422,6 +422,21 @@ + +
  • @@ -1010,6 +1025,21 @@ + +
  • @@ -1166,6 +1196,8 @@

    Edge Labels

    +

    Label Positions Rendered

    +

    label_positions.png

    Edge Geometry

    Besides the source and target, the edge geometry can be very finely tuned. There are eight parameters that control where and how the edge meets the source and target objects:

    @@ -1219,6 +1251,10 @@

    Edge Geometry

    If these parameters are set to None then the Draw.io rendering engine will place the origination and direction of the edge wherever makes the most sense based on the layout of the objects. This is the same as the behavior in the app when an edge is dragged to the center of a shape (highlighting the whole object green) instead of to a specific node on the border (and seeing just that node highlighted in green).

    +

    They can also be set to X and Y coordinates designating where on the source and target objects the edge will meet it. The rest of the routing will be handled automatically.

    +

    coords_legend.png

    +

    Some examples of different coordinate settings:

    +

    coords_examples.png

    Other attributes for controlling the general shape of the object are:

    @@ -1235,7 +1271,7 @@

    Edge Geometry

    Points

    -

    You can also add points to Edges to further fine tune their routing. This isn't always necessary, usually setting the entry/exit parameters handles the auto routing correctly. However this is an option, using the Edge.add_point() and Edge.add_point_pos() functions.

    +

    You can also add points to Edges to further fine tune their routing. This isn't always necessary, usually setting the entry/exit parameters handles the auto routing correctly. However this is an option, using the Edge.add_point() and Edge.add_point_pos() functions. The edge will then route through those points but auto layout otherwise.

    Styling edges

    Just about every edge styling option from the Draw.io app is implemented in Drawpyo. It's easiest to just play with all of the different line styling options in Draw.io to understand how they render but the major options are listed here.

    Text Styling

    diff --git a/usage/objects/index.html b/usage/objects/index.html index b3a511c..f0131f7 100644 --- a/usage/objects/index.html +++ b/usage/objects/index.html @@ -453,6 +453,25 @@ + +
  • @@ -1047,6 +1071,25 @@ + + @@ -1111,11 +1159,13 @@

    Creating a basic object

    base_obj = drawpyo.diagram.Object(page=page)
     

    The default object type is a rounded corner rectangle with white background and a black border just like in the Draw.io app.

    +

    object_default

    The value attribute holds the text to display in the object.

    base_obj.value = "This Object's Name is Fred"
     
    +

    object_default_fred

    Creating an object from a shape library

    -

    Just like the built-in shape libraries in the Draw.io app, Drawpyo supports generating shapes from libraries. Currently the 'general' library from the Draw.io app is defined but more will be added in the future.

    +

    Just like the built-in shape libraries in the Draw.io app, Drawpyo supports generating shapes from libraries. Currently the 'general' and 'flowchart' libraries from the Draw.io app is defined but more will be added in the future.

    These libraries are defined in TOML files and drawpyo supports importing custom shape libraries! See Shape Libraries for more information.

    @@ -1148,12 +1198,28 @@

    Object Geometry and Placement

    Object.geometry.y = 0

    Styling Objects

    +

    Generating from a style string

    +

    While styling an object from scratch in drawpyo is possible, you're probably using drawpyo because Draw.io exists and is a great UI so use it! The easiest workflow is to style objects in Draw.io, or at least play with the different parameters to understand how they'll render visually.

    +

    Once you have an object styled in Draw.io how you like it, you can replicate the styling attributes you want manually or just copy the style string.

    +

    To do this, first style an object as much as you want:

    +

    stylestr_styled_object

    +

    Then right click on the object and select 'Edit Style:'. The following pop-up will show the exact style string:

    +

    stylestr_edit_style

    +

    This style string can be copied into the drawpyo function apply_style_string:

    +
    style_str_obj = drawpyo.diagram.Object(page=page)
    +
    +style_str_obj.apply_style_string(
    +    "rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#63B6FF;glass=1;strokeWidth=5;shadow=1;"
    +)
    +
    +

    The style_str_obj will now have all of the custom styled attributes. It can also be used as a template object for others.

    +

    Styling Manually

    There are infinite permutations of object formatting and styling available. There are some higher order attributes that set the template for the object. What lower order styling attributes may or may not apply in combination. Then there are attributes like size and text formatting that apply in all cases. These interactions are difficult to predict in drawpyo alone so a good way to get familiar with all of the possible options and types of customizations is just to play with the Draw.io app directly to design formatting to your taste.

    Almost all styling attributes are optional (and drawpyo adds the non-optional ones automatically). If an attribute is unset or set to None then it won't be included in the file output. This will set that specific styling behavior to a default mode.

    -

    Text Styling

    +

    Text Styling

    The styling within an object is contained inside of a TextFormat object. All styling parameters can be accessed at the attribute Object.text_format, which contains a TextFormat object.

    -

    For more information about styling text, see Formatting Text for mor information.

    -

    BaseStyle and Shape

    +

    For more information about styling text, see Formatting Text for more information.

    +

    BaseStyle and Shape

    The highest order styling attribute in Draw.io for objects is shape. This sets how the object behaves and is rendered. Different values include:

    It can be hard to predict how these two attributes will interact. To utilize them it's recommended to start in the Draw.io app, use their shape libraries or templates to get the desired style, then look at the style string to see what shape and baseStyle were used. When creating an object from a shape library these two attributes are handled automatically.

    -

    Basic Styling Attributes

    +

    Basic Styling Attributes

    These attributes mostly apply to most shape/baseStyle combinations and can be set on almost any object.

    -

    Further Styling Attributes

    +

    Further Styling Attributes

    As mentioned above, not all of these attributes will apply to all object shapes and types. But some commonly called include: