Skip to content

Commit af2c75a

Browse files
authored
Merge pull request #633 from AppDevNext/TimelineActivity
Timeline activity
2 parents e30a9f0 + 5b1f8d4 commit af2c75a

6 files changed

Lines changed: 185 additions & 0 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
<activity android:name="info.appdev.chartexample.GradientActivity" />
5757
<activity android:name="info.appdev.chartexample.HalfPieChartActivity" />
5858
<activity android:name="info.appdev.chartexample.SpecificPositionsLineChartActivity" />
59+
<activity android:name="info.appdev.chartexample.TimeLineActivity" />
5960
</application>
6061

6162
</manifest>

app/src/main/kotlin/info/appdev/chartexample/DataTools.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import info.appdev.charting.interfaces.dataprovider.LineDataProvider
1313
import info.appdev.charting.interfaces.datasets.ILineDataSet
1414
import info.appdev.charting.utils.getSDKInt
1515
import timber.log.Timber
16+
import kotlin.math.PI
17+
import kotlin.math.sin
1618

1719
class DataTools {
1820
companion object {
@@ -135,6 +137,19 @@ class DataTools {
135137

136138
fun getValues(size: Int) = VAL_102.copyOf(size)
137139

140+
/**
141+
* Generates points for n complete sine waves.
142+
* @param cycles Number of complete sine graphs (n)
143+
* @param pointsPerCycle Number of data points to generate for each cycle
144+
*/
145+
fun generateSineWaves(cycles: Int, pointsPerCycle: Int): List<Double> {
146+
val totalPoints = cycles * pointsPerCycle
147+
val stepSize = (2 * PI * cycles) / totalPoints
148+
149+
return (0 until totalPoints).map { i ->
150+
sin(i * stepSize)
151+
}
152+
}
138153
fun getMuchValues(size: Int): Array<Double?> {
139154
var result = VAL_102.copyOf(VAL_102.size)
140155
while (result.size < size)
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package info.appdev.chartexample
2+
3+
import android.content.Intent
4+
import android.graphics.Color
5+
import android.os.Bundle
6+
import android.view.Menu
7+
import android.view.MenuItem
8+
import androidx.core.net.toUri
9+
import info.appdev.chartexample.DataTools.Companion.generateSineWaves
10+
import info.appdev.chartexample.databinding.ActivityLinechartNoseekbarBinding
11+
import info.appdev.chartexample.formatter.UnixTimeAxisValueFormatter
12+
import info.appdev.chartexample.notimportant.DemoBase
13+
import info.appdev.charting.components.Description
14+
import info.appdev.charting.components.Legend.LegendForm
15+
import info.appdev.charting.components.XAxis.XAxisPosition
16+
import info.appdev.charting.components.YAxis
17+
import info.appdev.charting.data.Entry
18+
import info.appdev.charting.data.LineData
19+
import info.appdev.charting.data.LineDataSet
20+
import info.appdev.charting.formatter.IFillFormatter
21+
import info.appdev.charting.interfaces.dataprovider.LineDataProvider
22+
import info.appdev.charting.interfaces.datasets.ILineDataSet
23+
24+
class TimeLineActivity : DemoBase() {
25+
private lateinit var binding: ActivityLinechartNoseekbarBinding
26+
27+
override fun onCreate(savedInstanceState: Bundle?) {
28+
super.onCreate(savedInstanceState)
29+
binding = ActivityLinechartNoseekbarBinding.inflate(layoutInflater)
30+
setContentView(binding.root)
31+
32+
binding.chart1.setBackgroundColor(Color.WHITE)
33+
binding.chart1.setDrawGridBackground(true)
34+
35+
binding.chart1.setDrawBorders(true)
36+
37+
// no description text
38+
binding.chart1.description = Description().apply {
39+
text = "Sinus Time Line"
40+
}
41+
binding.chart1.description.isEnabled = true
42+
43+
binding.chart1.xAxis.apply {
44+
// enableGridDashedLine(10f, 10f, 0f)
45+
// this.position = XAxis.XAxisPosition.BOTH_SIDED
46+
isEnabled = true
47+
position = XAxisPosition.BOTTOM
48+
typeface = tfLight
49+
labelRotationAngle = 45f
50+
setDrawGridLines(false)
51+
// granularity = 1f // only intervals of 1 day
52+
labelCount = 7
53+
valueFormatter = UnixTimeAxisValueFormatter("yyyy-MM-dd HH:mm:ss")
54+
}
55+
56+
// if disabled, scaling can be done on x- and y-axis separately
57+
binding.chart1.setPinchZoom(false)
58+
59+
binding.chart1.legend.apply {
60+
isEnabled = false
61+
form = LegendForm.LINE
62+
}
63+
64+
binding.chart1.axisLeft.apply {
65+
axisMaximum = 150f
66+
axisMinimum = -50f
67+
setDrawAxisLine(true)
68+
setDrawZeroLine(true)
69+
setDrawGridLines(true)
70+
}
71+
72+
binding.chart1.axisRight.isEnabled = false
73+
74+
setData(60f, TIME_OFFSET)
75+
76+
binding.chart1.invalidate()
77+
}
78+
79+
@Suppress("SameParameterValue")
80+
private fun setData(range: Float, timeOffset: Long) {
81+
82+
val sampleEntries = generateSineWaves(3, 30)
83+
.mapIndexed { index, data ->
84+
val valueY = (data.toFloat() * range) + 50
85+
Entry(timeOffset + index.toFloat() * 1000, valueY)
86+
}.toMutableList()
87+
88+
val set1: LineDataSet
89+
90+
if (binding.chart1.lineData.dataSetCount > 0) {
91+
set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet
92+
set1.entries = sampleEntries
93+
binding.chart1.lineData.notifyDataChanged()
94+
binding.chart1.notifyDataSetChanged()
95+
} else {
96+
// create a dataset and give it a type
97+
set1 = LineDataSet(sampleEntries, "DataSet 1")
98+
99+
set1.axisDependency = YAxis.AxisDependency.LEFT
100+
set1.color = Color.rgb(255, 241, 46)
101+
set1.isDrawCirclesEnabled = false
102+
set1.lineWidth = 2f
103+
set1.circleRadius = 3f
104+
set1.fillAlpha = 255
105+
set1.isDrawFilledEnabled = true
106+
set1.fillColor = Color.WHITE
107+
set1.highLightColor = Color.rgb(244, 117, 117)
108+
set1.isDrawCircleHoleEnabled = false
109+
set1.fillFormatter = object : IFillFormatter {
110+
override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float {
111+
// change the return value here to better understand the effect
112+
// return 0;
113+
return binding.chart1.axisLeft.axisMinimum
114+
}
115+
}
116+
117+
val dataSets = ArrayList<ILineDataSet>()
118+
dataSets.add(set1) // add the data sets
119+
120+
// create a data object with the data sets
121+
val data = LineData(dataSets)
122+
data.setDrawValues(false)
123+
124+
binding.chart1.setData(data)
125+
}
126+
}
127+
128+
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
129+
menuInflater.inflate(R.menu.only_github, menu)
130+
return true
131+
}
132+
133+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
134+
when (item.itemId) {
135+
R.id.viewGithub -> {
136+
val i = Intent(Intent.ACTION_VIEW)
137+
i.data =
138+
"https://github.com/AppDevNext/AndroidChart/blob/master/app/src/main/java/info/appdev/chartexample/FilledLineActivity.kt".toUri()
139+
startActivity(i)
140+
}
141+
}
142+
143+
return true
144+
}
145+
146+
public override fun saveToGallery() = Unit // Intentionally left empty
147+
148+
companion object {
149+
const val TIME_OFFSET = 1767105583L
150+
}
151+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package info.appdev.chartexample.formatter
2+
3+
import info.appdev.charting.components.AxisBase
4+
import info.appdev.charting.formatter.IAxisValueFormatter
5+
import java.text.SimpleDateFormat
6+
import java.util.Locale
7+
8+
class UnixTimeAxisValueFormatter(val format: String = "yyyy-MM-dd'T'HH:mm:ss'Z'") : IAxisValueFormatter {
9+
10+
val sdf = SimpleDateFormat(format, Locale.getDefault())
11+
12+
override fun getFormattedValue(value: Float, axis: AxisBase?): String {
13+
return sdf.format(value * 1000L)
14+
}
15+
16+
}

app/src/main/kotlin/info/appdev/chartexample/notimportant/MainActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ import info.appdev.chartexample.ScrollViewActivity
7777
import info.appdev.chartexample.SpecificPositionsLineChartActivity
7878
import info.appdev.chartexample.StackedBarActivity
7979
import info.appdev.chartexample.StackedBarActivityNegative
80+
import info.appdev.chartexample.TimeLineActivity
8081
import info.appdev.chartexample.compose.HorizontalBarComposeActivity
8182
import info.appdev.chartexample.fragments.ViewPagerSimpleChartDemo
8283

@@ -212,6 +213,7 @@ class MainActivity : ComponentActivity() {
212213

213214
add(ContentItem("Demonstrate and fix issues"))
214215
add(ContentItem("Gradient", "Show a gradient edge case", GradientActivity::class.java))
216+
add(ContentItem("Timeline", "Show a time line with Unix timestamp", TimeLineActivity::class.java))
215217
}
216218
}
217219
}
21.1 KB
Loading

0 commit comments

Comments
 (0)