Skip to main content

Plugins

warning

The plugin system is still under development and the API is subject to change.

info

The examples in this page use TypeScript; adapt them if you write JavaScript.

Introduction

The maxGraph plugins system aims to:

  • reduce coupling in the code, in particular in the Graph class
  • improve the tree-shaking
  • provide extension points

Historically, the Graph class coming from mxGraph was a monolithic class that included all the features. In particular, it contained many handler instances that were gradually phased out and turned into plugins.

For more details about discussions and decisions, refer to the following discussions:

Available Plugins

The following table lists all built-in plugins provided by maxGraph.

Plugins marked as default are automatically loaded when using Graph. When using BaseGraph, no plugin is loaded — you must pass the ones you need explicitly.

PluginDescriptionDefault
CellEditorHandlerIn-place cell label editing✔️
ConnectionHandlerDrawing new edges between cells✔️
FitPluginFit-to-container utilities (fit(), fitCenter())✔️
ImageBundlePluginImage bundle resolution for style.image keys (see Image Bundles)✔️
PanningHandlerMouse and touch panning✔️
PopupMenuHandlerRight-click context menus✔️
RubberBandHandlerRubber band (lasso) selection. Requires loading CSS
SelectionCellsHandlerManages per-cell selection handlers (move, resize, rotate)✔️
SelectionHandlerClick and marquee selection✔️
TooltipHandlerHover tooltips✔️

Retrieving and Using a Plugin

Use the getPlugin method to retrieve a plugin instance from a Graph instance and then call the methods or properties it provides:

const graph = new Graph(container);
const panningHandler = graph.getPlugin<PanningHandler>('PanningHandler');
panningHandler.useLeftButtonForPanning = true;
panningHandler.ignoreCell = true;

Choosing the Plugins to Use

The plugins to use can be specified when creating a graph.
The default plugins depend on which Graph class you use — see the Graph documentation page for details on choosing between Graph and BaseGraph.

You can pass exactly the plugins you need via the constructor. Here is an example with Graph, where the RubberBandHandler plugin is added on top of the default plugins:

const graph = new Graph(container, undefined, [
...getDefaultPlugins(),
RubberBandHandler, // Enables rubber band selection
]);

Here is an example with BaseGraph:

const graph = new BaseGraph({
container,
plugins: [
CellEditorHandler,
SelectionCellsHandler,
SelectionHandler,
PanningHandler,
],
});

It is also possible to use a dedicated set of plugins, in particular when extending some plugins provided out of the box by maxGraph.

In the following example, a MyCustomConnectionHandler plugin is used instead of the default ConnectionHandler plugin:

const graph = new BaseGraph({
container,
plugins: [
CellEditorHandler,
SelectionCellsHandler,
MyCustomConnectionHandler,
SelectionHandler,
],
});
warning

When replacing a built-in plugin with a custom implementation, make sure you do not include both the original and the custom plugin in the list. Loading two plugins that handle the same functionality (e.g., both registering listeners for the same events) leads to non-deterministic behavior.

Creating a Custom Plugin

A custom plugin is defined as a class:

  • It must implement the GraphPlugin interface.
  • Its constructor must satisfy the GraphPluginConstructor type.
  • It can provide new methods to extend the existing API or introduce new behavior (using listeners, for example).
class MyCustomPlugin implements GraphPlugin {
static pluginId = 'my-custom-plugin';

constructor(graph: Graph) {
// Initialization and configuration code
}
}