Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions GANTT_CHART.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Gantt Chart Feature

A native Gantt chart implementation for MPAndroidChart that visualizes tasks as horizontal bars positioned by time intervals.

## Features

- **Time-based positioning** - Tasks positioned by start time and duration
- **Responsive layout** - Automatically scales to fit any number of tasks
- **Customizable colors** - Each task can have its own color
- **Grid lines** - Time scale visualization with grid lines and labels
- **Clean design** - Professional appearance with task labels and borders

## Usage

### 1. Add to your layout XML

```xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.github.mikephil.charting.charts.GanttChart
android:id="@+id/ganttChart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>
```

### 2. Create your Activity

```java
package com.example.myapp;

import android.graphics.Color;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.github.mikephil.charting.charts.GanttChart;
import com.github.mikephil.charting.data.GanttChartData;
import com.github.mikephil.charting.data.GanttTask;

public class GanttChartActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gantt_chart);

GanttChart chart = findViewById(R.id.ganttChart);

// Create Gantt chart data
GanttChartData ganttData = new GanttChartData();

// Add tasks (name, startTime, duration, color)
ganttData.addTask(new GanttTask("Design", 0, 30, Color.rgb(255, 107, 107)));
ganttData.addTask(new GanttTask("Development", 20, 40, Color.rgb(66, 165, 245)));
ganttData.addTask(new GanttTask("Testing", 50, 20, Color.rgb(76, 175, 80)));
ganttData.addTask(new GanttTask("Deployment", 65, 15, Color.rgb(255, 193, 7)));

// Set data and render
chart.setData(ganttData);
}
}
```

## API Reference

### GanttTask

Represents a single task in the Gantt chart.

```java
GanttTask task = new GanttTask(
"Task Name", // String: display name
0, // float: start time
50, // float: duration
Color.BLUE // int: task color
);
```

**Methods:**
- `getName()` - Get task name
- `getStartTime()` - Get start time
- `getDuration()` - Get task duration
- `getEndTime()` - Get end time (startTime + duration)
- `getColor()` - Get task color

### GanttChartData

Container for managing tasks.

```java
GanttChartData data = new GanttChartData();
data.addTask(task1);
data.addTask(task2);
data.clearTasks();
```

**Methods:**
- `addTask(GanttTask)` - Add a single task
- `addTasks(List<GanttTask>)` - Add multiple tasks
- `getTasks()` - Get all tasks
- `getTaskCount()` - Get number of tasks
- `getMinTime()` - Get earliest start time
- `getMaxTime()` - Get latest end time
- `clearTasks()` - Remove all tasks

### GanttChart

Custom View that renders the Gantt chart.

```java
GanttChart chart = findViewById(R.id.ganttChart);
chart.setData(ganttData);
```

**Methods:**
- `setData(GanttChartData)` - Set chart data and trigger redraw

## Example Use Cases

- **Project Management** - Visualize project timeline and tasks
- **Resource Allocation** - Show resource usage over time
- **Production Scheduling** - Display manufacturing timeline
- **Event Planning** - Timeline visualization for events

## Tips

- Use consistent time units (hours, days, weeks) across all tasks
- Ensure start times and durations use the same scale
- Keep task names reasonably short for better display
- Use contrasting colors for task visibility

## Customization

The chart automatically scales to fit your screen size and number of tasks. All styling parameters are calculated dynamically based on:
- Available screen space
- Number of tasks
- Time range of tasks

For visual customization, modify the `GanttChart` class directly:
- Adjust padding in `calculateDimensions()`
- Change grid line color/style in `drawGrid()`
- Modify task bar appearance in `drawTasks()`
4 changes: 4 additions & 0 deletions MPChartExample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

lintOptions {
abortOnError false
}
}

