diff --git a/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt b/app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt
index 2c127e96d..4798d0d6e 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)
@@ -296,6 +297,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 == TimeIntervalChartActivity::class.java ||
contentItem.clazz == TimeLineActivity::class.java
) {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a8f2a241b..5cd410447 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -61,6 +61,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..a0bd8ffe8
--- /dev/null
+++ b/app/src/main/kotlin/info/appdev/chartexample/TimeBarActivity.kt
@@ -0,0 +1,248 @@
+package info.appdev.chartexample
+
+import android.Manifest
+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.databinding.ActivityHorizontalbarchartBinding
+import info.appdev.chartexample.formatter.TimeRangeValueFormatter
+import info.appdev.chartexample.formatter.UnixTimeRelative2NowAxisValueFormatter
+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
+ axisMaxLabels = 4
+ isDrawGridLines = false
+ axisMinimum = 0f // this replaces setStartAtZero(true)
+ valueFormatter = UnixTimeRelative2NowAxisValueFormatter("mm:ss", 1776000000 * 1000L)
+ }
+
+ 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.0f
+ val values = ArrayList()
+ val sampleValues = getValues(100).map { (it!! * 100).toInt() }
+
+ var previousTimeOffset = 0f //TIME_OFFSET.toFloat()
+ 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/formatter/UnixTimeRelative2NowAxisValueFormatter.kt b/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeRelative2NowAxisValueFormatter.kt
index 0183239d5..d6d1ac242 100644
--- a/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeRelative2NowAxisValueFormatter.kt
+++ b/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeRelative2NowAxisValueFormatter.kt
@@ -5,12 +5,12 @@ import info.appdev.charting.formatter.IAxisValueFormatter
import java.text.SimpleDateFormat
import java.util.Locale
-class UnixTimeRelative2NowAxisValueFormatter(val format: String = "yyyy-MM-dd'T'HH:mm:ss'Z'") : IAxisValueFormatter {
+class UnixTimeRelative2NowAxisValueFormatter(val format: String = "yyyy-MM-dd'T'HH:mm:ss'Z'", val relativeTime : Long = System.currentTimeMillis()) : IAxisValueFormatter {
val simpleDateFormat = SimpleDateFormat(format, Locale.getDefault())
override fun getFormattedValue(value: Float, axis: AxisBase?): String {
- val relative2Now = System.currentTimeMillis() + (value.toLong() * 1000)
+ val relative2Now = relativeTime + (value.toLong() * 1000)
return simpleDateFormat.format(relative2Now)
}
diff --git a/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeValueFormatter.kt b/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeValueFormatter.kt
index 2ab02341d..39982e990 100644
--- a/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeValueFormatter.kt
+++ b/app/src/main/kotlin/info/appdev/chartexample/formatter/UnixTimeValueFormatter.kt
@@ -1,6 +1,5 @@
package info.appdev.chartexample.formatter
-import info.appdev.charting.data.BarEntryDouble
import info.appdev.charting.data.BarEntryFloat
import info.appdev.charting.data.EntryFloat
import info.appdev.charting.formatter.IValueFormatter
@@ -14,24 +13,12 @@ class UnixTimeValueFormatter(val format: String = "yyyy-MM-dd'T'HH:mm:ss'Z'") :
// For bar/line values
override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String {
- return when (entryFloat) {
- is BarEntryDouble if entryFloat.yValsDouble != null -> {
- // High-precision double path
- val vals = entryFloat.yValsDouble!!
- val start = simpleDateFormat.format(vals.first().toLong())
- val end = simpleDateFormat.format(vals.last().toLong())
- "$start - $end"
- }
-
- is BarEntryFloat if entryFloat.yVals != null -> {
- // Float path
- val vals = entryFloat.yVals!!
- val start = simpleDateFormat.format(vals.first().toLong())
- val end = simpleDateFormat.format(vals.last().toLong())
- "$start - $end"
- }
-
- else -> simpleDateFormat.format(value.toLong())
+ return if (entryFloat is BarEntryFloat) {
+ simpleDateFormat.format(entryFloat.yVals?.get(0)!!.toLong()) +
+ " - " +
+ simpleDateFormat.format(entryFloat.yVals?.get(entryFloat.yVals?.size!! - 1)!!.toLong())
}
+ else
+ simpleDateFormat.format(value.toLong())
}
}
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 ccae0d21c..7caedfec3 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.TimeIntervalChartActivity
import info.appdev.chartexample.TimeLineActivity
import info.appdev.chartexample.compose.HorizontalBarComposeActivity
@@ -220,6 +221,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))
add(ContentItem("Timeinterval", "Grantt chart", TimeIntervalChartActivity::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..0f0106775
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..03562c6a7
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..03562c6a7
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..03562c6a7
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..03562c6a7
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..03562c6a7
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..03562c6a7
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..03562c6a7
Binary files /dev/null and b/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeBarActivity-TimeBar-2menu-click-7ToggleAutoScale.png differ
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-1SampleClick.png b/screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-1SampleClick.png
similarity index 100%
rename from screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-1SampleClick.png
rename to screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-1SampleClick.png
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click.png b/screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-click.png
similarity index 100%
rename from screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click.png
rename to screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-click.png
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click2020.png b/screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-click2020.png
similarity index 100%
rename from screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click2020.png
rename to screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-click2020.png
diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click7070.png b/screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-click7070.png
similarity index 100%
rename from screenshotsToCompare9/StartTest_smokeTestStart-46-TimeIntervalChartActivity-Timeinterval-click7070.png
rename to screenshotsToCompare9/StartTest_smokeTestStart-47-TimeIntervalChartActivity-Timeinterval-click7070.png