Gantt Calendar
A flexible and customizable Gantt chart calendar widget for Flutter applications. This package provides an elegant way to visualize tasks and projects across time periods with a clean, responsive interface.
Preview
|
iOS |
Android
|
Features
- Multi-month view: Display tasks spanning across multiple months
- Customizable styling: Extensive theming options for colors, fonts, and dimensions
- Task visualization: Clear representation of tasks with customizable colors and text
- Month navigation: Built-in controls for navigating between months
- Programmatic control: Controller for programmatically navigating and managing the calendar
- Custom builders: Flexibility to customize header cells, task cells, and navigation components
- Responsive layout: Adapts to different screen sizes
- Task interaction: Support for tapping on tasks with callbacks
Getting started
Add the package to your pubspec.yaml:
dependencies:
gantt_calendar: ^1.0.0
Then run:
flutter pub get
Import the package in your Dart code:
import 'package:gantt_calendar/gantt_calendar.dart';
Usage
Basic Usage
Create a simple Gantt calendar with a list of tasks:
final tasks = [
GanntTask(
startDate: DateTime.now().subtract(const Duration(days: 2)),
endDate: DateTime.now().add(const Duration(days: 3)),
color: Colors.blue.shade300,
textColor: Colors.white,
assignedTo: 'John Doe',
task: 'Design UI',
),
GanntTask(
startDate: DateTime.now().add(const Duration(days: 4)),
endDate: DateTime.now().add(const Duration(days: 8)),
color: Colors.green.shade300,
textColor: Colors.white,
assignedTo: 'Jane Smith',
task: 'Develop Backend',
),
];
GanttCalendar(
tasks: tasks,
taskHeaderText: 'Tasks',
)
Tasks Spanning Multiple Months
You can create tasks that span across different months:
final now = DateTime.now();
final lastMonth = DateTime(now.year, now.month - 1, 15);
final nextMonth = DateTime(now.year, now.month + 1, 1);
final tasks = [
// Task in last month
GanntTask(
startDate: DateTime(lastMonth.year, lastMonth.month, 10),
endDate: DateTime(lastMonth.year, lastMonth.month, 20),
color: Colors.purple.shade300,
textColor: Colors.white,
assignedTo: 'Alice Chen',
task: 'Research Phase',
),
// Task spanning from last month to current month
GanntTask(
startDate: DateTime(lastMonth.year, lastMonth.month, 25),
endDate: DateTime(now.year, now.month, 5),
color: Colors.teal.shade300,
textColor: Colors.white,
assignedTo: 'Sarah Johnson',
task: 'Architecture Planning',
),
// Task spanning from current month to next month
GanntTask(
startDate: now.add(const Duration(days: 20)),
endDate: DateTime(nextMonth.year, nextMonth.month, 10),
color: Colors.deepPurple.shade300,
textColor: Colors.white,
assignedTo: 'Team',
task: 'Final Review & Deployment',
),
]
Customizing Appearance
You can customize the appearance of the Gantt calendar using GanntStyleTheme:
GanttCalendar(
tasks: tasks,
styleTheme: GanntStyleTheme(
cellWidth: 60,
cellHeight: 40,
headerHeight: 50,
leftColumnWidth: 150,
taskBarHeight: 25,
gridLineColor: Colors.grey.shade300,
gridLineWidth: 1.0,
todayColumnColor: Colors.blue.shade50,
weekendColumnColor: Colors.grey.shade100,
headerBackgroundColor: Colors.blue.shade100,
taskBorderRadius: 8.0,
headerTextStyle: TextStyle(fontWeight: FontWeight.bold),
taskTextStyle: TextStyle(fontSize: 12, color: Colors.white),
),
)
Using a Controller
You can programmatically control the calendar using GanttCalendarController:
final controller = GanttCalendarController();
// In your build method
GanttCalendar(
tasks: tasks,
controller: controller,
)
// Later in your code, you can:
controller.nextMonth();
controller.previousMonth();
controller.jumpToDate(DateTime(2023, 6, 1));
controller.animateToDate(
DateTime(2023, 7, 1),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
Custom Builders
You can customize various parts of the calendar using builder functions:
GanttCalendar(
tasks: tasks,
// Custom header cell builder
headerCellBuilder: (context, date, isToday, isWeekend) {
return Container(
decoration: BoxDecoration(
color: isToday ? Colors.amber : (isWeekend ? Colors.grey.shade200 : Colors.white),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(DateFormat('E').format(date)),
Text(date.day.toString(), style: TextStyle(fontWeight: FontWeight.bold)),
],
),
);
},
// Custom task header cell builder
taskHeaderCellBuilder: (context, propertyName, isHeader) {
return Container(
padding: EdgeInsets.all(8),
color: isHeader ? Colors.blue.shade100 : Colors.white,
child: Text(
propertyName ?? '',
style: TextStyle(fontWeight: isHeader ? FontWeight.bold : FontWeight.normal),
),
);
},
// Custom task builder
taskBuilder: (context, task, width, isStartDate, isEndDate) {
return Container(
decoration: BoxDecoration(
color: task.color,
borderRadius: BorderRadius.horizontal(
left: isStartDate ? Radius.circular(8) : Radius.zero,
right: isEndDate ? Radius.circular(8) : Radius.zero,
),
),
child: Center(
child: Text(
task.assignedTo,
style: TextStyle(color: task.textColor, fontWeight: FontWeight.bold),
),
),
);
},
// Custom navigation builder
navigationBuilder: (context, currentDate, onPrevious, onNext) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(icon: Icon(Icons.arrow_back), onPressed: onPrevious),
Text(
DateFormat('MMMM yyyy').format(currentDate),
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
IconButton(icon: Icon(Icons.arrow_forward), onPressed: onNext),
],
);
},
)
Handling Task Taps
You can respond to task taps using the onTaskTap callback:
GanttCalendar(
tasks: tasks,
onTaskTap: (task) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(task.task),
content: Text('Assigned to: ${task.assignedTo}\n'
'From: ${DateFormat('MMM d, yyyy').format(task.startDate!)}\n'
'To: ${DateFormat('MMM d, yyyy').format(task.endDate!)}'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('Close'),
),
],
),
);
},
)
Additional information
Model Classes
- GanntTask: Represents a task in the Gantt chart with properties like start date, end date, color, assigned person, and task name.
- GanntStyleTheme: Contains styling properties for customizing the appearance of the Gantt calendar.
- GanttCalendarController: Provides methods to programmatically control the calendar.
Limitations
- The calendar is designed for day-level granularity, not for hour-level scheduling.
- For very large datasets (hundreds of tasks), consider implementing pagination or filtering.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.