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
4 changes: 4 additions & 0 deletions app/src/main/kotlin/info/appdev/chartexample/DataTools.kt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ class DataTools {
return result
}

fun getSawtoothValues(size: Int): Array<Double> {
return Array(size) { i -> if (i % 2 == 0) -1.0 else 1.0 }
}

fun setData(context: Context, lineChart: LineChart, count: Int = VAL_COUNT, range: Float = VAL_RANGE) {
Timber.d("count=$count range=$range")
val values = ArrayList<Entry>()
Expand Down
67 changes: 59 additions & 8 deletions app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import android.view.MenuItem
import androidx.core.net.toUri
import androidx.lifecycle.lifecycleScope
import info.appdev.chartexample.DataTools.Companion.generateSineWaves
import info.appdev.chartexample.DataTools.Companion.getSawtoothValues
import info.appdev.chartexample.custom.TimeMarkerView
import info.appdev.chartexample.databinding.ActivityLinechartNoseekbarBinding
import info.appdev.chartexample.formatter.UnixTimeAxisValueFormatter
import info.appdev.chartexample.notimportant.DemoBase
Expand All @@ -25,6 +27,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.Locale

class TimeLineActivity : DemoBase() {
private var menuItemMove: MenuItem? = null
Expand Down Expand Up @@ -77,31 +82,66 @@ class TimeLineActivity : DemoBase() {

binding.chart1.axisRight.isEnabled = false

setData(60f, TIME_OFFSET)
val timeMarkerView = TimeMarkerView(this, R.layout.custom_marker_view, "HH:mm:ss.sss")
timeMarkerView.chartView = binding.chart1
binding.chart1.marker.add(timeMarkerView)

setData(60f, TIME_OFFSET, true)

binding.chart1.invalidate()
}

@Suppress("SameParameterValue")
private fun setData(range: Float, timeOffset: Long) {
private fun setData(range: Float, timeOffset: Long, sinus: Boolean) {

val sampleEntries = generateSineWaves(3, 30)
.mapIndexed { index, data ->
val sampleEntries = if (sinus)
generateSineWaves(3, 30).mapIndexed { index, data ->
val valueY = (data.toFloat() * range) + 50
Entry(timeOffset + index.toFloat() * 1000, valueY)
}.toMutableList()
}
else {
var previousEntry: Entry? = null
getSawtoothValues(14).mapIndexed { index, data ->
val valueY = data.toFloat() * 20
val entry = previousEntry?.let {
// nay third value is 0, so we add here more then 1 second, otherwise we have a one second entry
if (index % 3 == 0) {
Entry(it.x + 3000, valueY)
} else
Entry(it.x + 1000, valueY)
} ?: run {
Entry(timeOffset + index.toFloat() * 1000, valueY)
}
previousEntry = entry
// Now you can use 'prev' which holds the previous Entry
entry
}
}

val simpleDateFormat = SimpleDateFormat("HH:mm:ss.sss", Locale.getDefault())
sampleEntries.forEach { entry ->
val entryText = "Entry: x=${simpleDateFormat.format(entry.x)} x=${entry.x}, y=${entry.y}"
Timber.d(entryText)
}

val set1: LineDataSet

if (binding.chart1.lineData.dataSetCount > 0) {
set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet
set1.entries = sampleEntries
set1.entries = sampleEntries.toMutableList()
if (sinus)
set1.lineMode = LineDataSet.Mode.LINEAR
else
set1.lineMode = LineDataSet.Mode.STEPPED
binding.chart1.lineData.notifyDataChanged()
binding.chart1.notifyDataSetChanged()
} else {
// create a dataset and give it a type
set1 = LineDataSet(sampleEntries, "DataSet 1")

set1 = LineDataSet(sampleEntries.toMutableList(), "DataSet 1")
if (sinus)
set1.lineMode = LineDataSet.Mode.LINEAR
else
set1.lineMode = LineDataSet.Mode.STEPPED
set1.axisDependency = YAxis.AxisDependency.LEFT
set1.color = Color.rgb(255, 241, 46)
set1.isDrawCircles = false
Expand Down Expand Up @@ -151,6 +191,17 @@ class TimeLineActivity : DemoBase() {
true
}.isCheckable = true
}
menuItemMove = menu?.add("Show sinus data")?.apply {
this.isChecked = true
setOnMenuItemClickListener { menuItem ->
menuItem.isChecked = !menuItem.isChecked
lifecycleScope.launch {
setData(60f, TIME_OFFSET, menuItem.isChecked)
binding.chart1.invalidate()
}
true
}.isCheckable = true
}
return true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package info.appdev.chartexample.custom

import android.annotation.SuppressLint
import android.content.Context
import android.widget.TextView
import info.appdev.chartexample.R
import info.appdev.charting.components.MarkerView
import info.appdev.charting.data.Entry
import info.appdev.charting.highlight.Highlight
import info.appdev.charting.interfaces.datasets.IDataSet
import info.appdev.charting.utils.PointF
import java.text.SimpleDateFormat
import java.util.Locale

@SuppressLint("ViewConstructor")
class TimeMarkerView(context: Context?, layoutResource: Int, val format: String = "yyyy-MM-dd'T'HH:mm:ss'Z'") : MarkerView(context, layoutResource) {

private val simpleDateFormat = SimpleDateFormat(format, Locale.getDefault())
private val tvContent: TextView = findViewById(R.id.tvContent)

@SuppressLint("SetTextI18n")
override fun refreshContent(entry: Entry, highlight: Highlight) {
@Suppress("UNCHECKED_CAST")
val dataset = this.chartView?.data?.dataSets[0] as? IDataSet<Entry>
val myIndex = dataset?.getEntryIndex(entry)
val nextEntry = myIndex?.let {
if (it < dataset.entryCount - 1)
dataset.getEntryForIndex(myIndex + 1)
else
null
} ?: run { null }

val duration = if (nextEntry != null) " - duration:${(nextEntry.x - entry.x)}" else ""
tvContent.text = "${simpleDateFormat.format(entry.x)}$duration"
super.refreshContent(entry, highlight)
}

override var offset: PointF = PointF()
get() = PointF(-(width / 2).toFloat(), -height.toFloat())
}
Loading