Skip to content

Commit d6755a0

Browse files
committed
TimeBar Double
XAxis label rotation
1 parent a2e2652 commit d6755a0

File tree

4 files changed

+253
-0
lines changed

4 files changed

+253
-0
lines changed

app/src/androidTest/kotlin/info/appdev/chartexample/StartTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import org.junit.Test
4242
import org.junit.rules.TestName
4343
import org.junit.runner.RunWith
4444
import timber.log.Timber
45+
import kotlin.jvm.java
4546

4647

4748
@RunWith(AndroidJUnit4::class)
@@ -296,6 +297,7 @@ class StartTest {
296297
contentItem.clazz == HorizontalBarFullComposeActivity::class.java ||
297298
contentItem.clazz == MultiLineComposeActivity::class.java ||
298299
contentItem.clazz == GradientActivity::class.java ||
300+
contentItem.clazz == TimeBarActivity::class.java ||
299301
// contentItem.clazz == TimeIntervalChartActivity::class.java ||
300302
contentItem.clazz == TimeLineActivity::class.java
301303
) {

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<activity android:name="info.appdev.chartexample.SpecificPositionsLineChartActivity" />
6262
<activity android:name="info.appdev.chartexample.TimeLineActivity" />
6363
<activity android:name="info.appdev.chartexample.TimeIntervalChartActivity" />
64+
<activity android:name="info.appdev.chartexample.TimeBarActivity" />
6465
</application>
6566

6667
</manifest>
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
package info.appdev.chartexample
2+
3+
import android.Manifest
4+
import android.content.Intent
5+
import android.content.pm.PackageManager
6+
import android.graphics.Color
7+
import android.os.Bundle
8+
import android.view.Menu
9+
import android.view.MenuItem
10+
import android.widget.SeekBar
11+
import android.widget.SeekBar.OnSeekBarChangeListener
12+
import androidx.core.content.ContextCompat
13+
import androidx.core.content.res.ResourcesCompat
14+
import androidx.core.net.toUri
15+
import info.appdev.chartexample.DataTools.Companion.getValues
16+
import info.appdev.chartexample.databinding.ActivityHorizontalbarchartBinding
17+
import info.appdev.chartexample.formatter.TimeRangeValueFormatter
18+
import info.appdev.chartexample.formatter.UnixTimeRelative2NowAxisValueFormatter
19+
import info.appdev.chartexample.notimportant.DemoBase
20+
import info.appdev.charting.components.Description
21+
import info.appdev.charting.components.Legend
22+
import info.appdev.charting.components.XAxis.XAxisPosition
23+
import info.appdev.charting.data.BarData
24+
import info.appdev.charting.data.BarDataSet
25+
import info.appdev.charting.data.BarEntryDouble
26+
import info.appdev.charting.data.BarEntryFloat
27+
import info.appdev.charting.interfaces.datasets.IBarDataSet
28+
import timber.log.Timber
29+
30+
class TimeBarActivity : DemoBase(), OnSeekBarChangeListener {
31+
32+
private lateinit var binding: ActivityHorizontalbarchartBinding
33+
34+
override fun onCreate(savedInstanceState: Bundle?) {
35+
super.onCreate(savedInstanceState)
36+
binding = ActivityHorizontalbarchartBinding.inflate(layoutInflater)
37+
setContentView(binding.root)
38+
39+
binding.seekBarX.setOnSeekBarChangeListener(this)
40+
binding.seekBarY.setOnSeekBarChangeListener(this)
41+
42+
binding.chart1.isLogging = true
43+
binding.chart1.isDrawBarShadow = false
44+
binding.chart1.isDrawValueAboveBar = true
45+
binding.chart1.description.isEnabled = true
46+
binding.chart1.description = Description().apply {
47+
text = "Time Bar Line"
48+
}
49+
50+
// if more than 60 entries are displayed in the chart, no values will be drawn
51+
binding.chart1.setMaxVisibleValueCount(60)
52+
53+
// scaling can now only be done on x- and y-axis separately
54+
binding.chart1.isPinchZoom = false
55+
56+
// draw shadows for each bar that show the maximum value
57+
// chart.setDrawBarShadow(true);
58+
binding.chart1.setDrawGridBackground(false)
59+
60+
binding.chart1.xAxis.apply {
61+
position = XAxisPosition.BOTTOM
62+
typeface = tfLight
63+
isDrawAxisLine = true
64+
isDrawGridLines = true
65+
granularity = 10f
66+
// valueFormatter = UnixTimeAxisValueFormatter("HH:mm:ss")
67+
}
68+
69+
// binding.chart1.axisLeft.apply {
70+
// typeface = tfLight
71+
// isDrawAxisLine = true
72+
// isDrawGridLines = true
73+
// axisMinimum = 0f // this replaces setStartAtZero(true)
74+
// }
75+
76+
binding.chart1.axisRight.apply {
77+
typeface = tfLight
78+
isDrawAxisLine = true
79+
axisMaxLabels = 5
80+
isDrawGridLines = false
81+
axisMinimum = 0f // this replaces setStartAtZero(true)
82+
valueFormatter = UnixTimeRelative2NowAxisValueFormatter("HH:mm:ss")
83+
}
84+
85+
binding.chart1.setFitBars(true)
86+
binding.chart1.animateY(2500)
87+
88+
// setting data
89+
binding.seekBarX.progress = 4
90+
binding.seekBarY.progress = 12
91+
92+
binding.chart1.legend.apply {
93+
verticalAlignment = Legend.LegendVerticalAlignment.BOTTOM
94+
horizontalAlignment = Legend.LegendHorizontalAlignment.LEFT
95+
orientation = Legend.LegendOrientation.HORIZONTAL
96+
setDrawInside(false)
97+
formSize = 8f
98+
xEntrySpace = 4f
99+
}
100+
}
101+
102+
private fun setData(count: Int) {
103+
val barWidth = 9f
104+
val spaceForBar = 10.0
105+
val values = ArrayList<BarEntryDouble>()
106+
val sampleValues = getValues(100).map { (it!! * 100).toInt() }
107+
108+
var previousTimeOffset: Double = 0.0 //TIME_OFFSET.toDouble()
109+
for (i in 0..<count) {
110+
Timber.d("add ${sampleValues[i]}s to $previousTimeOffset")
111+
val yValue = sampleValues[i] + previousTimeOffset
112+
val value = BarEntryDouble(
113+
x = i * spaceForBar,
114+
vals = doubleArrayOf(previousTimeOffset, yValue),
115+
icon = ResourcesCompat.getDrawable(resources, R.drawable.star, null)
116+
)
117+
values.add(value)
118+
previousTimeOffset = yValue
119+
}
120+
121+
Timber.d(values.joinToString(separator = "\n"))
122+
123+
val set1: BarDataSet
124+
125+
if (binding.chart1.barData != null &&
126+
binding.chart1.barData!!.dataSetCount > 0
127+
) {
128+
set1 = binding.chart1.barData!!.getDataSetByIndex(0) as BarDataSet
129+
@Suppress("UNCHECKED_CAST")
130+
set1.entries = values as MutableList<BarEntryFloat>
131+
binding.chart1.barData?.notifyDataChanged()
132+
binding.chart1.notifyDataSetChanged()
133+
} else {
134+
@Suppress("UNCHECKED_CAST")
135+
set1 = BarDataSet(values as MutableList<BarEntryFloat>, "Bar DataSet")
136+
set1.setColors(
137+
Color.GREEN,
138+
Color.BLUE,
139+
Color.YELLOW
140+
)
141+
142+
set1.isDrawIcons = false
143+
144+
val dataSets = ArrayList<IBarDataSet>()
145+
dataSets.add(set1)
146+
147+
val data = BarData(dataSets)
148+
data.setValueTextSize(10f)
149+
data.setValueTypeface(tfLight)
150+
data.setValueFormatter(TimeRangeValueFormatter("HH:mm:ss"))
151+
data.barWidth = barWidth
152+
binding.chart1.data = data
153+
}
154+
}
155+
156+
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
157+
menuInflater.inflate(R.menu.bar, menu)
158+
return true
159+
}
160+
161+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
162+
when (item.itemId) {
163+
R.id.viewGithub -> {
164+
val i = Intent(Intent.ACTION_VIEW)
165+
i.data =
166+
"https://github.com/AppDevNext/AndroidChart/blob/master/app/src/main/java/info/appdev/chartexample/HorizontalBarChartActivity.kt".toUri()
167+
startActivity(i)
168+
}
169+
170+
R.id.actionToggleValues -> {
171+
binding.chart1.barData?.dataSets?.forEach {
172+
it.isDrawValues = !it.isDrawValues
173+
}
174+
binding.chart1.invalidate()
175+
}
176+
177+
R.id.actionToggleIcons -> {
178+
binding.chart1.barData?.dataSets?.forEach { set ->
179+
set.isDrawIcons = !set.isDrawIcons
180+
}
181+
binding.chart1.invalidate()
182+
}
183+
184+
R.id.actionToggleHighlight -> {
185+
binding.chart1.barData?.let { data ->
186+
data.isHighlight = !data.isHighlight
187+
binding.chart1.invalidate()
188+
}
189+
}
190+
191+
R.id.actionTogglePinch -> {
192+
binding.chart1.isPinchZoom = !binding.chart1.isPinchZoom
193+
binding.chart1.invalidate()
194+
}
195+
196+
R.id.actionToggleAutoScaleMinMax -> {
197+
binding.chart1.isAutoScaleMinMax = !binding.chart1.isAutoScaleMinMax
198+
binding.chart1.notifyDataSetChanged()
199+
}
200+
201+
R.id.actionToggleBarBorders -> {
202+
binding.chart1.barData?.dataSets?.map { it as BarDataSet }?.forEach { set ->
203+
set.barBorderWidth = if (set.barBorderWidth == 1f) 0f else 1f
204+
}
205+
binding.chart1.invalidate()
206+
}
207+
208+
R.id.animateX -> {
209+
binding.chart1.animateX(2000)
210+
}
211+
212+
R.id.animateY -> {
213+
binding.chart1.animateY(2000)
214+
}
215+
216+
R.id.animateXY -> {
217+
binding.chart1.animateXY(2000, 2000)
218+
}
219+
220+
R.id.actionSave -> {
221+
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
222+
saveToGallery()
223+
} else {
224+
requestStoragePermission(binding.chart1)
225+
}
226+
}
227+
}
228+
return true
229+
}
230+
231+
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
232+
binding.tvXMax.text = binding.seekBarX.progress.toString()
233+
binding.tvYMax.text = binding.seekBarY.progress.toString()
234+
235+
setData(binding.seekBarX.progress)
236+
binding.chart1.setFitBars(true)
237+
binding.chart1.invalidate()
238+
}
239+
240+
override fun saveToGallery() {
241+
saveToGallery(binding.chart1, "HorizontalBarChartActivity")
242+
}
243+
244+
override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
245+
246+
override fun onStopTrackingTouch(seekBar: SeekBar?) = Unit
247+
248+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import info.appdev.chartexample.ScrollViewActivity
7575
import info.appdev.chartexample.SpecificPositionsLineChartActivity
7676
import info.appdev.chartexample.StackedBarActivity
7777
import info.appdev.chartexample.StackedBarActivityNegative
78+
import info.appdev.chartexample.TimeBarActivity
7879
import info.appdev.chartexample.TimeIntervalChartActivity
7980
import info.appdev.chartexample.TimeLineActivity
8081
import info.appdev.chartexample.compose.HorizontalBarComposeActivity
@@ -220,6 +221,7 @@ class MainActivity : ComponentActivity() {
220221
add(ContentItem("Demonstrate and fix issues"))
221222
add(ContentItem("Gradient", "Show a gradient edge case", GradientActivity::class.java))
222223
add(ContentItem("Timeline", "Show a time line with Unix timestamp", TimeLineActivity::class.java))
224+
add(ContentItem("TimeBar", "Show a time line with Unix timestamp", TimeBarActivity::class.java))
223225
add(ContentItem("Timeinterval", "Grantt chart", TimeIntervalChartActivity::class.java))
224226
}
225227
}

0 commit comments

Comments
 (0)