oxean_flutter_gantt 0.2.2
oxean_flutter_gantt: ^0.2.2 copied to clipboard
Interactive Gantt chart widget for Flutter.
example/lib/main.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:oxean_flutter_gantt/config/gantt_chart_style_config.dart';
import 'package:oxean_flutter_gantt/models/gantt_task.dart';
import 'package:oxean_flutter_gantt/widgets/gantt_chart_widget.dart';
void main() {
runApp(MyApp());
}
List<GanttTask> tasks = [
// Use DateTime objects directly
GanttTask(
id: '1',
name: 'Requirement Analysis',
start: DateTime(2025, 3, 25),
end: DateTime(2025, 3, 27),
status: 'Done',
color: Colors.green,
progress: 1.0, // 100% complete
details: 'Define project scope and goals.'),
GanttTask(
id: '2',
name: 'Design Mockups',
start: DateTime(2025, 3, 30),
end: DateTime(2025, 4, 2),
status: 'In progress',
color: Colors.blue,
progress: 0.8, // 80% complete
details: 'Create and review UI/UX designs.',
dependsOn: '1'),
GanttTask(
id: '3',
name: 'Development Sprint 1',
start: DateTime(2025, 4, 3),
end: DateTime(2025, 4, 10),
status: 'In progress',
color: Colors.orange,
progress: 0.6, // 60% complete
details: 'Implement core features.',
dependsOn: '2'),
GanttTask(
id: '4',
name: 'Testing & QA',
start: DateTime(2025, 4, 11),
end: DateTime(2025, 4, 15),
status: 'In progress',
color: Colors.purple,
progress: 0.3, // 30% complete
details: 'Run test cases and fix bugs.',
dependsOn: '3'),
GanttTask(
id: '5',
name: 'Deployment Prep',
start: DateTime(2025, 4, 16),
end: DateTime(2025, 4, 17),
status: 'In progress',
color: Colors.red,
details: 'Prepare servers and docs.'),
GanttTask(
id: '6',
name: 'User Training',
start: DateTime(2025, 4, 16),
end: DateTime(2025, 4, 18),
status: 'Pending',
color: Colors.teal,
progress: 0.0, // 0% complete (not started)
details: 'Train end users.',
dependsOn: '4'),
GanttTask(
id: '7',
name: 'Deployment',
start: DateTime(2025, 4, 19),
end: DateTime(2025, 4, 20),
status: 'Pending',
color: Colors.amber,
progress: 0.0, // 0% complete (not started)
details: 'Go live with the product.',
dependsOn: '5'),
GanttTask(
id: '8',
name: 'Post-Deployment Support',
start: DateTime(2025, 4, 21),
end: DateTime(2025, 4, 25),
status: 'Pending',
color: Colors.cyan,
progress: 0.0, // 0% complete (not started)
details: 'Monitor and support users.',
dependsOn: '7'),
GanttTask(
id: '9',
name: 'Feedback Collection',
start: DateTime(2025, 4, 26),
end: DateTime(2025, 4, 30),
status: 'Pending',
color: Colors.indigo,
progress: 0.0, // 0% complete (not started)
details: 'Collect user feedback and suggestions.',
dependsOn: '8'),
];
// ignore: must_be_immutable
class PageWidget extends StatelessWidget {
late BuildContext context;
PageWidget({super.key});
@override
Widget build(BuildContext context) {
this.context = context; // Store the context for later use
return Scaffold(
appBar: AppBar(
title: const Text('Gantt Chart'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: GanttChartWidget(
tasks: tasks,
style: const GanttStyleConfig(
showProgressText: true,
),
onTaskTap: _showTaskDetails,
onDependencyDeleted: (GanttTask task) {
// Handle dependency deletion
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Dependency deleted for task: ${task.name}'),
),
);
},
onDependencyCreated: (GanttTask task) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Dependency created for task: ${task.name}'),
),
);
},
onTaskDatesChanged: (GanttTask task) {
if (kDebugMode) {
print(
'Task dates changed: ${task.name} from ${task.start} to ${task.end}');
}
},
),
),
);
}
void _showTaskDetails(GanttTask task) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(task.name),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(task.details),
const SizedBox(height: 10),
Text('Start: ${task.start}'),
Text('End: ${task.end}'),
Text('Progress: ${((task.progress ?? 0) * 100).toInt()}%'),
if (task.dependsOn != null)
Text(
'Depends on: ${tasks.firstWhere(
(t) => t.id == task.dependsOn,
orElse: () {
return GanttTask(
id: '?',
name: 'Unknown Task',
start: DateTime.now(),
end: DateTime.now(),
status: 'Pending',
color: Colors.grey,
details: '');
},
).name}',
),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Close'),
onPressed: () => Navigator.of(context).pop(),
),
],
),
);
}
}
// ignore: must_be_immutable
class MyApp extends StatelessWidget {
MyApp({super.key});
late BuildContext context;
@override
Widget build(BuildContext context) {
this.context = context; // Store the context for later use
return MaterialApp(
title: 'Flutter Gantt Chart',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true, // Use Material 3 features like SegmentedButton
// Optional: Define color scheme for better M3 look
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),
home: PageWidget(),
);
}
}