dependencies {
Expand Down
70 changes: 36 additions & 34 deletions MPChartExample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,48 @@
android:theme="@style/AppTheme">
<activity
android:name="com.xxmassdeveloper.mpchartexample.notimportant.MainActivity"
android:label="@string/app_name" >
android:label="@string/app_name"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="LineChartActivity1" />
<activity android:name="LineChartActivity2" />
<activity android:name="LineChartTime" />
<activity android:name="BarChartActivity" />
<activity android:name="HorizontalBarChartActivity" />
<activity android:name="HorizontalBarNegativeChartActivity" />
<activity android:name="PieChartActivity" />
<activity android:name="PiePolylineChartActivity" />
<activity android:name="MultiLineChartActivity" />
<activity android:name="BarChartActivityMultiDataset" />
<activity android:name="DrawChartActivity" />
<activity android:name="ScatterChartActivity" />
<activity android:name="BubbleChartActivity" />
<activity android:name=".fragments.SimpleChartDemo" />
<activity android:name="ListViewBarChartActivity" />
<activity android:name="ListViewMultiChartActivity" />
<activity android:name="StackedBarActivity" />
<activity android:name="AnotherBarActivity" />
<activity android:name="InvertedLineChartActivity" />
<activity android:name="CandleStickChartActivity" />
<activity android:name="CubicLineChartActivity" />
<activity android:name="RadarChartActivity" />
<activity android:name="LineChartActivityColored" />
<activity android:name="DynamicalAddingActivity" />
<activity android:name="RealtimeLineChartActivity" />
<activity android:name="CombinedChartActivity" />
<activity android:name="PerformanceLineChart" />
<activity android:name="BarChartActivitySinus" />
<activity android:name="ScrollViewActivity" />
<activity android:name="StackedBarActivityNegative" />
<activity android:name="BarChartPositiveNegative" />
<activity android:name="FilledLineActivity" />
<activity android:name="HalfPieChartActivity" />
<activity android:name="LineChartActivity1" android:exported="false" />
<activity android:name="LineChartActivity2" android:exported="false" />
<activity android:name="LineChartTime" android:exported="false" />
<activity android:name="BarChartActivity" android:exported="false" />
<activity android:name="HorizontalBarChartActivity" android:exported="false" />
<activity android:name="HorizontalBarNegativeChartActivity" android:exported="false" />
<activity android:name="PieChartActivity" android:exported="false" />
<activity android:name="PiePolylineChartActivity" android:exported="false" />
<activity android:name="MultiLineChartActivity" android:exported="false" />
<activity android:name="BarChartActivityMultiDataset" android:exported="false" />
<activity android:name="DrawChartActivity" android:exported="false" />
<activity android:name="ScatterChartActivity" android:exported="false" />
<activity android:name="BubbleChartActivity" android:exported="false" />
<activity android:name=".fragments.SimpleChartDemo" android:exported="false" />
<activity android:name="ListViewBarChartActivity" android:exported="false" />
<activity android:name="ListViewMultiChartActivity" android:exported="false" />
<activity android:name="StackedBarActivity" android:exported="false" />
<activity android:name="AnotherBarActivity" android:exported="false" />
<activity android:name="InvertedLineChartActivity" android:exported="false" />
<activity android:name="CandleStickChartActivity" android:exported="false" />
<activity android:name="CubicLineChartActivity" android:exported="false" />
<activity android:name="RadarChartActivity" android:exported="false" />
<activity android:name="LineChartActivityColored" android:exported="false" />
<activity android:name="DynamicalAddingActivity" android:exported="false" />
<activity android:name="RealtimeLineChartActivity" android:exported="false" />
<activity android:name="CombinedChartActivity" android:exported="false" />
<activity android:name="PerformanceLineChart" android:exported="false" />
<activity android:name="BarChartActivitySinus" android:exported="false" />
<activity android:name="ScrollViewActivity" android:exported="false" />
<activity android:name="StackedBarActivityNegative" android:exported="false" />
<activity android:name="BarChartPositiveNegative" android:exported="false" />
<activity android:name="FilledLineActivity" android:exported="false" />
<activity android:name="HalfPieChartActivity" android:exported="false" />
<activity android:name="com.xxmassdeveloper.chartdemo.TimeIntervalChartActivity" android:exported="false" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.xxmassdeveloper.chartdemo;

import android.graphics.Color;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import com.github.mikephil.charting.charts.GanttChart;
import com.github.mikephil.charting.data.GanttChartData;
import com.github.mikephil.charting.data.GanttTask;
import com.xxmassdeveloper.mpchartexample.R;

/**
* Demo activity showing Gantt-style timeline visualization.
* Each horizontal bar represents a task with start time and duration.
*/
public class TimeIntervalChartActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time_interval_chart);

GanttChart chart = findViewById(R.id.chart);

// Create Gantt chart data
GanttChartData ganttData = new GanttChartData();

// Add sample project tasks
ganttData.addTask(new GanttTask("Design", 0, 50, Color.rgb(255, 107, 107))); // Red: 0-50
ganttData.addTask(new GanttTask("Development", 40, 100, Color.rgb(66, 165, 245))); // Blue: 40-140
ganttData.addTask(new GanttTask("Testing", 120, 40, Color.rgb(76, 175, 80))); // Green: 120-160
ganttData.addTask(new GanttTask("Launch", 150, 20, Color.rgb(255, 193, 7))); // Yellow: 150-170

// Set data and render
chart.setData(ganttData);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.github.mikephil.charting.charts.GanttChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</RelativeLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public void feed(IBarDataSet data) {

float bottom = x - barWidthHalf;
float top = x + barWidthHalf;
float left, right;
float left;
float right;
if (mInverted) {
left = y >= 0 ? y : 0;
right = y <= 0 ? y : 0;
Expand All @@ -52,12 +53,12 @@ public void feed(IBarDataSet data) {

float posY = 0f;
float negY = -e.getNegativeSum();
float yStart = 0f;

// fill the stack
for (int k = 0; k < vals.length; k++) {

float value = vals[k];
float yStart;

if (value >= 0f) {
y = posY;
Expand All @@ -71,7 +72,8 @@ public void feed(IBarDataSet data) {

float bottom = x - barWidthHalf;
float top = x + barWidthHalf;
float left, right;
float left;
float right;
if (mInverted) {
left = y >= yStart ? y : yStart;
right = y <= yStart ? y : yStart;
Expand Down
Loading