Skip to content

Refactor Graph class and mixins to improve modularity and tree-shaking #762

@tbouffard

Description

@tbouffard

Is your feature request related to a problem? Please describe

The Graph class is currently the central point of maxGraph (version 0.17.0), containing numerous functionalities. This setup prevents optional features from being loaded only when needed, which negatively impacts tree-shaking and performance.

Additionally, several methods in the Graph class are only used by plugins or other specific components but are still always bundled due to their location. This approach, inherited from mxGraph for easier migration, makes Graph a "God Object" and blurs responsibility boundaries.

Describe the solution you'd like

We want to clarify responsibilities and improve tree-shaking efficiency by relocating methods from the Graph class and its mixins to the specific plugins or classes where they are actually used. This may involve creating new plugins, moving existing methods, and possibly removing unused or deprecated ones.

Warning

This will introduce breaking changes, but the long-term benefits in modularity and performance make it worthwhile.

Proposed changes

Note

This list is not exhaustive.

✔ FitPlugin (Graph.fit)

  • Move Graph.fit to a new FitPlugin.
  • Related PR: #734
  • Available in 0.21.0

FoldingMixin

  • Remove the mixin.
  • Move its methods to a new dedicated plugin.
  • Relocate related Graph.options properties.

OverlaysMixin

  • Move the getCellOverlays to AbstractGraph. This is an extension point to eventually override the result of cell.overlays. The JSDoc of this method should be improved to mention that
  • Move properties from AbstractGraph to the new Plugin. Related getter/setter could be remove
    • warningImage

PanningMixin

  • Evaluate which methods are used only by PanningHandler and move them there.
  • Move appropriate methods to a new ScrollPlugin (see below).
  • The remaining methods may be moved to a separate plugin.

PageBreaksMixin

  • Evaluate page break-related properties currently defined directly in Graph.
  • Move updatePageBreaks (only used by EventsMixin) accordingly. See also sizeDidChange.

ScrollPlugin

  • Introduce a new plugin with id scroll.
  • Move the following methods:
    • From PanningMixin:
      • scrollCellToVisible
      • scrollRectToVisible
    • From Graph:
      • scrollPointToVisible (evaluate its impact before moving)
      • center

✔ TooltipMixin

  • Move getTooltip and getTooltipForCell to the TooltipHandler plugin.
  • Decide whether to remove or relocate setTooltips (likely remove).
  • Related PR: #640

ValidationMixin

  • This mixin is quite independent and currently uses browser alerts.
  • Consider replacing alerts with a custom logger in the Validation story.
  • Move allowLoops (and its getter/setter) here in preparation for future extraction.
  • Move properties from AbstractGraph to the new Plugin. Related getter/setter could be remove
    • alreadyConnectedResource
    • containsValidationErrorsResource
    • multiplicity
  • ⚠️ Some methods depends on the OverlaysMixin which is planned to be converted to Plugin

Note: the method ConnectionsMixin.isValidConnection (and some methods it uses) is only used by ValidationMixin. So, the related code could be moved to the new plugin as well.

ZoomMixin

  • Create a ZoomPlugin (id zoom) and move all methods from this mixin.
  • This plugin will depend on ScrollPlugin, as zoom features require scroll capabilities. Document this dependency.

🚧 Edge and Vertex handler factory methods

See #823

maxGraph lets you perform actions on cells when they are selected. This is orchestrated by the SelectionCellsHandler plugin, which currently relies on Graph methods to create dedicated handlers for edges and vertices. This indirection comes from mxGraph and is still in place to ease migration.

If an application doesn't require selection actions (e.g., viewer-only mode), the plugin can be removed (see #432). However, EdgeHandler and VertexHandler classes remain imported because they are still defined in Graph.

  • Move these methods to the SelectionCellsHandler plugin.
  • This change can significantly reduce bundle size. Experimentation shows that the decrease could be about 65 kB (see PR #449).
  • Update stories to override plugin methods instead of the Graph.createHandler method:
    • ContextIcons → override createVertexHandler
    • Wires → override createEdgeHandlerInstance

Other refactorings

  • Continue reducing the size and responsibility of the Graph class:

Describe alternatives you've considered

  • Keep current structure to ease mxGraph migration — dismissed due to tree-shaking and modularity issues.
  • Gradually refactor over several releases to reduce migration burden.

Additional context

  • This refactor introduces breaking changes and should be documented in the migration guide.
  • It aligns with long-term goals: improved modularity, better maintainability, and smaller builds.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions