diff --git a/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt b/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt
index 5bbdbaf80..b667f4fbb 100644
--- a/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt
+++ b/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt
@@ -42,6 +42,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)
@@ -278,6 +279,7 @@ class StartTest {
contentItem.clazz == HorizontalBarFullComposeActivity::class.java ||
contentItem.clazz == MultiLineComposeActivity::class.java ||
contentItem.clazz == GradientActivity::class.java ||
+ contentItem.clazz == TimeBarActivity::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..96654d69d 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/TimeBarActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/TimeBarActivity.kt
new file mode 100644
index 000000000..e9525b1cf
--- /dev/null
+++ b/app/src/main/kotlin/info/appdev/chartexample/TimeBarActivity.kt
@@ -0,0 +1,251 @@
+package info.appdev.chartexample
+
+import android.Manifest
+import android.R.attr.entries
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.graphics.Color
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
+import android.widget.SeekBar
+import android.widget.SeekBar.OnSeekBarChangeListener
+import androidx.core.content.ContextCompat
+import androidx.core.content.res.ResourcesCompat
+import androidx.core.net.toUri
+import info.appdev.chartexample.DataTools.Companion.getValues
+import info.appdev.chartexample.TimeLineActivity.Companion.TIME_OFFSET
+import info.appdev.chartexample.databinding.ActivityHorizontalbarchartBinding
+import info.appdev.chartexample.formatter.TimeRangeValueFormatter
+import info.appdev.chartexample.formatter.UnixTimeAxisValueFormatter
+import info.appdev.chartexample.formatter.UnixTimeRelative2NowAxisValueFormatter
+import info.appdev.chartexample.formatter.UnixTimeValueFormatter
+import info.appdev.chartexample.notimportant.DemoBase
+import info.appdev.charting.components.Description
+import info.appdev.charting.components.Legend
+import info.appdev.charting.components.XAxis.XAxisPosition
+import info.appdev.charting.data.BarData
+import info.appdev.charting.data.BarDataSet
+import info.appdev.charting.data.BarEntryDouble
+import info.appdev.charting.data.BarEntryFloat
+import info.appdev.charting.interfaces.datasets.IBarDataSet
+import timber.log.Timber
+
+class TimeBarActivity : DemoBase(), OnSeekBarChangeListener {
+
+ private lateinit var binding: ActivityHorizontalbarchartBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityHorizontalbarchartBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ binding.seekBarX.setOnSeekBarChangeListener(this)
+ binding.seekBarY.setOnSeekBarChangeListener(this)
+
+ binding.chart1.isLogging = true
+ binding.chart1.isDrawBarShadow = false
+ binding.chart1.isDrawValueAboveBar = true
+ binding.chart1.description.isEnabled = true
+ binding.chart1.description = Description().apply {
+ text = "Time Bar Line"
+ }
+
+ // if more than 60 entries are displayed in the chart, no values will be drawn
+ binding.chart1.setMaxVisibleValueCount(60)
+
+ // scaling can now only be done on x- and y-axis separately
+ binding.chart1.isPinchZoom = false
+
+ // draw shadows for each bar that show the maximum value
+ // chart.setDrawBarShadow(true);
+ binding.chart1.setDrawGridBackground(false)
+
+ binding.chart1.xAxis.apply {
+ position = XAxisPosition.BOTTOM
+ typeface = tfLight
+ isDrawAxisLine = true
+ isDrawGridLines = true
+ granularity = 10f
+// valueFormatter = UnixTimeAxisValueFormatter("HH:mm:ss")
+ }
+
+// binding.chart1.axisLeft.apply {
+// typeface = tfLight
+// isDrawAxisLine = true
+// isDrawGridLines = true
+// axisMinimum = 0f // this replaces setStartAtZero(true)
+// }
+
+ binding.chart1.axisRight.apply {
+ typeface = tfLight
+ isDrawAxisLine = true
+ isDrawGridLines = false
+ axisMinimum = 0f // this replaces setStartAtZero(true)
+ valueFormatter = UnixTimeRelative2NowAxisValueFormatter("HH:mm:ss")
+ }
+
+ binding.chart1.setFitBars(true)
+ binding.chart1.animateY(2500)
+
+ // setting data
+ binding.seekBarX.progress = 4
+ binding.seekBarY.progress = 12
+
+ binding.chart1.legend.apply {
+ verticalAlignment = Legend.LegendVerticalAlignment.BOTTOM
+ horizontalAlignment = Legend.LegendHorizontalAlignment.LEFT
+ orientation = Legend.LegendOrientation.HORIZONTAL
+ setDrawInside(false)
+ formSize = 8f
+ xEntrySpace = 4f
+ }
+ }
+
+ private fun setData(count: Int) {
+ val barWidth = 9f
+ val spaceForBar = 10.0
+ val values = ArrayList()
+ val sampleValues = getValues(100).map { (it!! * 100).toInt() }
+
+ var previousTimeOffset: Double = 0.0 //TIME_OFFSET.toDouble()
+ for (i in 0.. 0
+ ) {
+ set1 = binding.chart1.barData!!.getDataSetByIndex(0) as BarDataSet
+ @Suppress("UNCHECKED_CAST")
+ set1.entries = values as MutableList
+ binding.chart1.barData?.notifyDataChanged()
+ binding.chart1.notifyDataSetChanged()
+ } else {
+ @Suppress("UNCHECKED_CAST")
+ set1 = BarDataSet(values as MutableList, "Bar DataSet")
+ set1.setColors(
+ Color.GREEN,
+ Color.BLUE,
+ Color.YELLOW
+ )
+
+ set1.isDrawIcons = false
+
+ val dataSets = ArrayList()
+ dataSets.add(set1)
+
+ val data = BarData(dataSets)
+ data.setValueTextSize(10f)
+ data.setValueTypeface(tfLight)
+ data.setValueFormatter(TimeRangeValueFormatter("HH:mm:ss"))
+ data.barWidth = barWidth
+ binding.chart1.data = data
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ menuInflater.inflate(R.menu.bar, menu)
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.viewGithub -> {
+ val i = Intent(Intent.ACTION_VIEW)
+ i.data =
+ "https://github.com/AppDevNext/AndroidChart/blob/master/app/src/main/java/info/appdev/chartexample/HorizontalBarChartActivity.kt".toUri()
+ startActivity(i)
+ }
+
+ R.id.actionToggleValues -> {
+ binding.chart1.barData?.dataSets?.forEach {
+ it.isDrawValues = !it.isDrawValues
+ }
+ binding.chart1.invalidate()
+ }
+
+ R.id.actionToggleIcons -> {
+ binding.chart1.barData?.dataSets?.forEach { set ->
+ set.isDrawIcons = !set.isDrawIcons
+ }
+ binding.chart1.invalidate()
+ }
+
+ R.id.actionToggleHighlight -> {
+ binding.chart1.barData?.let { data ->
+ data.isHighlight = !data.isHighlight
+ binding.chart1.invalidate()
+ }
+ }
+
+ R.id.actionTogglePinch -> {
+ binding.chart1.isPinchZoom = !binding.chart1.isPinchZoom
+ binding.chart1.invalidate()
+ }
+
+ R.id.actionToggleAutoScaleMinMax -> {
+ binding.chart1.isAutoScaleMinMax = !binding.chart1.isAutoScaleMinMax
+ binding.chart1.notifyDataSetChanged()
+ }
+
+ R.id.actionToggleBarBorders -> {
+ binding.chart1.barData?.dataSets?.map { it as BarDataSet }?.forEach { set ->
+ set.barBorderWidth = if (set.barBorderWidth == 1f) 0f else 1f
+ }
+ binding.chart1.invalidate()
+ }
+
+ R.id.animateX -> {
+ binding.chart1.animateX(2000)
+ }
+
+ R.id.animateY -> {
+ binding.chart1.animateY(2000)
+ }
+
+ R.id.animateXY -> {
+ binding.chart1.animateXY(2000, 2000)
+ }
+
+ R.id.actionSave -> {
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ saveToGallery()
+ } else {
+ requestStoragePermission(binding.chart1)
+ }
+ }
+ }
+ return true
+ }
+
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ binding.tvXMax.text = binding.seekBarX.progress.toString()
+ binding.tvYMax.text = binding.seekBarY.progress.toString()
+
+ setData(binding.seekBarX.progress)
+ binding.chart1.setFitBars(true)
+ binding.chart1.invalidate()
+ }
+
+ override fun saveToGallery() {
+ saveToGallery(binding.chart1, "HorizontalBarChartActivity")
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) = 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..38f26d6b7 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.TimeBarActivity
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("TimeBar", "Show a time line with Unix timestamp", TimeBarActivity::class.java))
}
}
}
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-1SampleClick.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-1SampleClick.png
new file mode 100644
index 000000000..4960717a3
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-1SampleClick.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-10ToggleBarBorders.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-10ToggleBarBorders.png
new file mode 100644
index 000000000..675558691
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-10ToggleBarBorders.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-1ToggleValues.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-1ToggleValues.png
new file mode 100644
index 000000000..675558691
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-1ToggleValues.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-24rotateXAxislabels.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-24rotateXAxislabels.png
new file mode 100644
index 000000000..77b6f2cc1
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-24rotateXAxislabels.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-4ToggleIcons.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-4ToggleIcons.png
new file mode 100644
index 000000000..feb6754a9
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-4ToggleIcons.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-5ToggleHighlight.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-5ToggleHighlight.png
new file mode 100644
index 000000000..feb6754a9
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-5ToggleHighlight.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-6TogglePinchZoom.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-6TogglePinchZoom.png
new file mode 100644
index 000000000..77b6f2cc1
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-6TogglePinchZoom.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-7ToggleAutoScale.png b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-7ToggleAutoScale.png
new file mode 100644
index 000000000..77b6f2cc1
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-7ToggleAutoScale.png differ