搜尋套件、儲存庫與 APP 分類

diagram_editor 封面
套件詳情v1.0.0

diagram_editor

一個用於建立互動式圖表編輯器的 Flutter 庫,支援類型安全的元件、連結、平移/縮放與序列化。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
1110
喜歡數
184
Pub 分數
160

安裝套件

flutter pub add diagram_editor

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

一個專為建立互動式圖表編輯器而設計的Flutter程式庫,支援類型安全的元件、動態連結、平移與縮放功能,以及無縫序列化。它讓開發者能使用一致且可重複使用的UI元件,建構豐富的視覺化工具,適用於流程圖、線框圖及其他圖表類型。此程式庫跨平台,支援Android、iOS、Web、macOS、Windows及Linux,非常適合需要即時圖表操作與資料持久化的應用。以開發人員體驗為導向,提供直覺的API來管理圖表狀態與互動。

適用情境

  • 創建流程圖建構器
  • 設計線框圖工具
  • 建構可視化程式設計介面
  • 開發協作式繪圖應用
  • 實現網絡拓撲可視化工具

主要特色

  • 類型安全的元件系統
  • 互動式連結管理
  • 內建的平移與縮放控制項
  • 資料持久化的序列化
  • 跨平台相容性
  • 可擴展的外掛架構

適合對象

  • UI/UX 開發人員建構視覺工具
  • 教育類應用開發者
  • 設計工作流系統的軟體架構師
  • 需要跨平台繪圖解決方案的團隊
  • 快速原型化互動式圖表

使用建議

  • 需要理解 Flutter 的 widget 樹
  • 可能需要自定樣式來處理複雜圖表
  • 大型圖表帶來的效能影響
  • 有限的內建形狀庫(可擴展)
  • 進階功能的初始學習曲線

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

diagram_editor

pub package

Flutter library for building interactive diagram editors. Create, connect, and manipulate nodes and links with pan, zoom, and full gesture support.

Quick Start

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.

Type-Safe Custom Data

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

Connecting Components

final linkId = controller.connect(
  sourceComponentId: 'node-1',
  targetComponentId: 'node-2',
  linkStyle: LinkStyle(
    arrowType: ArrowType.arrow,
    lineWidth: 2,
    color: Colors.grey,
  ),
);

Configuration

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. */,
);

Serialization

// Save
final json = controller.serialize();

// Load
controller.deserialize(json);

Custom data is serialized via the JsonCodec passed to the controller.

API Overview

DiagramController

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
Link Endpoint Alignment
Strategy Method
Rectangular LinkAttachment.rectangular() (default)
Oval LinkAttachment.oval()
Crystal/Diamond LinkAttachment.crystal()
Center LinkAttachment.center()
Link Styles
  • Arrow types: none, arrow, pointedArrow, circle, centerCircle, semiCircle
  • Line types: solid, dashed, dotted
Built-in Painters
  • GridPainter — canvas grid background
  • ComponentHighlightPainter — selection highlight
  • DeleteIconPainter — delete icon overlay

Migration from v0.x

See 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 callbacks
  • canvasWriter.model.addComponent(...) -> controller.addComponent(...)
  • componentData.data as MyType -> componentData.data (typed generics)
  • provider dependency removed (uses built-in ListenableBuilder)

所屬分類

依賴

依賴清單 1 項

原始碼儲存庫

使用此套件的專案

暫無相關資料。