Skip to main content

Diagram tools

Provides a set of tools for working with shapes in a Diagram - resizing, rotating, cloning, deleting, and creating links.

The plugin automatically attaches tools to any shape that is added to VisuallyJs's current selection, and removes the tools when the shape is removed from the selection.

Setup​

This plugin is installed on an editable Diagram by default, and configured indirectly via various diagram options.

By default, these tools are enabled:

  • Resize Places a handle at each corner of a shape, with which the user can alter the shape's size
  • Rotate Places a rotate handle above the shape, which the user can drag to rotate the shape.
  • Clone Places a clone button at the top right corner, which a user can click on to create a clone of the shape
  • Link Places a link handle at the bottom right, from which a user can drag a link to another shape

The default settings for the diagram tools plugin attach a handle at each corner that your users can drag to resize, but you can also instruct the plugin to allow users to resize by dragging an element's borders

Resizing​

The default resize mechanism is to place handles at each corner and halfway along each edge on a vertex's perimeter:

Handle shape​

By default, the plugin will use circular handles. You can change this to use rectangular handles by setting handleShape:"rectangle" in the cell options:


Handle size​

The default handle size is 10 pixels. You can change this to use rectangular handles by setting handleSize:


Resize by border​

Instead of attaching a handle at each corner to enable resize, you can setup the diagram tools to allow resize by dragging the borders of the element:

Border visibility​

By default, the borders for resizing will be visible to the user. You can set bordersVisible:false to hide the borders - the user will still see the cursor change when hovering over a border, but the border itself will not be shown:

Rotation​

By default, the rotation tool is enabled.

Disabling rotation​

You can switch off the rotate tool by setting rotatable:false in the cells diagram option:

Rotation stops​

The default behaviour is to support rotation to any angle, but you can specify the number of rotation stops VisuallyJs should use:

Grids​

When the associated diagram has a grid, this plugin will constrain node/group resizing so that the dimensions of the vertex are a multiple of the grid in each axis.

Ignoring the grid​

Constraining resize to the grid is controlled by the ignoreGrid option, which is set to false by default. You can change that:

Constraining resize axes​

By default, the diagram tools plugin will allow users to resize an element's width and height. This behaviour can be changed, by setting resizeX or resizeY to "false" in the plugin options.

The above configuration would result in a setup where your users can only resize the height of elements:

Excluding elements​

You can exclude specific elements from being resizable by writing a data-vjs-resizable attribute on them:

<div data-vjs-resizable="false">{{name}}</div>

Custom payloads​

You can provide a payloadGenerator to the diagram tools which will be invoked before the diagram tools commits a change to a model object. This method allows you to customize the changes that will be made to the model object (or it can be used as a hook to make other changes in your model of course):

payloadGenerator?:(v:Node, p:ObjectData) => ObjectData
import { newInstance, ResizingToolsPlugin } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
plugins: [
{
type: ResizingToolsPlugin.type,
options: {
payloadGenerator: (vertex, data) => {
return {
someDynamicValue:data.w * something etc
}
}
}
}
]
})

In this example the model object's data will be updated with the someDynamicValue we calculated.

caution

A payload generator function cannot override the value of any attributes the diagram tools needs to set, ie. the position or size of the object. the diagram tools will merge its attributes on top of any you return from a payload generator.

CSS​

