Skip to content

9. Control the canvas and grid ​

Commercial extension tutorial · Built on the free Core + Flutter foundations. Start with the free Hello World example.

Finish with view controls. These change presentation and interaction options without rewriting the saved flowchart.

The grid is always installed, and its GridOptions belong to the grid extension. Add a toggle to the reactive toolbar; the toolbar's Observer reads controller.options<GridOptions>(), so it rebuilds when the options change:

dart
FilterChip(
  label: const Text('Grid'),
  selected: controller.options<GridOptions>().visible,
  onSelected: (visible) => controller.edits.setOptions(
    controller.options<GridOptions>().copyWith(
      visible: visible,
      snap: visible,
    ),
  ),
),

This UI deliberately toggles visibility and snapping together. visible and snap are independent. When visible, direct manipulation snaps to displayed grid spacing; when hidden with snapping enabled, it uses the configured base interval. Zooming out can reduce grid density.

Add two more toolbar controls:

dart
TextButton(
  onPressed: () => controller.view.show(const ViewTarget.selection()),
  child: const Text('Fit selection'),
),
TextButton(
  onPressed: () =>
      controller.view.show(const ViewTarget.point(DiagramPoint.zero, zoom: 1)),
  child: const Text('Reset view'),
),

Navigation needs a mounted, laid-out canvas. These callbacks run after mounting. For initial navigation, use a post-frame callback and verify that the State is still mounted and the controller attached (controller.isAttached).

For a zoom percentage, read controller.camera.zoom inside an Observer; it rebuilds as the camera moves. Document changes will not update a zoom label.

The default canvas is infinite. Pass DiagramConfiguration(bounds: CanvasBounds.fit(padding: 48)), or call controller.edits.setBounds(const CanvasBounds.fit(padding: 48)), if your editor needs a bounded workspace: the canvas then fits the content plus that padding in screen pixels. Bounds and options changes preserve document and history; copyWith keeps the other grid options intact across your toggle.

For a minimap, add the vyuh_diagram_extension_minimap package and install MinimapExtension() in the configuration's extensions. It owns MinimapOptions, so a toolbar toggle is one call:

dart
final minimap = controller.options<MinimapOptions>();
controller.edits.setOptions(minimap.copyWith(visible: !minimap.visible));

Checkpoint: select nodes and fit the selection, change the grid, pan and zoom. Saving still captures authored world coordinates; camera movement creates no document Undo entry.

Where to go next ​

You now have a flowchart canvas, a registry, reactive host controls, an inspector, connections, a JSON boundary, a custom node and a shared keyboard shortcut. Your application supplies storage, authorization and domain semantics around those boundaries.

Try the interactive flowchart example, then use Common tasks for focused recipes or Build a library to package your domain shapes. Navigation and motion and Grids cover the remaining view controls.