tree.auto_layout()
diff --git a/index.html b/index.html
index 245c4e8..92099ac 100644
--- a/index.html
+++ b/index.html
@@ -913,8 +913,8 @@
Welcome to drawpyo
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.
History/Justification
-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.
+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 backwards 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 when I had a need to generate hierarchical 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.
The Future of Drawpyo
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.
diff --git a/objects.inv b/objects.inv
index 6506a0f..3a0c0e3 100644
Binary files a/objects.inv and b/objects.inv differ
diff --git a/search/search_index.json b/search/search_index.json
index 9a51c0b..99c2e3a 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 def add_object(self, obj):\n self.page.add_object(obj)\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/extended_objects/","title":"Extended Objects","text":""},{"location":"api/extended_objects/#list","title":"List","text":""},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List","title":"src.drawpyo.diagram.extended_objects.List
","text":" Bases: Object
Source code in src/drawpyo/diagram/extended_objects.py
class List(Object):\n def __init__(self, title=\"List\", list_items=[], **kwargs):\n \"\"\"The List object wraps the basic Object type but allows easier managing of a list object and its members. All of the arguments and keyword arguments for Object are available here as well.\n\n Args:\n title (str, optional): The name in the heading of the list. Defaults to \"List\".\n list_items (list of strings, optional): A Python list of strings denoting the items. Defaults to empty.\n \"\"\"\n super().__init__(value=title, **kwargs)\n self.format_as_library_object(library=\"general\", obj_name=\"list\")\n self.autosizing = kwargs.get(\"autosizing\", True)\n self.width = kwargs.get(\"width\", 120)\n self.list_items = list_items\n\n @property\n def list_items(self):\n \"\"\"A Python list of strings of the objects in the list.\n\n Returns:\n list of strings: The list items\n \"\"\"\n return [child.value for child in self.children]\n\n @list_items.setter\n def list_items(self, value):\n if not isinstance(value, list):\n raise TypeError(\"list_items must be a list!\")\n self.children = []\n for item in value:\n self.add_item(item)\n\n def add_item(self, item_text):\n \"\"\"This function creates a new Draw.io text item and adds it to the end of the list.\n\n Args:\n item_text (string): The name of the item to add.\n \"\"\"\n new_item = object_from_library(\n library=\"general\", obj_name=\"list_item\", page=self.page\n )\n new_item.value = item_text\n new_item.parent = self\n new_item.width = self.width\n new_item.geometry.y = len(self.list_items) * new_item.height\n if self.autosizing:\n self.autosize()\n\n def remove_item(self, item_text):\n \"\"\"This function removes any list items matching the text passed into the function.\n\n Args:\n item_text (string): The text of the list item to remove.\n \"\"\"\n for child in self.children:\n if child.value == item_text:\n self.remove_object(child)\n self.page.remove_object(child)\n del child\n if self.autosizing:\n self.autosize()\n\n def autosize(self):\n \"\"\"This function resizes the parent List object to match the length of the list of items. It also restacks the list items to fill any gaps from deleted items.\n \"\"\"\n y_pos = self.startSize\n for child in self.children:\n child.geometry.y = y_pos\n y_pos = y_pos + child.height\n self.height = self.startSize + sum(child.height for child in self.children)\n self.width = min(child.width for child in self.children)\n\n @property\n def width(self):\n \"\"\"The width of the object. The difference between List's width and Object's width is that when the List.width is set all of the child objects will be set to the same width.\n\n Returns:\n _type_: _description_\n \"\"\"\n return self.geometry.width\n\n @width.setter\n def width(self, value):\n for child in self.children:\n child.width = value\n self.geometry.width = value\n self.update_parent()\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.list_items","title":"list_items
property
writable
","text":"A Python list of strings of the objects in the list.
Returns:
Type Description list of strings: The list items
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.width","title":"width
property
writable
","text":"The width of the object. The difference between List's width and Object's width is that when the List.width is set all of the child objects will be set to the same width.
Returns:
Name Type Description _type_
description
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.__init__","title":"__init__(title='List', list_items=[], **kwargs)
","text":"The List object wraps the basic Object type but allows easier managing of a list object and its members. All of the arguments and keyword arguments for Object are available here as well.
Parameters:
Name Type Description Default title
str
The name in the heading of the list. Defaults to \"List\".
'List'
list_items
list of strings
A Python list of strings denoting the items. Defaults to empty.
[]
Source code in src/drawpyo/diagram/extended_objects.py
def __init__(self, title=\"List\", list_items=[], **kwargs):\n \"\"\"The List object wraps the basic Object type but allows easier managing of a list object and its members. All of the arguments and keyword arguments for Object are available here as well.\n\n Args:\n title (str, optional): The name in the heading of the list. Defaults to \"List\".\n list_items (list of strings, optional): A Python list of strings denoting the items. Defaults to empty.\n \"\"\"\n super().__init__(value=title, **kwargs)\n self.format_as_library_object(library=\"general\", obj_name=\"list\")\n self.autosizing = kwargs.get(\"autosizing\", True)\n self.width = kwargs.get(\"width\", 120)\n self.list_items = list_items\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.add_item","title":"add_item(item_text)
","text":"This function creates a new Draw.io text item and adds it to the end of the list.
Parameters:
Name Type Description Default item_text
string
The name of the item to add.
required Source code in src/drawpyo/diagram/extended_objects.py
def add_item(self, item_text):\n \"\"\"This function creates a new Draw.io text item and adds it to the end of the list.\n\n Args:\n item_text (string): The name of the item to add.\n \"\"\"\n new_item = object_from_library(\n library=\"general\", obj_name=\"list_item\", page=self.page\n )\n new_item.value = item_text\n new_item.parent = self\n new_item.width = self.width\n new_item.geometry.y = len(self.list_items) * new_item.height\n if self.autosizing:\n self.autosize()\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.autosize","title":"autosize()
","text":"This function resizes the parent List object to match the length of the list of items. It also restacks the list items to fill any gaps from deleted items.
Source code in src/drawpyo/diagram/extended_objects.py
def autosize(self):\n \"\"\"This function resizes the parent List object to match the length of the list of items. It also restacks the list items to fill any gaps from deleted items.\n \"\"\"\n y_pos = self.startSize\n for child in self.children:\n child.geometry.y = y_pos\n y_pos = y_pos + child.height\n self.height = self.startSize + sum(child.height for child in self.children)\n self.width = min(child.width for child in self.children)\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.remove_item","title":"remove_item(item_text)
","text":"This function removes any list items matching the text passed into the function.
Parameters:
Name Type Description Default item_text
string
The text of the list item to remove.
required Source code in src/drawpyo/diagram/extended_objects.py
def remove_item(self, item_text):\n \"\"\"This function removes any list items matching the text passed into the function.\n\n Args:\n item_text (string): The text of the list item to remove.\n \"\"\"\n for child in self.children:\n if child.value == item_text:\n self.remove_object(child)\n self.page.remove_object(child)\n del child\n if self.autosizing:\n self.autosize()\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 position_rel_to_parent (tuple, optional): The position of the object relative to the parent in pixels, in (X, Y). # TODO document\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 parent (Object, optional): The parent object (container, etc) of this object. Defaults to None. # TODO document\n children (array of Objects, optional): The subobjects to add to this object as a parent. Defaults to []. # TODO document\n autosize_to_children (bool, optional): Whether to autoexpand when child objects are added. Defaults to false. # TODO document\n autocontract (bool, optional): Whether to contract to fit the child objects. Defaults to false.\n autosize_margin (int, optional): What margin in pixels to leave around the child objects. Defaults to 20px. # TODO document\n template_object (Object, optional): Another object to copy the style_attributes from\n aspect # TODO ?\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 self.geometry = Geometry(parent_object=self)\n\n # Subobjecting\n # If there is a parent passed in, disable that parents\n # autoexpanding until position is set\n if \"parent\" in kwargs:\n parent = kwargs.get(\"parent\")\n old_parent_autosize = parent.autosize_to_children\n parent.autoexpand = False\n self.parent = parent\n else:\n self.parent = None\n self.children = kwargs.get(\"children\", [])\n self.autosize_to_children = kwargs.get(\"autosize_to_children\", False)\n self.autocontract = kwargs.get(\"autocontract\", False)\n self.autosize_margin = kwargs.get(\"autosize_margin\", 20)\n\n # Geometry\n self.position = position\n # Since the position is already set to either a passed in arg or the default this will\n # either override that default position or redundantly reset the position to the same value\n self.position_rel_to_parent = kwargs.get(\"position_rel_to_parent\", position)\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 # If a parent was passed in, reactivate the parents autoexpanding and update it\n if \"parent\" in kwargs:\n self.parent.autosize_to_children = old_parent_autosize\n self.update_parent()\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 def __delete__(self):\n self.page.remove_object(self)\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 self.update_parent()\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 self.update_parent()\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 if self.parent is not None:\n return (\n self.geometry.x + self.parent.position[0],\n self.geometry.y + self.parent.position[1],\n )\n return (self.geometry.x, self.geometry.y)\n\n @position.setter\n def position(self, value):\n if self.parent is not None:\n self.geometry.x = value[0] - self.parent.position[0]\n self.geometry.y = value[1] - self.parent.position[1]\n else:\n self.geometry.x = value[0]\n self.geometry.y = value[1]\n self.update_parent()\n\n # Position Rel to Parent\n @property\n def position_rel_to_parent(self):\n \"\"\"The position of the object relative to its parent (container). If there's no parent this will be relative to 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_rel_to_parent.setter\n def position_rel_to_parent(self, value):\n self.geometry.x = value[0]\n self.geometry.y = value[1]\n self.update_parent()\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 # Subobjects\n ###########################################################\n # TODO add to documentation\n\n @property\n def xml_parent_id(self):\n if self.parent is not None:\n return self.parent.id\n return 1\n\n @property\n def parent(self):\n \"\"\"The parent object that owns this object. This is usually a container of some kind but can be any other object.\n\n Returns:\n Object: the parent object.\n \"\"\"\n return self._parent\n\n @parent.setter\n def parent(self, value):\n if isinstance(value, Object):\n # value.add_object(self)\n value.children.append(self)\n self.update_parent()\n self._parent = value\n\n def add_object(self, child_object):\n \"\"\"Adds a child object to this object, sets the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to add as a child\n \"\"\"\n child_object._parent = self # Bypass the setter to prevent a loop\n self.children.append(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\n\n def remove_object(self, child_object):\n \"\"\"Removes a child object from this object, clears the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to remove as a child\n \"\"\"\n child_object._parent = None # Bypass the setter to prevent a loop\n self.children.remove(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\n\n def update_parent(self):\n \"\"\"If a parent object is set and the parent is set to autoexpand, then autoexpand it.\"\"\"\n # This function needs to be callable prior to the parent being set during init,\n # hence the hasattr() check.\n if (\n hasattr(self, \"_parent\")\n and self.parent is not None\n and self.parent.autosize_to_children\n ):\n # if the parent is autoexpanding, call the autoexpand function\n self.parent.resize_to_children()\n\n def resize_to_children(self):\n \"\"\"If the object contains children (is a container, parent, etc) then expand the size and position to fit all of the children.\n\n By default this function will never shrink the size of the object, only expand it. The contract input can be set for that behavior.\n\n Args:\n contract (bool, optional): Contract the parent object to hug the children. Defaults to False.\n \"\"\"\n # Get current extents\n if len(self.children) == 0:\n return\n if self.autocontract:\n topmost = 65536\n bottommost = -65536\n leftmost = 65536\n rightmost = -65536\n else:\n topmost = self.position[1]\n bottommost = self.position[1] + self.height\n leftmost = self.position[0]\n rightmost = self.position[0] + self.width\n\n # Check all child objects for extents\n for child_object in self.children:\n topmost = min(topmost, child_object.position[1] - self.autosize_margin)\n bottommost = max(\n bottommost,\n child_object.position[1] + child_object.height + self.autosize_margin,\n )\n leftmost = min(leftmost, child_object.position[0] - self.autosize_margin)\n rightmost = max(\n rightmost,\n child_object.position[0] + child_object.width + self.autosize_margin,\n )\n\n # Set self extents to furthest positions\n self.move_wo_children((leftmost, topmost))\n self.width = rightmost - leftmost\n self.height = bottommost - topmost\n\n def move_wo_children(self, position):\n \"\"\"Move the parent object relative to the page without moving the children relative to the page.\n\n Args:\n position (Tuple of Ints): The target position for the parent object.\n \"\"\"\n # Disable autoexpand to avoid recursion from child_objects\n # attempting to update their autoexpanding parent upon a move\n old_autoexpand = self.autosize_to_children\n self.autosize_to_children = False\n\n # Move children to counter upcoming parent move\n pos_delta = [\n old_pos - new_pos for old_pos, new_pos in zip(self.position, position)\n ]\n for child_object in self.children:\n child_object.position = [\n curr_pos + container_move\n for curr_pos, container_move in zip(child_object.position, pos_delta)\n ]\n\n # Set new position and re-enable autoexpand\n self.position = position\n self.autosize_to_children = old_autoexpand\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.parent","title":"parent
property
writable
","text":"The parent object that owns this object. This is usually a container of some kind but can be any other object.
Returns:
Name Type Description Object
the parent object.
"},{"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.position_rel_to_parent","title":"position_rel_to_parent
property
writable
","text":"The position of the object relative to its parent (container). If there's no parent this will be relative to 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 position_rel_to_parent
tuple
The position of the object relative to the parent in pixels, in (X, Y). # TODO document
width
int
The width of the object in pixels. Defaults to 120.
height
int
The height of the object in pixels. Defaults to 80.
parent
Object
The parent object (container, etc) of this object. Defaults to None. # TODO document
children
array of Objects
The subobjects to add to this object as a parent. Defaults to []. # TODO document
autosize_to_children
bool
Whether to autoexpand when child objects are added. Defaults to false. # TODO document
autocontract
bool
Whether to contract to fit the child objects. Defaults to false.
autosize_margin
int
What margin in pixels to leave around the child objects. Defaults to 20px. # TODO document
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 position_rel_to_parent (tuple, optional): The position of the object relative to the parent in pixels, in (X, Y). # TODO document\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 parent (Object, optional): The parent object (container, etc) of this object. Defaults to None. # TODO document\n children (array of Objects, optional): The subobjects to add to this object as a parent. Defaults to []. # TODO document\n autosize_to_children (bool, optional): Whether to autoexpand when child objects are added. Defaults to false. # TODO document\n autocontract (bool, optional): Whether to contract to fit the child objects. Defaults to false.\n autosize_margin (int, optional): What margin in pixels to leave around the child objects. Defaults to 20px. # TODO document\n template_object (Object, optional): Another object to copy the style_attributes from\n aspect # TODO ?\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 self.geometry = Geometry(parent_object=self)\n\n # Subobjecting\n # If there is a parent passed in, disable that parents\n # autoexpanding until position is set\n if \"parent\" in kwargs:\n parent = kwargs.get(\"parent\")\n old_parent_autosize = parent.autosize_to_children\n parent.autoexpand = False\n self.parent = parent\n else:\n self.parent = None\n self.children = kwargs.get(\"children\", [])\n self.autosize_to_children = kwargs.get(\"autosize_to_children\", False)\n self.autocontract = kwargs.get(\"autocontract\", False)\n self.autosize_margin = kwargs.get(\"autosize_margin\", 20)\n\n # Geometry\n self.position = position\n # Since the position is already set to either a passed in arg or the default this will\n # either override that default position or redundantly reset the position to the same value\n self.position_rel_to_parent = kwargs.get(\"position_rel_to_parent\", position)\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 # If a parent was passed in, reactivate the parents autoexpanding and update it\n if \"parent\" in kwargs:\n self.parent.autosize_to_children = old_parent_autosize\n self.update_parent()\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_object","title":"add_object(child_object)
","text":"Adds a child object to this object, sets the child objects parent, and autoexpands this object if set to.
Parameters:
Name Type Description Default child_object
Object
object to add as a child
required Source code in src/drawpyo/diagram/objects.py
def add_object(self, child_object):\n \"\"\"Adds a child object to this object, sets the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to add as a child\n \"\"\"\n child_object._parent = self # Bypass the setter to prevent a loop\n self.children.append(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\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.move_wo_children","title":"move_wo_children(position)
","text":"Move the parent object relative to the page without moving the children relative to the page.
Parameters:
Name Type Description Default position
Tuple of Ints
The target position for the parent object.
required Source code in src/drawpyo/diagram/objects.py
def move_wo_children(self, position):\n \"\"\"Move the parent object relative to the page without moving the children relative to the page.\n\n Args:\n position (Tuple of Ints): The target position for the parent object.\n \"\"\"\n # Disable autoexpand to avoid recursion from child_objects\n # attempting to update their autoexpanding parent upon a move\n old_autoexpand = self.autosize_to_children\n self.autosize_to_children = False\n\n # Move children to counter upcoming parent move\n pos_delta = [\n old_pos - new_pos for old_pos, new_pos in zip(self.position, position)\n ]\n for child_object in self.children:\n child_object.position = [\n curr_pos + container_move\n for curr_pos, container_move in zip(child_object.position, pos_delta)\n ]\n\n # Set new position and re-enable autoexpand\n self.position = position\n self.autosize_to_children = old_autoexpand\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_object","title":"remove_object(child_object)
","text":"Removes a child object from this object, clears the child objects parent, and autoexpands this object if set to.
Parameters:
Name Type Description Default child_object
Object
object to remove as a child
required Source code in src/drawpyo/diagram/objects.py
def remove_object(self, child_object):\n \"\"\"Removes a child object from this object, clears the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to remove as a child\n \"\"\"\n child_object._parent = None # Bypass the setter to prevent a loop\n self.children.remove(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\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/#src.drawpyo.diagram.objects.Object.resize_to_children","title":"resize_to_children()
","text":"If the object contains children (is a container, parent, etc) then expand the size and position to fit all of the children.
By default this function will never shrink the size of the object, only expand it. The contract input can be set for that behavior.
Parameters:
Name Type Description Default contract
bool
Contract the parent object to hug the children. Defaults to False.
required Source code in src/drawpyo/diagram/objects.py
def resize_to_children(self):\n \"\"\"If the object contains children (is a container, parent, etc) then expand the size and position to fit all of the children.\n\n By default this function will never shrink the size of the object, only expand it. The contract input can be set for that behavior.\n\n Args:\n contract (bool, optional): Contract the parent object to hug the children. Defaults to False.\n \"\"\"\n # Get current extents\n if len(self.children) == 0:\n return\n if self.autocontract:\n topmost = 65536\n bottommost = -65536\n leftmost = 65536\n rightmost = -65536\n else:\n topmost = self.position[1]\n bottommost = self.position[1] + self.height\n leftmost = self.position[0]\n rightmost = self.position[0] + self.width\n\n # Check all child objects for extents\n for child_object in self.children:\n topmost = min(topmost, child_object.position[1] - self.autosize_margin)\n bottommost = max(\n bottommost,\n child_object.position[1] + child_object.height + self.autosize_margin,\n )\n leftmost = min(leftmost, child_object.position[0] - self.autosize_margin)\n rightmost = max(\n rightmost,\n child_object.position[0] + child_object.width + self.autosize_margin,\n )\n\n # Set self extents to furthest positions\n self.move_wo_children((leftmost, topmost))\n self.width = rightmost - leftmost\n self.height = bottommost - topmost\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.update_parent","title":"update_parent()
","text":"If a parent object is set and the parent is set to autoexpand, then autoexpand it.
Source code in src/drawpyo/diagram/objects.py
def update_parent(self):\n \"\"\"If a parent object is set and the parent is set to autoexpand, then autoexpand it.\"\"\"\n # This function needs to be callable prior to the parent being set during init,\n # hence the hasattr() check.\n if (\n hasattr(self, \"_parent\")\n and self.parent is not None\n and self.parent.autosize_to_children\n ):\n # if the parent is autoexpanding, call the autoexpand function\n self.parent.resize_to_children()\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/extended_objects/","title":"Extended Objects","text":"While any of the objects in Draw.io can be created by setting the correct combination of attributes it's not always convenient, particularly when an 'object' is actually a small group of objects. To offer a little more convenience drawpyo has extended objects. These inherit from the Object class but extend it with added functionality, though not quite to the level of the custom diagram types.
There's only one extended object implemented now but there could be more in the future, either mirroring Draw.io functionality or new object types.
"},{"location":"usage/extended_objects/#list","title":"List","text":"A list object is available in the General library in Draw.io. It's simple a small container object with a horizontal label filled with text objects as the list items. The Draw.io app conveniently keeps the list items positioned and in order as you add or remove, also scaling the size of the list container.
"},{"location":"usage/extended_objects/#creating-a-list","title":"Creating a List","text":"To create a list in drawpyo, use the diagram.List
object.
new_list = drawpyo.diagram.List(title=\"List\", page=page, width=200)\n
Like any other Object, the position and geometry can be set during creation as well as various styling attributes.
"},{"location":"usage/extended_objects/#adding-items","title":"Adding Items","text":"There are a few methods of adding items. The easiest would be using the .add_item()
method.
new_list.add_item(\"item 1\")\nnew_list.add_item(\"item B\")\nnew_list.add_item(\"item iii\")\n
This will create a text object, set the List as its parent, position it correctly, and then resize the List object.
You can also access the property list_items
. It will return a list of strings denoting all the items in the list. But it also has a setter property, so setting it to a list of strings will remove existing items and then go through the creation and resizing process.
"},{"location":"usage/extended_objects/#deleting-items","title":"Deleting Items","text":"The easiest way to delete an item is to call the .remove_item()
method. Pass in the text of the item to remove and it will be strucken from the list then the list resized.
new_list.remove_item(\"item B\")\n
"},{"location":"usage/extended_objects/#resizing-the-list","title":"Resizing the List","text":"The list will be automatically resized to match the contents when the above methods are called. But the resize can also be called manually with the .autosize()
method.
"},{"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:
- parallelogram
- shape
- process
- hexagon
- document
- cylinder3
- internalStorage
- cube
- step
- tape
- trapezoid
- note
- card
- callout
- dataStorage
and many more.
Confusingly there is another attribute called baseStyle
that is sometimes used in combination with shape
and sometimes without.
BaseStyles include:
- text
- ellipse
- rhombus
- triangle
- swimlane
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.
- rounded
- fillColor
- strokeColor
- opacity
- whiteSpace
- glass
- shadow
- comic
- line_pattern
"},{"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:
- darkOpacity
- darkOpacity2
- backgroundOutline
- perimeter
"},{"location":"usage/parent_child_objects/","title":"Parent and Child Objects","text":"In Draw.io, any object can have a parent. This is used within the app for containers and lists but actually any object can have subobjects. Within the XML this is achieved just be setting the parent
attribute from 1
(the page) to any other object's ID. This changes the X and Y coordinates of the child object to be relative to the parent's X and Y coordinates.
Drawpyo has convenient support for subobjects with a handful of attributes and parameters.
"},{"location":"usage/parent_child_objects/#linking-parent-and-child-objects","title":"Linking Parent and Child Objects","text":"A parent object can be assigned to any subobject either during instantiation or after the fact by using the parent
property. Every object has this property as well as a children
property that's a list of other objects.
Creating the parent object:
parent_container = drawpyo.diagram.object_from_library(\n library=\"general\", obj_name=\"labeled_horizontal_container\", page=page\n)\n
Adding child objects:
block_1 = drawpyo.diagram.object_from_library(\n library=\"general\", obj_name=\"rectangle\", page=page\n)\nblock_1.value = \"Block 1\"\nblock_1.parent = parent_container\n\nblock_2 = drawpyo.diagram.Object(\n position_rel_to_parent=(300, 300), parent=parent_container, value=\"Block 2\", page=page\n)\n
There are also methods for adding and removing objects:
parent_container.add_object(block_1)\n parent_container.remove_object(block_2)\n
This will create or remove the link on both ends (set the parent attribute of the child object as well as add the child to the parents. These functions are called by the setters of the parent
property, this is just an alternate syntax.
"},{"location":"usage/parent_child_objects/#positioning","title":"Positioning","text":"Within the Draw.io application, child objects X and Y coordinates are relative to the parent object. This isn't always useful so drawpyo offers two different position attributes. Both are tuples of ints: (X, Y). They both modify or return the underlying Geometry object so they can be used interchangeably and are not duplicate variables.
The normal position
attribute continues to be relative to the page regardless of whether there's a parent object set.
There is also a position_rel_to_parent
attribute that will return the position with respect to the position of the parent.
"},{"location":"usage/parent_child_objects/#autosizing","title":"Autosizing","text":"It's useful to have a parent object expand or contract to fit its objects. This behavior is disabled by default but can be enabled by setting the autosize_to_children
boolean parameter to True. There is also a corresponding parameter called autosize_margin
that sets the margin to maintain around the child objects in pixels. When this is set anytime that a child object is added, resized, or repositioned the parent will expand to fit the contents plus the margins. By default the parent will never contract unless autocontract
is set to True as well.
Note that the margin is inclusive of a container's title block.
The autofit behavior can also be called manually using the resize_to_children()
function on an object. This will respect the autofit_margin and autocontract behavior.
"},{"location":"usage/parent_child_objects/#combining-relative-positioning-and-autosizing","title":"Combining Relative Positioning and Autosizing","text":"Combining the autosizing behavior with relative positioning can cause unexpected behavior. Since the parent object will resize every time a child object is added or moved within it the successive objects added will now be relative to a new updated parent object position. This will make your code order-dependent.
To avoid this, either disable autosize_to_children
or use absolute positioning for child objects.
"},{"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 backwards 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 when I had a need to generate hierarchical 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 def add_object(self, obj):\n self.page.add_object(obj)\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 strokeWidth (int): The width of the border of the the edge within range (1-999)\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.strokeWidth = kwargs.get(\"strokeWidth\", 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 \"strokeWidth\",\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 ## strokeWidth\n @property\n def strokeWidth(self):\n return self._strokeWidth\n\n @strokeWidth.setter\n def strokeWidth(self, value):\n self._strokeWidth = width_input_check(value)\n\n @strokeWidth.deleter\n def strokeWidth(self):\n self._strokeWidth = 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 strokeWidth
int
The width of the border of the the edge within range (1-999)
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 strokeWidth (int): The width of the border of the the edge within range (1-999)\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.strokeWidth = kwargs.get(\"strokeWidth\", 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/extended_objects/","title":"Extended Objects","text":""},{"location":"api/extended_objects/#list","title":"List","text":""},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List","title":"src.drawpyo.diagram.extended_objects.List
","text":" Bases: Object
Source code in src/drawpyo/diagram/extended_objects.py
class List(Object):\n def __init__(self, title=\"List\", list_items=[], **kwargs):\n \"\"\"The List object wraps the basic Object type but allows easier managing of a list object and its members. All of the arguments and keyword arguments for Object are available here as well.\n\n Args:\n title (str, optional): The name in the heading of the list. Defaults to \"List\".\n list_items (list of strings, optional): A Python list of strings denoting the items. Defaults to empty.\n \"\"\"\n super().__init__(value=title, **kwargs)\n self.format_as_library_object(library=\"general\", obj_name=\"list\")\n self.autosizing = kwargs.get(\"autosizing\", True)\n self.width = kwargs.get(\"width\", 120)\n self.list_items = list_items\n\n @property\n def list_items(self):\n \"\"\"A Python list of strings of the objects in the list.\n\n Returns:\n list of strings: The list items\n \"\"\"\n return [child.value for child in self.children]\n\n @list_items.setter\n def list_items(self, value):\n if not isinstance(value, list):\n raise TypeError(\"list_items must be a list!\")\n self.children = []\n for item in value:\n self.add_item(item)\n\n def add_item(self, item_text):\n \"\"\"This function creates a new Draw.io text item and adds it to the end of the list.\n\n Args:\n item_text (string): The name of the item to add.\n \"\"\"\n new_item = object_from_library(\n library=\"general\", obj_name=\"list_item\", page=self.page\n )\n new_item.value = item_text\n new_item.parent = self\n new_item.width = self.width\n new_item.geometry.y = len(self.list_items) * new_item.height\n if self.autosizing:\n self.autosize()\n\n def remove_item(self, item_text):\n \"\"\"This function removes any list items matching the text passed into the function.\n\n Args:\n item_text (string): The text of the list item to remove.\n \"\"\"\n for child in self.children:\n if child.value == item_text:\n self.remove_object(child)\n self.page.remove_object(child)\n del child\n if self.autosizing:\n self.autosize()\n\n def autosize(self):\n \"\"\"This function resizes the parent List object to match the length of the list of items. It also restacks the list items to fill any gaps from deleted items.\"\"\"\n y_pos = self.startSize\n for child in self.children:\n child.geometry.y = y_pos\n y_pos = y_pos + child.height\n self.height = self.startSize + sum(child.height for child in self.children)\n self.width = min(child.width for child in self.children)\n\n @property\n def width(self):\n \"\"\"The width of the object. The difference between List's width and Object's width is that when the List.width is set all of the child objects will be set to the same width.\n\n Returns:\n _type_: _description_\n \"\"\"\n return self.geometry.width\n\n @width.setter\n def width(self, value):\n for child in self.children:\n child.width = value\n self.geometry.width = value\n self.update_parent()\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.list_items","title":"list_items
property
writable
","text":"A Python list of strings of the objects in the list.
Returns:
Type Description list of strings: The list items
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.width","title":"width
property
writable
","text":"The width of the object. The difference between List's width and Object's width is that when the List.width is set all of the child objects will be set to the same width.
Returns:
Name Type Description _type_
description
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.__init__","title":"__init__(title='List', list_items=[], **kwargs)
","text":"The List object wraps the basic Object type but allows easier managing of a list object and its members. All of the arguments and keyword arguments for Object are available here as well.
Parameters:
Name Type Description Default title
str
The name in the heading of the list. Defaults to \"List\".
'List'
list_items
list of strings
A Python list of strings denoting the items. Defaults to empty.
[]
Source code in src/drawpyo/diagram/extended_objects.py
def __init__(self, title=\"List\", list_items=[], **kwargs):\n \"\"\"The List object wraps the basic Object type but allows easier managing of a list object and its members. All of the arguments and keyword arguments for Object are available here as well.\n\n Args:\n title (str, optional): The name in the heading of the list. Defaults to \"List\".\n list_items (list of strings, optional): A Python list of strings denoting the items. Defaults to empty.\n \"\"\"\n super().__init__(value=title, **kwargs)\n self.format_as_library_object(library=\"general\", obj_name=\"list\")\n self.autosizing = kwargs.get(\"autosizing\", True)\n self.width = kwargs.get(\"width\", 120)\n self.list_items = list_items\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.add_item","title":"add_item(item_text)
","text":"This function creates a new Draw.io text item and adds it to the end of the list.
Parameters:
Name Type Description Default item_text
string
The name of the item to add.
required Source code in src/drawpyo/diagram/extended_objects.py
def add_item(self, item_text):\n \"\"\"This function creates a new Draw.io text item and adds it to the end of the list.\n\n Args:\n item_text (string): The name of the item to add.\n \"\"\"\n new_item = object_from_library(\n library=\"general\", obj_name=\"list_item\", page=self.page\n )\n new_item.value = item_text\n new_item.parent = self\n new_item.width = self.width\n new_item.geometry.y = len(self.list_items) * new_item.height\n if self.autosizing:\n self.autosize()\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.autosize","title":"autosize()
","text":"This function resizes the parent List object to match the length of the list of items. It also restacks the list items to fill any gaps from deleted items.
Source code in src/drawpyo/diagram/extended_objects.py
def autosize(self):\n \"\"\"This function resizes the parent List object to match the length of the list of items. It also restacks the list items to fill any gaps from deleted items.\"\"\"\n y_pos = self.startSize\n for child in self.children:\n child.geometry.y = y_pos\n y_pos = y_pos + child.height\n self.height = self.startSize + sum(child.height for child in self.children)\n self.width = min(child.width for child in self.children)\n
"},{"location":"api/extended_objects/#src.drawpyo.diagram.extended_objects.List.remove_item","title":"remove_item(item_text)
","text":"This function removes any list items matching the text passed into the function.
Parameters:
Name Type Description Default item_text
string
The text of the list item to remove.
required Source code in src/drawpyo/diagram/extended_objects.py
def remove_item(self, item_text):\n \"\"\"This function removes any list items matching the text passed into the function.\n\n Args:\n item_text (string): The text of the list item to remove.\n \"\"\"\n for child in self.children:\n if child.value == item_text:\n self.remove_object(child)\n self.page.remove_object(child)\n del child\n if self.autosizing:\n self.autosize()\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 with open(\n path.join(self.file_path, self.file_name), write_mode, encoding=\"utf-8\"\n ) as f:\n f.write(self.xml)\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 with open(\n path.join(self.file_path, self.file_name), write_mode, encoding=\"utf-8\"\n ) as f:\n f.write(self.xml)\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 position_rel_to_parent (tuple, optional): The position of the object relative to the parent in pixels, in (X, Y). # TODO document\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 parent (Object, optional): The parent object (container, etc) of this object. Defaults to None. # TODO document\n children (array of Objects, optional): The subobjects to add to this object as a parent. Defaults to []. # TODO document\n autosize_to_children (bool, optional): Whether to autoexpand when child objects are added. Defaults to false. # TODO document\n autocontract (bool, optional): Whether to contract to fit the child objects. Defaults to false.\n autosize_margin (int, optional): What margin in pixels to leave around the child objects. Defaults to 20px. # TODO document\n template_object (Object, optional): Another object to copy the style_attributes from\n aspect # TODO ?\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 self.geometry = Geometry(parent_object=self)\n\n # Subobjecting\n # If there is a parent passed in, disable that parents\n # autoexpanding until position is set\n if \"parent\" in kwargs:\n parent = kwargs.get(\"parent\")\n old_parent_autosize = parent.autosize_to_children\n parent.autoexpand = False\n self.parent = parent\n else:\n self.parent = None\n self.children = kwargs.get(\"children\", [])\n self.autosize_to_children = kwargs.get(\"autosize_to_children\", False)\n self.autocontract = kwargs.get(\"autocontract\", False)\n self.autosize_margin = kwargs.get(\"autosize_margin\", 20)\n\n # Geometry\n self.position = position\n # Since the position is already set to either a passed in arg or the default this will\n # either override that default position or redundantly reset the position to the same value\n self.position_rel_to_parent = kwargs.get(\"position_rel_to_parent\", position)\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 # If a parent was passed in, reactivate the parents autoexpanding and update it\n if \"parent\" in kwargs:\n self.parent.autosize_to_children = old_parent_autosize\n self.update_parent()\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 def __delete__(self):\n self.page.remove_object(self)\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 self.update_parent()\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 self.update_parent()\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 if self.parent is not None:\n return (\n self.geometry.x + self.parent.position[0],\n self.geometry.y + self.parent.position[1],\n )\n return (self.geometry.x, self.geometry.y)\n\n @position.setter\n def position(self, value):\n if self.parent is not None:\n self.geometry.x = value[0] - self.parent.position[0]\n self.geometry.y = value[1] - self.parent.position[1]\n else:\n self.geometry.x = value[0]\n self.geometry.y = value[1]\n self.update_parent()\n\n # Position Rel to Parent\n @property\n def position_rel_to_parent(self):\n \"\"\"The position of the object relative to its parent (container). If there's no parent this will be relative to 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_rel_to_parent.setter\n def position_rel_to_parent(self, value):\n self.geometry.x = value[0]\n self.geometry.y = value[1]\n self.update_parent()\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 # Subobjects\n ###########################################################\n # TODO add to documentation\n\n @property\n def xml_parent_id(self):\n if self.parent is not None:\n return self.parent.id\n return 1\n\n @property\n def parent(self):\n \"\"\"The parent object that owns this object. This is usually a container of some kind but can be any other object.\n\n Returns:\n Object: the parent object.\n \"\"\"\n return self._parent\n\n @parent.setter\n def parent(self, value):\n if isinstance(value, Object):\n # value.add_object(self)\n value.children.append(self)\n self.update_parent()\n self._parent = value\n\n def add_object(self, child_object):\n \"\"\"Adds a child object to this object, sets the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to add as a child\n \"\"\"\n child_object._parent = self # Bypass the setter to prevent a loop\n self.children.append(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\n\n def remove_object(self, child_object):\n \"\"\"Removes a child object from this object, clears the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to remove as a child\n \"\"\"\n child_object._parent = None # Bypass the setter to prevent a loop\n self.children.remove(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\n\n def update_parent(self):\n \"\"\"If a parent object is set and the parent is set to autoexpand, then autoexpand it.\"\"\"\n # This function needs to be callable prior to the parent being set during init,\n # hence the hasattr() check.\n if (\n hasattr(self, \"_parent\")\n and self.parent is not None\n and self.parent.autosize_to_children\n ):\n # if the parent is autoexpanding, call the autoexpand function\n self.parent.resize_to_children()\n\n def resize_to_children(self):\n \"\"\"If the object contains children (is a container, parent, etc) then expand the size and position to fit all of the children.\n\n By default this function will never shrink the size of the object, only expand it. The contract input can be set for that behavior.\n\n Args:\n contract (bool, optional): Contract the parent object to hug the children. Defaults to False.\n \"\"\"\n # Get current extents\n if len(self.children) == 0:\n return\n if self.autocontract:\n topmost = 65536\n bottommost = -65536\n leftmost = 65536\n rightmost = -65536\n else:\n topmost = self.position[1]\n bottommost = self.position[1] + self.height\n leftmost = self.position[0]\n rightmost = self.position[0] + self.width\n\n # Check all child objects for extents\n for child_object in self.children:\n topmost = min(topmost, child_object.position[1] - self.autosize_margin)\n bottommost = max(\n bottommost,\n child_object.position[1] + child_object.height + self.autosize_margin,\n )\n leftmost = min(leftmost, child_object.position[0] - self.autosize_margin)\n rightmost = max(\n rightmost,\n child_object.position[0] + child_object.width + self.autosize_margin,\n )\n\n # Set self extents to furthest positions\n self.move_wo_children((leftmost, topmost))\n self.width = rightmost - leftmost\n self.height = bottommost - topmost\n\n def move_wo_children(self, position):\n \"\"\"Move the parent object relative to the page without moving the children relative to the page.\n\n Args:\n position (Tuple of Ints): The target position for the parent object.\n \"\"\"\n # Disable autoexpand to avoid recursion from child_objects\n # attempting to update their autoexpanding parent upon a move\n old_autoexpand = self.autosize_to_children\n self.autosize_to_children = False\n\n # Move children to counter upcoming parent move\n pos_delta = [\n old_pos - new_pos for old_pos, new_pos in zip(self.position, position)\n ]\n for child_object in self.children:\n child_object.position = [\n curr_pos + container_move\n for curr_pos, container_move in zip(child_object.position, pos_delta)\n ]\n\n # Set new position and re-enable autoexpand\n self.position = position\n self.autosize_to_children = old_autoexpand\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.parent","title":"parent
property
writable
","text":"The parent object that owns this object. This is usually a container of some kind but can be any other object.
Returns:
Name Type Description Object
the parent object.
"},{"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.position_rel_to_parent","title":"position_rel_to_parent
property
writable
","text":"The position of the object relative to its parent (container). If there's no parent this will be relative to 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 position_rel_to_parent
tuple
The position of the object relative to the parent in pixels, in (X, Y). # TODO document
width
int
The width of the object in pixels. Defaults to 120.
height
int
The height of the object in pixels. Defaults to 80.
parent
Object
The parent object (container, etc) of this object. Defaults to None. # TODO document
children
array of Objects
The subobjects to add to this object as a parent. Defaults to []. # TODO document
autosize_to_children
bool
Whether to autoexpand when child objects are added. Defaults to false. # TODO document
autocontract
bool
Whether to contract to fit the child objects. Defaults to false.
autosize_margin
int
What margin in pixels to leave around the child objects. Defaults to 20px. # TODO document
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 position_rel_to_parent (tuple, optional): The position of the object relative to the parent in pixels, in (X, Y). # TODO document\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 parent (Object, optional): The parent object (container, etc) of this object. Defaults to None. # TODO document\n children (array of Objects, optional): The subobjects to add to this object as a parent. Defaults to []. # TODO document\n autosize_to_children (bool, optional): Whether to autoexpand when child objects are added. Defaults to false. # TODO document\n autocontract (bool, optional): Whether to contract to fit the child objects. Defaults to false.\n autosize_margin (int, optional): What margin in pixels to leave around the child objects. Defaults to 20px. # TODO document\n template_object (Object, optional): Another object to copy the style_attributes from\n aspect # TODO ?\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 self.geometry = Geometry(parent_object=self)\n\n # Subobjecting\n # If there is a parent passed in, disable that parents\n # autoexpanding until position is set\n if \"parent\" in kwargs:\n parent = kwargs.get(\"parent\")\n old_parent_autosize = parent.autosize_to_children\n parent.autoexpand = False\n self.parent = parent\n else:\n self.parent = None\n self.children = kwargs.get(\"children\", [])\n self.autosize_to_children = kwargs.get(\"autosize_to_children\", False)\n self.autocontract = kwargs.get(\"autocontract\", False)\n self.autosize_margin = kwargs.get(\"autosize_margin\", 20)\n\n # Geometry\n self.position = position\n # Since the position is already set to either a passed in arg or the default this will\n # either override that default position or redundantly reset the position to the same value\n self.position_rel_to_parent = kwargs.get(\"position_rel_to_parent\", position)\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 # If a parent was passed in, reactivate the parents autoexpanding and update it\n if \"parent\" in kwargs:\n self.parent.autosize_to_children = old_parent_autosize\n self.update_parent()\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_object","title":"add_object(child_object)
","text":"Adds a child object to this object, sets the child objects parent, and autoexpands this object if set to.
Parameters:
Name Type Description Default child_object
Object
object to add as a child
required Source code in src/drawpyo/diagram/objects.py
def add_object(self, child_object):\n \"\"\"Adds a child object to this object, sets the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to add as a child\n \"\"\"\n child_object._parent = self # Bypass the setter to prevent a loop\n self.children.append(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\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.move_wo_children","title":"move_wo_children(position)
","text":"Move the parent object relative to the page without moving the children relative to the page.
Parameters:
Name Type Description Default position
Tuple of Ints
The target position for the parent object.
required Source code in src/drawpyo/diagram/objects.py
def move_wo_children(self, position):\n \"\"\"Move the parent object relative to the page without moving the children relative to the page.\n\n Args:\n position (Tuple of Ints): The target position for the parent object.\n \"\"\"\n # Disable autoexpand to avoid recursion from child_objects\n # attempting to update their autoexpanding parent upon a move\n old_autoexpand = self.autosize_to_children\n self.autosize_to_children = False\n\n # Move children to counter upcoming parent move\n pos_delta = [\n old_pos - new_pos for old_pos, new_pos in zip(self.position, position)\n ]\n for child_object in self.children:\n child_object.position = [\n curr_pos + container_move\n for curr_pos, container_move in zip(child_object.position, pos_delta)\n ]\n\n # Set new position and re-enable autoexpand\n self.position = position\n self.autosize_to_children = old_autoexpand\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_object","title":"remove_object(child_object)
","text":"Removes a child object from this object, clears the child objects parent, and autoexpands this object if set to.
Parameters:
Name Type Description Default child_object
Object
object to remove as a child
required Source code in src/drawpyo/diagram/objects.py
def remove_object(self, child_object):\n \"\"\"Removes a child object from this object, clears the child objects parent, and autoexpands this object if set to.\n\n Args:\n child_object (Object): object to remove as a child\n \"\"\"\n child_object._parent = None # Bypass the setter to prevent a loop\n self.children.remove(child_object)\n if self.autosize_to_children:\n self.resize_to_children()\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/#src.drawpyo.diagram.objects.Object.resize_to_children","title":"resize_to_children()
","text":"If the object contains children (is a container, parent, etc) then expand the size and position to fit all of the children.
By default this function will never shrink the size of the object, only expand it. The contract input can be set for that behavior.
Parameters:
Name Type Description Default contract
bool
Contract the parent object to hug the children. Defaults to False.
required Source code in src/drawpyo/diagram/objects.py
def resize_to_children(self):\n \"\"\"If the object contains children (is a container, parent, etc) then expand the size and position to fit all of the children.\n\n By default this function will never shrink the size of the object, only expand it. The contract input can be set for that behavior.\n\n Args:\n contract (bool, optional): Contract the parent object to hug the children. Defaults to False.\n \"\"\"\n # Get current extents\n if len(self.children) == 0:\n return\n if self.autocontract:\n topmost = 65536\n bottommost = -65536\n leftmost = 65536\n rightmost = -65536\n else:\n topmost = self.position[1]\n bottommost = self.position[1] + self.height\n leftmost = self.position[0]\n rightmost = self.position[0] + self.width\n\n # Check all child objects for extents\n for child_object in self.children:\n topmost = min(topmost, child_object.position[1] - self.autosize_margin)\n bottommost = max(\n bottommost,\n child_object.position[1] + child_object.height + self.autosize_margin,\n )\n leftmost = min(leftmost, child_object.position[0] - self.autosize_margin)\n rightmost = max(\n rightmost,\n child_object.position[0] + child_object.width + self.autosize_margin,\n )\n\n # Set self extents to furthest positions\n self.move_wo_children((leftmost, topmost))\n self.width = rightmost - leftmost\n self.height = bottommost - topmost\n
"},{"location":"api/objects/#src.drawpyo.diagram.objects.Object.update_parent","title":"update_parent()
","text":"If a parent object is set and the parent is set to autoexpand, then autoexpand it.
Source code in src/drawpyo/diagram/objects.py
def update_parent(self):\n \"\"\"If a parent object is set and the parent is set to autoexpand, then autoexpand it.\"\"\"\n # This function needs to be callable prior to the parent being set during init,\n # hence the hasattr() check.\n if (\n hasattr(self, \"_parent\")\n and self.parent is not None\n and self.parent.autosize_to_children\n ):\n # if the parent is autoexpanding, call the autoexpand function\n self.parent.resize_to_children()\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 \"fontStyle\",\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\n @property\n def fontStyle(self):\n if self.font_style != 0:\n return self.font_style\n return None\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 \"fontStyle\",\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 tree_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.tree_children = kwargs.get(\"tree_children\", [])\n self.tree_parent = kwargs.get(\"tree_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 tree_parent(self):\n \"\"\"The parent NodeObject in the tree\n\n Returns:\n NodeObject\n \"\"\"\n return self._tree_parent\n\n @tree_parent.setter\n def tree_parent(self, value):\n if value is not None:\n value.tree_children.append(self)\n self._tree_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.tree_children.append(obj)\n obj._tree_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.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.tree_parent","title":"tree_parent
property
writable
","text":"The parent NodeObject in the tree
Returns:
Type Description NodeObject
"},{"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 tree_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 tree_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.tree_children = kwargs.get(\"tree_children\", [])\n self.tree_parent = kwargs.get(\"tree_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.tree_children.append(obj)\n obj._tree_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 \"tree_parent\" in kwargs:\n obj.tree_parent = kwargs.get(\"tree_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.tree_parent is None]\n\n def auto_layout(self):\n def layout_child(tree_parent):\n grp = TreeGroup(tree=self)\n grp.parent_object = tree_parent\n if len(tree_parent.tree_children) > 0:\n # has children, go through each child and check its children\n for child in tree_parent.tree_children:\n self.connect(tree_parent, child)\n if len(child.tree_children) > 0:\n # If this child has its own children then recursive call\n grp.add_object(layout_child(child))\n else:\n grp.add_object(child)\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 obj in grp.objects:\n if obj is not grp.parent_object:\n obj.position = pos\n pos = self.move_in_level(pos, obj.size_in_level + self.item_spacing)\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 # + tree_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.tree_parent is not None:\n self.connect(source=obj.tree_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 tree 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\", tree_parent=grinders)\nburr_grinders = NodeObject(tree=tree, value=\"Burr Grinders\", tree_parent=grinders)\nblunt_objects = NodeObject(tree=tree, value=\"Blunt Objects\", tree_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 tree parent, so you can keep adding objects down the tree:
# Other\nelec_blade = NodeObject(tree=tree, value=\"Electric Blade Grinder\", tree_parent=blade_grinders)\nmnp = NodeObject(tree=tree, value=\"Mortar and Pestle\", tree_parent=blunt_objects)\n\n# Conical Burrs\nconical = NodeObject(tree=tree, value=\"Conical Burrs\", tree_parent=burr_grinders)\nelec_conical = NodeObject(tree=tree, value=\"Electric\", tree_parent=conical)\nmanual_conical = NodeObject(tree=tree, value=\"Manual\", tree_parent=conical)\n
Important Note: TreeDiagrams do not currently support NodeObjects with multiple tree 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) strokeWidth
The width of the edge or the stroke around the edge shape (1-999) 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/extended_objects/","title":"Extended Objects","text":"While any of the objects in Draw.io can be created by setting the correct combination of attributes it's not always convenient, particularly when an 'object' is actually a small group of objects. To offer a little more convenience drawpyo has extended objects. These inherit from the Object class but extend it with added functionality, though not quite to the level of the custom diagram types.
There's only one extended object implemented now but there could be more in the future, either mirroring Draw.io functionality or new object types.
"},{"location":"usage/extended_objects/#list","title":"List","text":"A list object is available in the General library in Draw.io. It's simple a small container object with a horizontal label filled with text objects as the list items. The Draw.io app conveniently keeps the list items positioned and in order as you add or remove, also scaling the size of the list container.
"},{"location":"usage/extended_objects/#creating-a-list","title":"Creating a List","text":"To create a list in drawpyo, use the diagram.List
object.
new_list = drawpyo.diagram.List(title=\"List\", page=page, width=200)\n
Like any other Object, the position and geometry can be set during creation as well as various styling attributes.
"},{"location":"usage/extended_objects/#adding-items","title":"Adding Items","text":"There are a few methods of adding items. The easiest would be using the .add_item()
method.
new_list.add_item(\"item 1\")\nnew_list.add_item(\"item B\")\nnew_list.add_item(\"item iii\")\n
This will create a text object, set the List as its parent, position it correctly, and then resize the List object.
You can also access the property list_items
. It will return a list of strings denoting all the items in the list. But it also has a setter property, so setting it to a list of strings will remove existing items and then go through the creation and resizing process.
"},{"location":"usage/extended_objects/#deleting-items","title":"Deleting Items","text":"The easiest way to delete an item is to call the .remove_item()
method. Pass in the text of the item to remove and it will be strucken from the list then the list resized.
new_list.remove_item(\"item B\")\n
"},{"location":"usage/extended_objects/#resizing-the-list","title":"Resizing the List","text":"The list will be automatically resized to match the contents when the above methods are called. But the resize can also be called manually with the .autosize()
method.
"},{"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:
- parallelogram
- shape
- process
- hexagon
- document
- cylinder3
- internalStorage
- cube
- step
- tape
- trapezoid
- note
- card
- callout
- dataStorage
and many more.
Confusingly there is another attribute called baseStyle
that is sometimes used in combination with shape
and sometimes without.
BaseStyles include:
- text
- ellipse
- rhombus
- triangle
- swimlane
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.
- rounded
- fillColor
- strokeColor
- opacity
- whiteSpace
- glass
- shadow
- comic
- line_pattern
"},{"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:
- darkOpacity
- darkOpacity2
- backgroundOutline
- perimeter
"},{"location":"usage/parent_child_objects/","title":"Parent and Child Objects","text":"In Draw.io, any object can have a parent. This is used within the app for containers and lists but actually any object can have subobjects. Within the XML this is achieved just be setting the parent
attribute from 1
(the page) to any other object's ID. This changes the X and Y coordinates of the child object to be relative to the parent's X and Y coordinates.
Drawpyo has convenient support for subobjects with a handful of attributes and parameters.
"},{"location":"usage/parent_child_objects/#linking-parent-and-child-objects","title":"Linking Parent and Child Objects","text":"A parent object can be assigned to any subobject either during instantiation or after the fact by using the parent
property. Every object has this property as well as a children
property that's a list of other objects.
Creating the parent object:
parent_container = drawpyo.diagram.object_from_library(\n library=\"general\", obj_name=\"labeled_horizontal_container\", page=page\n)\n
Adding child objects:
block_1 = drawpyo.diagram.object_from_library(\n library=\"general\", obj_name=\"rectangle\", page=page\n)\nblock_1.value = \"Block 1\"\nblock_1.parent = parent_container\n\nblock_2 = drawpyo.diagram.Object(\n position_rel_to_parent=(300, 300), parent=parent_container, value=\"Block 2\", page=page\n)\n
There are also methods for adding and removing objects:
parent_container.add_object(block_1)\n parent_container.remove_object(block_2)\n
This will create or remove the link on both ends (set the parent attribute of the child object as well as add the child to the parents. These functions are called by the setters of the parent
property, this is just an alternate syntax.
"},{"location":"usage/parent_child_objects/#positioning","title":"Positioning","text":"Within the Draw.io application, child objects X and Y coordinates are relative to the parent object. This isn't always useful so drawpyo offers two different position attributes. Both are tuples of ints: (X, Y). They both modify or return the underlying Geometry object so they can be used interchangeably and are not duplicate variables.
The normal position
attribute continues to be relative to the page regardless of whether there's a parent object set.
There is also a position_rel_to_parent
attribute that will return the position with respect to the position of the parent.
"},{"location":"usage/parent_child_objects/#autosizing","title":"Autosizing","text":"It's useful to have a parent object expand or contract to fit its objects. This behavior is disabled by default but can be enabled by setting the autosize_to_children
boolean parameter to True. There is also a corresponding parameter called autosize_margin
that sets the margin to maintain around the child objects in pixels. When this is set anytime that a child object is added, resized, or repositioned the parent will expand to fit the contents plus the margins. By default the parent will never contract unless autocontract
is set to True as well.
Note that the margin is inclusive of a container's title block.
The autofit behavior can also be called manually using the resize_to_children()
function on an object. This will respect the autofit_margin and autocontract behavior.
"},{"location":"usage/parent_child_objects/#combining-relative-positioning-and-autosizing","title":"Combining Relative Positioning and Autosizing","text":"Combining the autosizing behavior with relative positioning can cause unexpected behavior. Since the parent object will resize every time a child object is added or moved within it the successive objects added will now be relative to a new updated parent object position. This will make your code order-dependent.
To avoid this, either disable autosize_to_children
or use absolute positioning for child objects.
"},{"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-libraries","title":"Built-In Shape Libraries","text":"Drawpyo uses these TOML shape libraries to store the default libraries. 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-libraries","title":"Custom Shape Libraries","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 b/sitemap.xml
index a8d60ff..679a845 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -2,97 +2,97 @@
https://merrimanind.github.io/drawpyo/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/about/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/architecture/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/edges/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/extended_objects/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/file/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/objects/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/page/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/text_format/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/tree_diagram/nodeobject/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/api/tree_diagram/treediagram/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/diagram_types/tree_diagrams/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/basic_usage/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/edges/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/extended_objects/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/objects/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/parent_child_objects/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/shape_libs/
- 2024-07-31
+ 2024-08-13
daily
https://merrimanind.github.io/drawpyo/usage/text_format/
- 2024-07-31
+ 2024-08-13
daily
\ No newline at end of file
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index 5c7a22d..bfa897c 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 e68f008..7286f78 100644
--- a/usage/edges/index.html
+++ b/usage/edges/index.html
@@ -1359,6 +1359,10 @@ Color and Shading
The color of the edge or the stroke around the edge shape ('default', 'none', or a hex color code) |