v1.0.0diagram_editor
형 안정성 컴포넌트, 링크, 팬/줌 및 직렬화를 갖춘 상호작용 가능한 다이어그램 편집기를 구축하기 위한 플러터 라이브러리입니다.
183좋아요 50530일 다운로드160Pub 점수
AndroidiOSWebmacOSWindowsLinux
Fllutter 다이어그램 편집기 라이브러리
{"sdk":"flutter"}^4.5.1{"sdk":"flutter"}^7.0.0아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.
Flutter library for building interactive diagram editors. Create, connect, and manipulate nodes and links with pan, zoom, and full gesture support.
import 'package:diagram_editor/diagram_editor.dart';
import 'package:flutter/material.dart';
class MyDiagram extends StatelessWidget {
MyDiagram({super.key});
final controller = DiagramController<void, void>();
@override
Widget build(BuildContext context) {
return DiagramEditor<void, void>(
controller: controller,
componentBuilder: (context, component) => Container(
color: Colors.blue,
child: Center(child: Text(component.id)),
),
onCanvasTapUp: (details) {
controller.addComponent(ComponentData(
size: const Size(96, 72),
position: controller.fromCanvasCoordinates(details.localPosition),
));
},
onComponentTap: (id) => controller.removeComponent(id),
);
}
}
Pan, zoom, link joints, and link control all work out of the box.
Use generic type parameters to attach typed data to components and links:
class MyNodeData {
final Color color;
final String label;
MyNodeData({required this.color, required this.label});
}
final controller = DiagramController<MyNodeData, void>(
componentDataCodec: JsonCodec(
encode: (d) => {'color': d.color.toHex(), 'label': d.label},
decode: (j) => MyNodeData(
color: Color(int.parse(j['color'] as String, radix: 16)),
label: j['label'] as String,
),
),
);
// No more casting — data is typed
controller.addComponent(ComponentData(
data: MyNodeData(color: Colors.blue, label: 'Start'),
size: const Size(96, 72),
));
// Access data without casting
final node = controller.getComponent('id');
final color = node.data?.color; // Color, not dynamic
final linkId = controller.connect(
sourceComponentId: 'node-1',
targetComponentId: 'node-2',
linkStyle: LinkStyle(
arrowType: ArrowType.arrow,
lineWidth: 2,
color: Colors.grey,
),
);
DiagramEditor<MyNodeData, void>(
controller: controller,
componentBuilder: (context, data) => MyNodeWidget(data),
// Canvas config
canvasConfig: const CanvasConfig(
backgroundColor: Color(0xFFF5F5F5),
minScale: 0.2,
maxScale: 5.0,
),
// Link endpoint alignment strategy
linkEndpointAlignment: LinkAttachment.oval(),
// Disable defaults if you want full control
enableDefaultPanZoom: true, // default
enableDefaultLinkControl: true, // default
enableDefaultJointControl: true, // default
// Links rendered on top of components
linksOnTop: true, // default
// All gesture callbacks
onCanvasTapUp: (details) { /* ... */ },
onComponentTap: (id) { /* ... */ },
onComponentScaleUpdate: (id, details) { /* ... */ },
onLinkTap: (id) { /* ... */ },
// Custom layers
backgroundBuilder: (context) => [CustomPaint(painter: GridPainter())],
foregroundBuilder: (context) => [/* selection UI, toolbars, etc. */],
componentOverlayBuilder: (context, data) => /* resize handles, etc. */,
);
// Save
final json = controller.serialize();
// Load
controller.deserialize(json);
Custom data is serialized via the JsonCodec passed to the controller.
The central class managing all diagram state.
| Category | Methods |
|---|---|
| Components | addComponent, removeComponent, moveComponent, getComponent, componentExists, components, componentsSorted |
| Links | connect, removeLink, getLink, linkExists, links |
| Z-order | bringToFront, sendToBack, setComponentZOrder |
| Parent-child | setComponentParent, removeComponentParent |
| Canvas | setCanvasPosition, panCanvas, zoomCanvas, resetCanvasView, fromCanvasCoordinates, toCanvasCoordinates |
| Joints | insertLinkJoint, removeLinkJoint, showLinkJoints, hideLinkJoints |
| Serialization | serialize, deserialize |
| Strategy | Method |
|---|---|
| Rectangular | LinkAttachment.rectangular() (default) |
| Oval | LinkAttachment.oval() |
| Crystal/Diamond | LinkAttachment.crystal() |
| Center | LinkAttachment.center() |
none, arrow, pointedArrow, circle, centerCircle, semiCirclesolid, dashed, dottedGridPainter — canvas grid backgroundComponentHighlightPainter — selection highlightDeleteIconPainter — delete icon overlaySee the full Migration Prompt for a detailed mapping of every old API surface to its new equivalent, including complete before/after examples.
Key changes:
PolicySet with mixins -> DiagramEditor with callbackscanvasWriter.model.addComponent(...) -> controller.addComponent(...)componentData.data as MyType -> componentData.data (typed generics)provider dependency removed (uses built-in ListenableBuilder)