Draw.io offers pre-built shapes, and lets you use your own raster and SVG images. This provides you with a lot of flexibility, but this approach doesn't let you style raster or SVG images, except for these colors in SVG images. Because SVG and raster images aren't native shapes, draw.io can't know where to draw a shadow, which line(s) the line width applies to, etc.
You can, however, create custom shapes in the Edit Shape dialog by entering XML to define the geometry, add text and style the shape. Click Arrange > Insert > Shape to see a simple example custom shape.
Custom shapes, once added to the drawing canvas, can be dragged into the Scratchpad or into a custom library. Create a new custom library to contain your custom shapes by selecting File > New Library.
Below is a description of the XML format used to create custom shapes. Add the XML content of this instructional example into the Edit Shape dialog (Arrange > Insert > Shape) to see a demonstration of a number of elements and their XSD.
The outer element is <shape>, that has the following attributes:
- name - string, required. The stencil name that uniquely identifies the shape. Not used in draw.io currently.
- w, h - optional decimal view bounds. This defines your co-ordinate system for the graphics operations in the shape. The default is 100,100.
- aspect - optional string with the value of either "variable", the default, or "fixed". Fixed means always render the shape with the aspect ratio defined by the ratio w/h. Variable causes the ratio to match that of the geometry of the current vertex.
- strokewidth - optional string containing either an integer or the string "inherit". Inherit indicates that the strokewidth of the cell is only changed on scaling, not on resizing. If numeric values are used, the strokewidth of the cell is changed on both scaling and resizing and the value defines the multiple that is applied to the width. Default is "1".
If you want to define specific fixed connection points on the shape, use the <connections> element. Each <constraint> element within the connections element defines a fixed connection point on the shape. Constraints have the following attributes:
- perimeter - required, with the values 1 or 0. 0 sets the connection point where specified by x,y. 1 causes the position of the connection point to be extrapolated from the center of the shape, through x,y to the point of intersection with the perimeter of the shape.
- x, y - the position of the fixed point relative to the bounds of the shape. They can be automatically adjusted if perimeter=1. (0,0) is top left, (0.5,0.5) is the center, (1,0.5) is the center of the right hand edge of the bounds, etc. Values may be less than 0 or greater than 1 to be positioned outside of the shape.
- name - optional string. A unique identifier for the port on the shape.
<background> and <foreground>
The paths used to draw the shape are split into two elements, <foreground> and <background>. The split is to define the part that any shadow is applied to, derived from the <background>. Generally, the background of the shape is the line that traces the outside of the shape, but not always.
Any stroke, fill or fillstroke of a background must be the first element of the foreground element, they must not be used within <background>. If the background of your shape is empty, this is not required.
Because the background cannot have any fill or stroke, it can contain only one <path>, <rect>, <roundrect> or <ellipse> element (or none). It can also not include <image>, <text> or <include-shape>.
Note that the state, styling and drawing in mxGraph stencils is very close in design to that of HTML 5 canvas. Tutorials on this subject, if you're not familiar with the topic, will give you a good high-level introduction to the concepts used.
Rendering within the foreground and background elements has the concept of state. There are two types of operations other than state save/load, styling and drawing. The styling operations change the current state.
- <save/> - saves the current state (current style).
- <restore/> - retrieves the last saved state from the state stack.
The elements that change the colors within the current state (style) all take a hash-prefixed hex color code ("#FFEA80").
- <strokecolor> - sets the color that drawing paths will be rendered in when a stroke or fillstroke command is issued.
- <fillcolor> - sets the color that the inside of closed paths will be rendered in when a fill or fillstroke command is issued.
- <fontcolor> - sets the color that fonts are rendered in when text is drawn.
The other styling elements are as follows:
- <alpha> - defines the degree of transparency used between 1.0 for fully opaque and 0.0 for fully transparent.
- <fillalpha> - defines the degree of fill transparency used between 1.0 for fully opaque and 0.0 for fully transparent.
- <strokealpha> - defines the degree of stroke transparency used between 1.0 for fully opaque and 0.0 for fully transparent.
- <strokewidth> - defines the integer thickness of drawing elements rendered by stroking. Use fixed="1" to apply the value as-is, without scaling.
- <dashed> - "1" for dashing enabled and "0" for disabled.
- <dashpattern> - defines the pattern of dashes and spaces on dashed strokes (when these are enabled). dashpattern is a sequence of space-separated "on, off" lengths that define the number of points to draw a line or a space. The pattern repeats, and the default is "3 3". You could define a more complex pattern with "5 3 2 6", for example. Generally, it makes sense to have an even number of elements in the dashpattern, but that's not required.
- <linejoin>, <linecap> and <miterlimit> - best explained by the Mozilla page on Canvas styling. The values are all the same except we use "flat" for linecap instead of Canvas' "butt".
For font styling, the following elements are used:
- <fontsize> - an integer.
- <fontstyle> - an ORed bit pattern of bold (1), italic (2) and underline (4), i.e. bold underline is "5".
- <fontfamily> - a string defining the typeface to be used.
Most of the drawing (the lines inside the shape) is contained within a <path> element. Again, the graphic primitives are very similar to that of HTML 5 Canvas.
- <move> - to attributes required decimals (x,y).
- <line> - to attributes required decimals (x,y).
- <quad> - to required decimals (x2,y2) via control point required decimals (x1,y1).
- <curve> - to required decimals (x3,y3), via control points required decimals (x1,y1) and (x2,y2).
- <arc> - a copy of the SVG arc command and doesn't follow the HTML Canvas signatures. The SVG specification documentation gives the best description of its behaviors. The attributes are named identically, they are decimals and all required.
- <close> - ends the current subpath and causes an automatic straight line to be drawn from the current point to the initial point of the current subpath.
In addition to the graphics primitive operations described above, there are non-primitive operations. These provide an easy method to draw some basic shapes:
- <rect> - attributes "x", "y", "w", "h", all required decimals.
- <roundrect> - attributes "x", "y", "w", "h", all required decimals. Also "arcsize" an optional decimal attribute defining how large, the corner curves are.
- <ellipse> - attributes "x", "y", "w", "h", all required decimals.
Note that these 3 shapes and all paths must be followed by either a fill, stroke, or fillstroke to render them.
<text> elements have the following attributes:
- str - the text string to display, required.
- x and y - the decimal location (x,y) of the text element, required.
- align - the horizontal alignment of the text element, either "left", "center" or "right". Optional, default is "left".
- valign - the vertical alignment of the text element, either "top", "middle" or "bottom". Optional, default is "top".
- localized - 0 or 1. If 1 then the "str" actually contains a key used to fetch the value out of mxResources. Optional, default is 0, unused in draw.io.
- vertical - 0 or 1. If 1 then the label is rendered vertically (rotated by 90 degrees). Optional, default is 0.
- rotation - angle in degrees (0 to 360). The angle to rotate the text by. Optional, default is 0.
- align-shape - 0 or 1. If 0 then the rotation of the shape is ignored when setting the text rotation. Optional, default is 1.
- placeholders -0 or 1. If 1 then placeholders of the form %name% will be replaced with their values. Optional, default is 0.
<image> elements can either be external URLs, or data URIs, where supported (not supported in IE 7-). Attributes are:
- src - required string. Either a data URI or URL.
- x, y - required decimals. The (x,y) position of the image.
- w, h - required decimals. The width and height of the image.
- flipH, flipV = optional 0 or 1. Used to flip the image along the horizontal/vertical axis. Default is 0 for both.
Sub-shapes (only supported for built-in shapes in draw.io)
<include-shape> allow stencils to be rendered within the current stencil by referencing the sub-stencil by name. Attributes are:
- name - required string. The unique shape name of the stencil.
- x, y, and w, h -required decimals. The (x,y) position of the sub-shape and its width and height.