Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import info.appdev.chartexample.compose.HorizontalBarComposeActivity
import info.appdev.chartexample.compose.HorizontalBarFullComposeActivity
import info.appdev.chartexample.compose.MultiLineComposeActivity
import info.appdev.chartexample.compose.TimeIntervalComposeActivity
import info.appdev.chartexample.fragments.ViewPagerSimpleChartDemo
import info.appdev.chartexample.notimportant.ContentItem
import info.appdev.chartexample.notimportant.DemoBase
Expand All @@ -42,6 +43,7 @@ import org.junit.Test
import org.junit.rules.TestName
import org.junit.runner.RunWith
import timber.log.Timber
import kotlin.jvm.java


@RunWith(AndroidJUnit4::class)
Expand Down Expand Up @@ -294,6 +296,7 @@ class StartTest {
contentItem.clazz == LineChartTimeActivity::class.java ||
contentItem.clazz == HorizontalBarComposeActivity::class.java ||
contentItem.clazz == HorizontalBarFullComposeActivity::class.java ||
contentItem.clazz == TimeIntervalComposeActivity::class.java ||
contentItem.clazz == MultiLineComposeActivity::class.java ||
contentItem.clazz == GradientActivity::class.java ||
// contentItem.clazz == TimeIntervalChartActivity::class.java ||
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<activity android:name="info.appdev.chartexample.SpecificPositionsLineChartActivity" />
<activity android:name="info.appdev.chartexample.TimeLineActivity" />
<activity android:name="info.appdev.chartexample.TimeIntervalChartActivity" />
<activity android:name="info.appdev.chartexample.compose.TimeIntervalComposeActivity" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package info.appdev.chartexample.compose

import android.graphics.Color
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import info.appdev.chartexample.notimportant.DemoBaseCompose
import info.appdev.charting.compose.GanttChart
import info.appdev.charting.data.GanttChartData
import info.appdev.charting.data.GanttTask

/**
* Demo activity showing Gantt-style timeline visualization using Compose.
*/
class TimeIntervalComposeActivity : DemoBaseCompose() {

// Full list of sample tasks
private val allTasks = listOf(
GanttTask("Design", 0f, 50f, Color.rgb(255, 107, 107)),
GanttTask("Dev", 40f, 100f, Color.rgb(66, 165, 245)),
GanttTask("Testing", 120f, 40f, Color.rgb(76, 175, 80), hatched = true),
GanttTask("Launch", 150f, 20f, Color.rgb(255, 193, 7)),
)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
GanttChartScreen(onViewGithub = { viewGithub() })
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun GanttChartScreen(onViewGithub: () -> Unit) {
var showMenu by remember { mutableStateOf(false) }
// X: controls visible max time (range 50–300)
var seekBarXValue by remember { mutableFloatStateOf(190f) }
// Y: controls how many tasks are shown (1–allTasks.size)
var seekBarYValue by remember { mutableFloatStateOf(allTasks.size.toFloat()) }

Scaffold(
topBar = {
TopAppBar(
title = { Text("TimeIntervalChart") },
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primary,
titleContentColor = MaterialTheme.colorScheme.onPrimary
),
actions = {
Box {
IconButton(
onClick = { showMenu = true },
modifier = Modifier.testTag("menuButton")
) {
Icon(
Icons.Default.MoreVert,
contentDescription = "Menu",
tint = MaterialTheme.colorScheme.onPrimary
)
}
DropdownMenu(
expanded = showMenu,
onDismissRequest = { showMenu = false },
modifier = Modifier.testTag("dropdownMenu")
) {
DropdownMenuItem(
text = { Text("View on GitHub") },
onClick = { showMenu = false; onViewGithub() },
modifier = Modifier.testTag("menuItem_View on GitHub")
)
}
}
}
)
}
) { paddingValues ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.background(androidx.compose.ui.graphics.Color.White)
) {
val ganttData = remember(seekBarXValue, seekBarYValue) {
val maxTime = seekBarXValue
val taskCount = seekBarYValue.toInt().coerceAtLeast(1)
GanttChartData().apply {
allTasks.take(taskCount).forEach { addTask(it) }
minTime = 0f
this.maxTime = maxTime
}
}

GanttChart(
data = ganttData,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
)

// SeekBar X – controls visible time range
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "X:",
modifier = Modifier.padding(end = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
Slider(
value = seekBarXValue,
onValueChange = { seekBarXValue = it },
valueRange = 1f..200f,
modifier = Modifier.weight(1f)
)
Text(
text = seekBarXValue.toInt().toString(),
modifier = Modifier.padding(start = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
}

// SeekBar Y – controls number of tasks shown
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "Y:",
modifier = Modifier.padding(end = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
Slider(
value = seekBarYValue,
onValueChange = { seekBarYValue = it },
valueRange = 1f..allTasks.size.toFloat(),
steps = allTasks.size - 2,
modifier = Modifier.weight(1f)
)
Text(
text = seekBarYValue.toInt().toString(),
modifier = Modifier.padding(start = 8.dp),
style = MaterialTheme.typography.bodyMedium
)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import info.appdev.chartexample.TimeLineActivity
import info.appdev.chartexample.compose.HorizontalBarComposeActivity
import info.appdev.chartexample.compose.HorizontalBarFullComposeActivity
import info.appdev.chartexample.compose.MultiLineComposeActivity
import info.appdev.chartexample.compose.TimeIntervalComposeActivity
import info.appdev.chartexample.fragments.ViewPagerSimpleChartDemo
import info.appdev.charting.utils.Utils
import info.appdev.charting.utils.initUtils
Expand Down Expand Up @@ -217,10 +218,13 @@ class MainActivity : ComponentActivity() {
add(ComposeItem("HorizontalFullCompose", "Render bar chart horizontally full compose.", HorizontalBarFullComposeActivity::class.java).toDemoBase())
add(ComposeItem("MultiLineCompose", "Show multiple data sets in compose.", MultiLineComposeActivity::class.java).toDemoBase())

add(ContentItem("Timeinterval"))
add(ContentItem("Timeinterval", "Grantt chart", TimeIntervalChartActivity::class.java))
add(ComposeItem("Timeinterval compose", "Grantt chart compose", TimeIntervalComposeActivity::class.java).toDemoBase())

add(ContentItem("Demonstrate and fix issues"))
add(ContentItem("Gradient", "Show a gradient edge case", GradientActivity::class.java))
add(ContentItem("Timeline", "Show a time line with Unix timestamp", TimeLineActivity::class.java))
add(ContentItem("Timeinterval", "Grantt chart", TimeIntervalChartActivity::class.java))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package info.appdev.charting.compose

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import info.appdev.charting.charts.GanttChart
import info.appdev.charting.data.GanttChartData

/**
* A Composable wrapper for [GanttChart].
*
* @param data The Gantt chart data to display
* @param modifier The modifier to be applied to the chart
*/
@Composable
fun GanttChart(
data: GanttChartData?,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current

val chart = remember { GanttChart(context) }

AndroidView(
factory = { chart },
modifier = modifier.fillMaxSize(),
update = { ganttChart ->
ganttChart.setData(data)
}
)
}

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading