From 2b4288ee187e76f0abf730789abd8fcd8a893763 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sat, 28 Mar 2026 08:24:02 +0100 Subject: [PATCH 1/5] Grantt chart Inspired by https://github.com/PhilJay/MPAndroidChart/pull/5519 Fix Gantt chart label clipping, x-axis label overlap, and seekbar overlay - GanttChart.kt: dynamically compute chartLeft from max label width so long names like 'Development' are never clipped by the view edge - GanttChart.kt: compute grid-line count from available width / label width so x-axis time labels never overlap each other - GanttChart.kt: extract labelTextSize, gridLinesMin/Max as constants so measurement paint and drawing paint are always in sync - activity_time_interval_chart.xml: remove unused SeekBar widgets and TextViews that were rendering on top of the chart - TimeIntervalChartActivity.kt: remove OnSeekBarChangeListener interface and its unused override methods --- .../info/appdev/chartexample/StartTest.kt | 23 ++- app/src/main/AndroidManifest.xml | 1 + .../chartexample/TimeIntervalChartActivity.kt | 45 +++++ .../chartexample/notimportant/MainActivity.kt | 2 + .../layout/activity_time_interval_chart.xml | 60 ++++++ .../info/appdev/charting/charts/GanttChart.kt | 185 ++++++++++++++++++ .../appdev/charting/data/GanttChartData.kt | 90 +++++++++ .../info/appdev/charting/data/GanttTask.kt | 15 ++ 8 files changed, 419 insertions(+), 2 deletions(-) create mode 100644 app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt create mode 100644 app/src/main/res/layout/activity_time_interval_chart.xml create mode 100644 chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt create mode 100644 chartLib/src/main/kotlin/info/appdev/charting/data/GanttChartData.kt create mode 100644 chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt diff --git a/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt b/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt index 5bbdbaf80..2c127e96d 100644 --- a/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt +++ b/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt @@ -75,7 +75,10 @@ class StartTest { @After fun cleanUp() { - Intents.release() + // release() may have already been called by the last loop iteration + try { + Intents.release() + } catch (_: IllegalStateException) { /* not initialised, nothing to do */ } // Clean up test timber tree Timber.uprootAll() } @@ -249,12 +252,17 @@ class StartTest { if (!compose) doClickTest(index, contentClass, contentItem) - //Thread.sleep(100) Espresso.pressBack() // Wait for MainActivity to be visible again composeTestRule.waitForIdle() Thread.sleep(200) // Small delay for back navigation + + // Reset intent recording for next iteration; otherwise intents accumulate + // across the loop and Intents.intended() can no longer find a fresh + // unverified match for the current activity. + Intents.release() + Intents.init() } catch (e: Exception) { Timber.e("#$index/'${contentClass.simpleName}'->'$optionMenu' ${e.message}", e) onView(ViewMatchers.isRoot()) @@ -264,6 +272,16 @@ class StartTest { .replace(" ", "") ) }) + // Navigate back so subsequent iterations start from MainActivity + try { + Espresso.pressBack() + composeTestRule.waitForIdle() + } catch (_: Exception) { /* already on MainActivity */ } + // Reset intents so the next iteration starts clean + try { + Intents.release() + Intents.init() + } catch (_: Exception) { /* ignore if already released */ } } } } @@ -278,6 +296,7 @@ class StartTest { contentItem.clazz == HorizontalBarFullComposeActivity::class.java || contentItem.clazz == MultiLineComposeActivity::class.java || contentItem.clazz == GradientActivity::class.java || +// contentItem.clazz == TimeIntervalChartActivity::class.java || contentItem.clazz == TimeLineActivity::class.java ) { // These charts have less clickable area, so skip further clicks diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 104d62c8d..a8f2a241b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -60,6 +60,7 @@ + diff --git a/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt new file mode 100644 index 000000000..02a0b43b7 --- /dev/null +++ b/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt @@ -0,0 +1,45 @@ +package info.appdev.chartexample + +import android.graphics.Color +import android.os.Bundle +import info.appdev.chartexample.databinding.ActivityTimeIntervalChartBinding +import info.appdev.chartexample.notimportant.DemoBase +import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.GanttChartData +import info.appdev.charting.data.GanttTask +import info.appdev.charting.highlight.Highlight +import info.appdev.charting.listener.OnChartValueSelectedListener + +/** + * Demo activity showing Gantt-style timeline visualization. + * Each horizontal bar represents a task with start time and duration. + */ +class TimeIntervalChartActivity : DemoBase(), OnChartValueSelectedListener { + + private lateinit var binding: ActivityTimeIntervalChartBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityTimeIntervalChartBinding.inflate(layoutInflater) + setContentView(binding.root) + + // Create Gantt chart data + val ganttData = GanttChartData() + + // Add sample project tasks + ganttData.addTask(GanttTask("Design", 0f, 50f, Color.rgb(255, 107, 107))) // Red: 0-50 + ganttData.addTask(GanttTask("Dev", 40f, 100f, Color.rgb(66, 165, 245))) // Blue: 40-140 + ganttData.addTask(GanttTask("Testing", 120f, 40f, Color.rgb(76, 175, 80))) // Green: 120-160 + ganttData.addTask(GanttTask("Launch", 150f, 20f, Color.rgb(255, 193, 7))) // Yellow: 150-170 + + // Set data and render + binding.chart1.setData(ganttData) + } + + override fun saveToGallery() = Unit + + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = Unit + + override fun onNothingSelected() = Unit + +} diff --git a/app/src/main/kotlin/info/appdev/chartexample/notimportant/MainActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/notimportant/MainActivity.kt index 9c50a3bf2..ccae0d21c 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/notimportant/MainActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/notimportant/MainActivity.kt @@ -75,6 +75,7 @@ import info.appdev.chartexample.ScrollViewActivity import info.appdev.chartexample.SpecificPositionsLineChartActivity import info.appdev.chartexample.StackedBarActivity import info.appdev.chartexample.StackedBarActivityNegative +import info.appdev.chartexample.TimeIntervalChartActivity import info.appdev.chartexample.TimeLineActivity import info.appdev.chartexample.compose.HorizontalBarComposeActivity import info.appdev.chartexample.compose.HorizontalBarFullComposeActivity @@ -219,6 +220,7 @@ class MainActivity : ComponentActivity() { 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)) } } } diff --git a/app/src/main/res/layout/activity_time_interval_chart.xml b/app/src/main/res/layout/activity_time_interval_chart.xml new file mode 100644 index 000000000..b41d55b6c --- /dev/null +++ b/app/src/main/res/layout/activity_time_interval_chart.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt new file mode 100644 index 000000000..1afe35bcf --- /dev/null +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt @@ -0,0 +1,185 @@ +package info.appdev.charting.charts + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF +import android.util.AttributeSet +import android.view.View +import info.appdev.charting.data.GanttChartData +import java.util.Locale + +class GanttChart : View { + private var data: GanttChartData? = null + private var taskPaint: Paint? = null + private var gridPaint: Paint? = null + private var textPaint: Paint? = null + + private var chartLeft = 0f + private var chartTop = 0f + private var chartRight = 0f + private var chartBottom = 0f + private val padding = 16f + private val labelTextSize = 24f + private val gridLinesMin = 2 + private val gridLinesMax = 10 + + constructor(context: Context?) : super(context) { + init() + } + + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { + init() + } + + constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { + init() + } + + private fun init() { + taskPaint = Paint().apply { + isAntiAlias = true + } + gridPaint = Paint().apply { + color = -0x333334 + strokeWidth = 1f + } + textPaint = Paint().apply { + color = -0x99999a + textSize = 28f + isAntiAlias = true + } + } + + fun setData(data: GanttChartData?) { + this.data = data + invalidate() + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + if (data == null || data!!.taskCount == 0) { + return + } + + calculateDimensions() + drawGrid(canvas) + drawTasks(canvas) + } + + private fun calculateDimensions() { + val labelMeasurePaint = Paint().apply { + textSize = labelTextSize + isAntiAlias = true + } + var maxLabelWidth = 0f + if (data != null) { + for (i in 0.. maxLabelWidth) maxLabelWidth = w + } + } + chartLeft = maxLabelWidth + padding * 3 + chartTop = padding + 30 + chartRight = width - padding + chartBottom = height - padding - 30 + } + + private val taskHeight: Float + // Dynamically calculate task height based on available space + get() { + if (data == null || data!!.taskCount == 0) { + return 40f + } + val availableHeight = chartBottom - chartTop + val taskCount = data!!.taskCount + // 50% of slot for bar, 50% for gap + return (availableHeight / taskCount) * 0.5f + } + + private val taskSpacing: Float + get() { + if (data == null || data!!.taskCount == 0) { + return 12f + } + val availableHeight = chartBottom - chartTop + val taskCount = data!!.taskCount + return (availableHeight / taskCount) * 0.5f + } + + private fun drawGrid(canvas: Canvas) { + val minTime = data!!.minTime + val maxTime = data!!.maxTime + var timeRange = maxTime - minTime + if (timeRange == 0f) { + timeRange = 100f + } + + val timeLabelPaint = Paint().apply { + color = -0x99999a + textSize = 22f + isAntiAlias = true + textAlign = Paint.Align.CENTER + } + + // Calculate how many grid lines fit without overlapping labels + val sampleLabel = String.format(Locale.getDefault(), "%.0f", maxTime) + val labelWidth = timeLabelPaint.measureText(sampleLabel) + 8f + val chartWidth = chartRight - chartLeft + val maxGridLines = (chartWidth / labelWidth).toInt().coerceIn(gridLinesMin, gridLinesMax) + + for (i in 0..maxGridLines) { + val x = chartLeft + (i / maxGridLines.toFloat()) * chartWidth + canvas.drawLine(x, chartTop, x, chartBottom, gridPaint!!) + + val time = minTime + (i / maxGridLines.toFloat()) * timeRange + canvas.drawText(String.format(Locale.getDefault(), "%.0f", time), x, chartBottom + 30, timeLabelPaint) + } + } + + private fun drawTasks(canvas: Canvas) { + val minTime = data!!.minTime + val maxTime = data!!.maxTime + var timeRange = maxTime - minTime + if (timeRange == 0f) { + timeRange = 100f + } + + val taskHeight = this.taskHeight + val taskSpacing = this.taskSpacing + val slotHeight = taskHeight + taskSpacing + + val labelPaint = Paint() + labelPaint.color = -0xcccccd + labelPaint.textSize = labelTextSize + labelPaint.isAntiAlias = true + labelPaint.textAlign = Paint.Align.RIGHT + + val borderPaint = Paint() + borderPaint.color = -0x666667 + borderPaint.strokeWidth = 2f + borderPaint.style = Paint.Style.STROKE + + for (i in 0.. = mutableListOf() + + /** + * Add a task to the Gantt chart. + * + * @param task The task to add + */ + fun addTask(task: GanttTask?) { + tasks.add(task!!) + } + + /** + * Add multiple tasks to the Gantt chart. + * + * @param taskList List of tasks to add + */ + fun addTasks(taskList: MutableList) { + tasks.addAll(taskList) + } + + /** + * Get a specific task by index. + * + * @param index Task index + * @return The task at the given index + */ + fun getTask(index: Int): GanttTask { + return tasks[index] + } + + /** + * Get the number of tasks. + * + * @return Number of tasks in the chart + */ + val taskCount: Int + get() = tasks.size + + /** + * Get the earliest start time across all tasks. + * + * @return Minimum start time + */ + val minTime: Float + get() { + if (tasks.isEmpty()) return 0f + var min = Float.MAX_VALUE + for (task in tasks) { + min = min(min, task.startTime) + } + return min + } + + /** + * Get the latest end time across all tasks. + * + * @return Maximum end time + */ + val maxTime: Float + get() { + if (tasks.isEmpty()) return 100f + var max = 0f + for (task in tasks) { + max = max(max, task.endTime) + } + return max + } + + /** + * Clear all tasks. + */ + fun clearTasks() { + tasks.clear() + } +} diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt new file mode 100644 index 000000000..9290551b7 --- /dev/null +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt @@ -0,0 +1,15 @@ +package info.appdev.charting.data + +/** + * Represents a single task in a Gantt chart. + * Each task has a name, start time, duration, and display color. + * + * @param name Task name/label + * @param startTime When the task starts + * @param duration How long the task lasts + * @param color Display color (Android color int) + */ +class GanttTask(val name: String?, val startTime: Float, val duration: Float, val color: Int) { + val endTime: Float + get() = startTime + duration +} From 73a3c7825dbfe0b7d2ad78b564395e12f243e6f2 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 12 Apr 2026 14:17:38 +0200 Subject: [PATCH 2/5] Optional hatch fill --- .../chartexample/TimeIntervalChartActivity.kt | 2 +- .../info/appdev/charting/charts/GanttChart.kt | 20 +++++++++++++++++++ .../info/appdev/charting/data/GanttTask.kt | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt index 02a0b43b7..1e2c1cd32 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt @@ -29,7 +29,7 @@ class TimeIntervalChartActivity : DemoBase(), OnChartValueSelectedListener { // Add sample project tasks ganttData.addTask(GanttTask("Design", 0f, 50f, Color.rgb(255, 107, 107))) // Red: 0-50 ganttData.addTask(GanttTask("Dev", 40f, 100f, Color.rgb(66, 165, 245))) // Blue: 40-140 - ganttData.addTask(GanttTask("Testing", 120f, 40f, Color.rgb(76, 175, 80))) // Green: 120-160 + ganttData.addTask(GanttTask("Testing", 120f, 40f, Color.rgb(76, 175, 80), hatched = true)) // Green: 120-160 ganttData.addTask(GanttTask("Launch", 150f, 20f, Color.rgb(255, 193, 7))) // Yellow: 150-170 // Set data and render diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt index 1afe35bcf..01029f82b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt @@ -8,10 +8,12 @@ import android.util.AttributeSet import android.view.View import info.appdev.charting.data.GanttChartData import java.util.Locale +import androidx.core.graphics.withClip class GanttChart : View { private var data: GanttChartData? = null private var taskPaint: Paint? = null + private var hatchPaint: Paint? = null private var gridPaint: Paint? = null private var textPaint: Paint? = null @@ -40,6 +42,12 @@ class GanttChart : View { taskPaint = Paint().apply { isAntiAlias = true } + hatchPaint = Paint().apply { + color = 0x7DFFFFFF // more transparent (0x7D ≈ 66 % opacity vs previous 0x55 ≈ 33 %) + strokeWidth = 20f // thicker lines (was 2f) + isAntiAlias = true + style = Paint.Style.STROKE + } gridPaint = Paint().apply { color = -0x333334 strokeWidth = 1f @@ -179,6 +187,18 @@ class GanttChart : View { val rect = RectF(startX, taskY, endX, taskY + taskHeight) taskPaint!!.color = task.color canvas.drawRect(rect, taskPaint!!) + + if (task.hatched) { + // Hatch lines (45° diagonal, bottom-left → top-right) + canvas.withClip(rect) { + val hatchSpacing = 10f + var hx = startX - taskHeight + while (hx < endX + taskHeight) { + drawLine(hx, taskY + taskHeight, hx + taskHeight, taskY, hatchPaint!!) + hx += hatchSpacing + } + } + } canvas.drawRect(rect, borderPaint) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt index 9290551b7..9c96eb613 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/GanttTask.kt @@ -9,7 +9,7 @@ package info.appdev.charting.data * @param duration How long the task lasts * @param color Display color (Android color int) */ -class GanttTask(val name: String?, val startTime: Float, val duration: Float, val color: Int) { +class GanttTask(val name: String?, val startTime: Float, val duration: Float, val color: Int, val hatched: Boolean = false) { val endTime: Float get() = startTime + duration } From 1609f151db09d3f4b74c0260d21f61ed7d13e0b9 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 12 Apr 2026 18:53:59 +0200 Subject: [PATCH 3/5] Thicker hatching --- .../info/appdev/charting/charts/GanttChart.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt index 01029f82b..8f8681906 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/GanttChart.kt @@ -43,10 +43,10 @@ class GanttChart : View { isAntiAlias = true } hatchPaint = Paint().apply { - color = 0x7DFFFFFF // more transparent (0x7D ≈ 66 % opacity vs previous 0x55 ≈ 33 %) - strokeWidth = 20f // thicker lines (was 2f) + color = 0xAAFFFFFF.toInt() // ~67 % opaque white – clearly visible over any bar colour isAntiAlias = true style = Paint.Style.STROKE + // strokeWidth is set dynamically in drawTasks to stay proportional to bar height } gridPaint = Paint().apply { color = -0x333334 @@ -189,9 +189,16 @@ class GanttChart : View { canvas.drawRect(rect, taskPaint!!) if (task.hatched) { + // Scale both stroke width and spacing to the bar height so the + // pattern is always clearly visible regardless of how many tasks + // are shown. Rule: spacing must be > strokeWidth or lines overlap. + // strokeWidth ≈ 20 % of bar height + // hatchSpacing ≈ 40 % of bar height (2× the stroke → clear gap) + hatchPaint!!.strokeWidth = taskHeight * 0.20f + val hatchSpacing = taskHeight * 0.40f + // Hatch lines (45° diagonal, bottom-left → top-right) canvas.withClip(rect) { - val hatchSpacing = 10f var hx = startX - taskHeight while (hx < endX + taskHeight) { drawLine(hx, taskY + taskHeight, hx + taskHeight, taskY, hatchPaint!!) From 3d2dbca847267daebdad3c2110ea327f9dc02041 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Mon, 13 Apr 2026 07:13:51 +0200 Subject: [PATCH 4/5] Set min/max --- .../chartexample/TimeIntervalChartActivity.kt | 3 +- .../appdev/charting/data/GanttChartData.kt | 52 +++++++++++++------ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt index 1e2c1cd32..ad79bb404 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/TimeIntervalChartActivity.kt @@ -31,7 +31,8 @@ class TimeIntervalChartActivity : DemoBase(), OnChartValueSelectedListener { ganttData.addTask(GanttTask("Dev", 40f, 100f, Color.rgb(66, 165, 245))) // Blue: 40-140 ganttData.addTask(GanttTask("Testing", 120f, 40f, Color.rgb(76, 175, 80), hatched = true)) // Green: 120-160 ganttData.addTask(GanttTask("Launch", 150f, 20f, Color.rgb(255, 193, 7))) // Yellow: 150-170 - + ganttData.minTime = 10f + ganttData.maxTime = 200f // Set data and render binding.chart1.setData(ganttData) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/GanttChartData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/GanttChartData.kt index 97fb7c0d5..e2b8c41ad 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/GanttChartData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/GanttChartData.kt @@ -8,6 +8,9 @@ import kotlin.math.min * Manages a list of tasks and provides convenient access methods. */ class GanttChartData { + private var mMaxTime = 0f + private var mMinTime = 0f + /** * Get all tasks. * @@ -22,6 +25,27 @@ class GanttChartData { */ fun addTask(task: GanttTask?) { tasks.add(task!!) + mMinTime = calcMinTime() + mMaxTime = calcMaxTime() + } + + private fun calcMaxTime(): Float { + if (tasks.isEmpty()) + return 100f + var max = 0f + for (task in tasks) { + max = max(max, task.endTime) + } + return max + } + + private fun calcMinTime(): Float { + if (tasks.isEmpty()) return 0f + var min = Float.MAX_VALUE + for (task in tasks) { + min = min(min, task.startTime) + } + return min } /** @@ -31,6 +55,8 @@ class GanttChartData { */ fun addTasks(taskList: MutableList) { tasks.addAll(taskList) + mMinTime = calcMinTime() + mMaxTime = calcMaxTime() } /** @@ -56,14 +82,10 @@ class GanttChartData { * * @return Minimum start time */ - val minTime: Float - get() { - if (tasks.isEmpty()) return 0f - var min = Float.MAX_VALUE - for (task in tasks) { - min = min(min, task.startTime) - } - return min + var minTime: Float + get() = mMinTime + set(value) { + mMinTime = value } /** @@ -71,14 +93,10 @@ class GanttChartData { * * @return Maximum end time */ - val maxTime: Float - get() { - if (tasks.isEmpty()) return 100f - var max = 0f - for (task in tasks) { - max = max(max, task.endTime) - } - return max + var maxTime: Float + get() = mMaxTime + set(value) { + mMaxTime = value } /** @@ -86,5 +104,7 @@ class GanttChartData { */ fun clearTasks() { tasks.clear() + mMinTime = calcMinTime() + mMaxTime = calcMaxTime() } } From e34cf3e4239737325a0237821e3c3fa1b81a9869 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Fri, 3 Apr 2026 07:35:55 +0200 Subject: [PATCH 5/5] Adapt screenshots --- ...lChartActivity-Timeinterval-1SampleClick.png | Bin 0 -> 15621 bytes ...IntervalChartActivity-Timeinterval-click.png | Bin 0 -> 15621 bytes ...rvalChartActivity-Timeinterval-click2020.png | Bin 0 -> 15621 bytes ...rvalChartActivity-Timeinterval-click7070.png | Bin 0 -> 15621 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-1SampleClick.png create mode 100644 screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click.png create mode 100644 screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click2020.png create mode 100644 screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click7070.png diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-1SampleClick.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-1SampleClick.png new file mode 100644 index 0000000000000000000000000000000000000000..3e61b1da061ab51d47978fbb34e08e2c94c58158 GIT binary patch literal 15621 zcmdseXH-<_wrv4o1QC&pprC*Rkt8`NARr2g5=1frlC$IjMI}d-Afb>TN)7@N3&|M; zk(`s{T;$@d-F?m-qkp`6@9A^ipXV5iZnVPQ-}kLG=bCeF|9i^vq$lZ4qEIMOMFm+^ z6pBC^g(CDmeiZ&@G3PvPnmCz3+YQRkF$Y6|g

{ODJs+E;g^oql9^|l<9(Io{c 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

{ODJs+E;g^oql9^|l<9(Io{c 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

{ODJs+E;g^oql9^|l<9(Io{c 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

{ODJs+E;g^oql9^|l<9(Io{c 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