ClassDescription
vjs-resize-borderSet on the border handles
vjs-resize-border-bSet on the bottom border handle
vjs-resize-border-lSet on the left border handle
vjs-resize-border-rSet on the right border handle
vjs-resize-border-tSet on the top border handle
vjs-resize-frameSet on the frame the resize tool draws around an object it is currently editing.
vjs-resize-handleSet on the resize handles by the resizing/diagram tools
vjs-resize-handle-activeSet on a resize handle when it is being actively used
vjs-resize-handle-bSet on the bottom center resize handle
vjs-resize-handle-blSet on the bottom left corner resize handle
vjs-resize-handle-brSet on the bottom right corner resize handle
vjs-resize-handle-lSet on the left center resize handle
vjs-resize-handle-rSet on the right center resize handle
vjs-resize-handle-tSet on the top center resize handle
vjs-resize-handle-tlSet on the top left corner resize handle
vjs-resize-handle-trSet on the top right corner resize handle
vjs-resize-skeletonSet on the element that is the parent of drag handles when in handles resize mode.
vjs-resize-skeleton-bordersSet on the element that is the parent of drag borders when in borders resize mode.
vjs-resize-skeleton-borders-visibleSet on the resize tool's main group element for some vertex when bordersVisible is set to true and the resize mode is RESIZING_TOOLS_RESIZE_METHOD_BORDERS
vjs-rotate-handleSet on the rotation handle
vjs-rotate-leaderSet on the leader to the rotation handle.

Options​

ResizingToolsPluginOptions
Options for the resizing tool plugin.
NameTypeDescription
borderHandleSize?numberSize of handles when using "border" resize. Defaults to 6 pixels.
bordersVisible?booleanWhen resizeMethod is "borders", set this to make the borders visible. Internally this just sets a CSS class on the draw skeleton's parent DOM element, and the appearance of the borders is then controlled via CSS.
canResizeFilter?(v:Vertex, el:BrowserElement) => booleanOptional function that can decide on whether or not the given vertex should be resizable
canRotateFilter?(v:Vertex, el:BrowserElement) => booleanOptional function that can decide on whether or not the given vertex should be rotatable
constrainGroups?booleanDefaults to true, meaning groups will not be shrunk to the point that one or more of their child vertices is no longer visible.
handleOffset?numberHow much to offset the resize frame and handles from the bounds of the shape. Defaults to 5 pixels.
handlerFactory?ResizingToolsHandlerFactoryOptional factory that can return a resize handler for some given vertex. You can use this to override the default behaviour for any vertex you choose
handleShape?"circle" | "rectangle"Shape of resize handles. Defaults to circle.
handleSize?numberWidth/height to use for handles. Defaults to 20 pixels.
heightAttribute?stringAttribute to use for vertex height - defaults to 'height'
ignoreGrid?booleanDefaults to false, meaning size changes conform to an underlying grid, if present
leftAttribute?stringAttribute to use for vertex left position - defaults to 'left'
minimumHeight?numberMinimum height the user can shrink a vertex to. Defaults to 30.
minimumWidth?numberMinimum width the user can shrink a vertex to. Defaults to 30.
modelUpdater?ResizingToolsModelUpdaterOptional function that can inject extra model updates each time a vertex is resized.
onDemand?booleanDefaults to false, meaning the resizing tool plugin switches on whenever a new vertex is selected.
onEdit?(o:Node | Group, surface:Surface, toolkit:VisuallyJsModel) => anyOptional callback invoked after an edit has occurred
payloadGenerator?(v:Node, p:ObjectData) => ObjectDataOptional function to invoke when a resize has occurred. The values the resizing plugin wants to write for the vertex are merged on top of the value returned from this function, and the combined payload is written as an update to the vertex in the data model. This exists for internal use mostly but there's no harm in it being exposed for your enjoyment.
resizeMethod?ResizingToolsResizeMethodMethod to use for resize - handles on the corners, or borders. Defaults to handles.
resizeX?booleanWhether or not to support resize in the X axis. Defaults to true.
resizeY?booleanWhether or not to support resize in the Y axis. Defaults to true.
rotatable?booleanWhether or not to support rotation on all elements.. Defaults to false.
rotateHandleSize?numberSize of the rotate handle. Defaults to 16 pixels.
rotateLeaderLength?numberLength of the leader line to the resize handle when using the resizing tools in an SVG container. Defaults to 30 pixels.
rotationStops?numberOptional number of stops to use when rotating. If not provided vertices can be rotated to any angle. If provided, the value is divided into 360 and the result is the angle between each stop. For example, a value of 12 means each stop is 30 degrees.
topAttribute?stringAttribute to use for vertex top position - defaults to 'top'
widthAttribute?stringAttribute to use for vertex width - defaults to 'width'