org_chart 4.0.2 copy "org_chart: ^4.0.2" to clipboard
org_chart: ^4.0.2 copied to clipboard

A flutter orgranizational chart with drag and drop, zoom and pan, search, collapse, expand, and easy customizations!

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:org_chart/org_chart.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Example2());
  }
}

class Example2 extends StatefulWidget {
  const Example2({super.key});

  @override
  State<Example2> createState() => _Example2State();
}

class _Example2State extends State<Example2> {
  final OrgChartController<Map> orgChartController = OrgChartController<Map>(
    boxSize: const Size(150, 80),
    items: [
      {
        "id": '0',
        "text": 'Main Block',
      },
      {
        "id": '1',
        "text": 'Block 2',
        "to": '0',
      },
      {
        "id": '2',
        "text": 'Block 3',
        "to": '0',
      },
      {
        "id": '3',
        "text": 'Block 4',
        "to": '1',
      },
    ],
    idProvider: (data) => data["id"],
    toProvider: (data) => data["to"],
    toSetter: (data, newID) => data["to"] = newID,
  );

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [
                Colors.blue.shade100,
                Colors.blue.shade200,
              ],
              begin: Alignment.bottomLeft,
              end: Alignment.topRight,
            ),
          ),
          child: Scaffold(
            backgroundColor: Colors.transparent,
            body: Stack(
              children: [
                Center(
                  child: OrgChart<Map>(
                    arrowStyle:
                        const DashedGraphArrow(pattern: [20, 10, 5, 10]),
                    cornerRadius: 10,
                    controller: orgChartController,
                    isDraggable: true,
                    linePaint: Paint()
                      ..color = Colors.black
                      ..strokeWidth = 5
                      ..style = PaintingStyle.stroke
                      ..strokeCap = StrokeCap.round
                      ..color = Colors.grey,
                    builder: (details) {
                      return Column(
                        children: [
                          GestureDetector(
                            onTap: () {
                              orgChartController.addItem({
                                "id": orgChartController.uniqueNodeId,
                                "text": 'New Block',
                                "to": details.item["id"],
                              });
                            },
                            onDoubleTap: () async {
                              String? text =
                                  await getBlockText(context, details.item);
                              if (text != null) {
                                setState(() => details.item["text"] = text);
                              }
                            },
                            child: Card(
                              elevation: 5,
                              color: details.isBeingDragged
                                  ? Colors.green.shade100
                                  : details.isOverlapped
                                      ? Colors.red.shade200
                                      : Colors.teal.shade50,
                              child: Center(
                                child: Text(
                                  details.item["text"],
                                  style: TextStyle(
                                    color: Colors.purple.shade900,
                                    fontSize: 20,
                                  ),
                                ),
                              ),
                            ),
                          ),
                          ElevatedButton(
                            onPressed: () {
                              details.hideNodes(!details.nodesHidden);
                            },
                            child: Text(
                              details.nodesHidden
                                  ? 'Press to Unhide'
                                  : 'Press to Hide',
                            ),
                          ),
                        ],
                      );
                    },
                    optionsBuilder: (item) {
                      return [
                        const PopupMenuItem(
                          value: 'Remove',
                          child: Text('Remove'),
                        ),
                      ];
                    },
                    onOptionSelect: (item, value) {
                      if (value == 'Remove') {
                        orgChartController.removeItem(
                            item["id"], ActionOnNodeRemoval.unlink);
                      }
                    },
                    onDrop: (dragged, target, isTargetSubnode) {
                      if (dragged["to"] == target["id"]) {
                        orgChartController.calculatePosition();
                        return;
                      }
                      if (isTargetSubnode) {
                        showDialog(
                            context: context,
                            builder: (_) {
                              return AlertDialog(
                                  title: const Text('Error'),
                                  content: const Text(
                                      'You cannot drop a node on a subnode'),
                                  actions: [
                                    TextButton(
                                      onPressed: () {
                                        Navigator.of(context).pop();
                                      },
                                      child: const Text('OK'),
                                    ),
                                  ]);
                            });
                        orgChartController.calculatePosition();

                        return;
                      }
                      dragged["to"] = target["id"];
                      orgChartController.calculatePosition();
                    },
                  ),
                ),
                const Positioned(
                  bottom: 20,
                  left: 20,
                  child: Text(
                      'Tap to add a node, double tap to change text\ndrag and drop to change hierarchy\nright click / tap and hold to remove \nDrag in the empty space to pan the chart\n& pinch to zoom in and out.'),
                )
              ],
            ),
            floatingActionButton: FloatingActionButton.extended(
                label: const Text('Reset & Change Orientation'),
                onPressed: () {
                  orgChartController.switchOrientation();
                }),
          ),
        ),
      ],
    );
  }

  Future<String?> getBlockText(
      BuildContext context, Map<dynamic, dynamic> item) async {
    final String? text = await showDialog(
      context: context,
      builder: (context) {
        String text = item["text"];
        return AlertDialog(
          title: const Text('Enter Text'),
          content: TextFormField(
            initialValue: item["text"],
            onChanged: (value) {
              text = value;
            },
          ),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text('Cancel'),
            ),
            TextButton(
              onPressed: () {
                Navigator.of(context).pop(text);
              },
              child: const Text('OK'),
            ),
          ],
        );
      },
    );
    return text;
  }
}
copied to clipboard
24
likes
150
points
924
downloads

Publisher

unverified uploader

Weekly Downloads

2024.08.26 - 2025.03.10

A flutter orgranizational chart with drag and drop, zoom and pan, search, collapse, expand, and easy customizations!

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

unknown (license)

Dependencies

flutter

More

Packages that depend on org_chart