From 8a7f2da2095268de11aec4041205c5d5de02c9d3 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 10:51:01 +0200 Subject: [PATCH 1/9] BaseEntry generic to be able to use it as Float or Double --- .../info/appdev/charting/data/BaseEntry.kt | 14 +- .../kotlin/info/appdev/charting/data/Entry.kt | 2 +- .../info/appdev/charting/data/EntryDouble.kt | 150 +++++++++++++++++- .../info/appdev/charting/utils/Utils.kt | 2 + 4 files changed, 159 insertions(+), 9 deletions(-) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt index d553eb652d..b3f2725b5f 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt @@ -2,10 +2,10 @@ package info.appdev.charting.data import android.graphics.drawable.Drawable -abstract class BaseEntry { +abstract class BaseEntry where T : Number, T : Comparable { - protected var yBase: Float = 0f - open var y: Float + protected lateinit var yBase: T + open var y: T get() = yBase set(value) { yBase = value @@ -17,19 +17,19 @@ abstract class BaseEntry { constructor() - constructor(y: Float) { + constructor(y: T) { this.yBase = y } - constructor(y: Float, data: Any?) : this(y) { + constructor(y: T, data: Any?) : this(y) { this.data = data } - constructor(y: Float, icon: Drawable?) : this(y) { + constructor(y: T, icon: Drawable?) : this(y) { this.icon = icon } - constructor(y: Float, icon: Drawable?, data: Any?) : this(y) { + constructor(y: T, icon: Drawable?, data: Any?) : this(y) { this.icon = icon this.data = data } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt index db85d860bc..9a0b9fd191 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt @@ -13,7 +13,7 @@ import kotlin.math.abs * Class representing one entry in the chart. Might contain multiple values. * Might only contain a single value depending on the used constructor. */ -open class Entry : BaseEntry, Parcelable, Serializable { +open class Entry : BaseEntry, Parcelable, Serializable { private var _x: Float = 0f open var x: Float diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt index 284880c978..955460af82 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt @@ -1,3 +1,151 @@ package info.appdev.charting.data -class EntryDouble(val xDouble: Double, y: Float) : Entry(xDouble.toFloat(), y) +import android.graphics.drawable.Drawable +import android.os.Build +import android.os.Parcel +import android.os.ParcelFormatException +import android.os.Parcelable +import info.appdev.charting.utils.Utils +import java.io.Serializable +import kotlin.math.abs + +open class EntryDouble : BaseEntry, Parcelable, Serializable { + + private var _x: Double = 0.0 + open var x: Double + get() = _x + set(value) { + _x = value + } + + constructor() + + /** + * A Entry represents one single entry in the chart. + * + * @param x the x value + * @param y the y value (the actual value of the entry) + */ + constructor(x: Double, y: Double) : super(y) { + this._x = x + } + + /** + * A Entry represents one single entry in the chart. + * + * @param x the x value + * @param y the y value (the actual value of the entry) + * @param data Spot for additional data this Entry represents. + */ + constructor(x: Double, y: Double, data: Any?) : super(y, data) { + this._x = x + } + + /** + * A Entry represents one single entry in the chart. + * + * @param x the x value + * @param y the y value (the actual value of the entry) + * @param icon icon image + */ + constructor(x: Double, y: Double, icon: Drawable?) : super(y, icon) { + this._x = x + } + + /** + * A Entry represents one single entry in the chart. + * + * @param x the x value + * @param y the y value (the actual value of the entry) + * @param icon icon image + * @param data Spot for additional data this Entry represents. + */ + constructor(x: Double, y: Double, icon: Drawable?, data: Any?) : super(y, icon, data) { + this._x = x + } + + /** + * returns an exact copy of the entry + */ + open fun copy(): EntryDouble { + val e = EntryDouble(x, y, data) + return e + } + + /** + * Compares value, xIndex and data of the entries. Returns true if entries + * are equal in those points, false if not. Does not check by hash-code like + * it's done by the "equals" method. + */ + fun equalTo(e: EntryDouble?): Boolean { + if (e == null) + return false + + if (e.data !== this.data) + return false + + if (abs((e.x - this.x)) > Utils.DOUBLE_EPSILON) + return false + + if (abs((e.y - this.y)) > Utils.DOUBLE_EPSILON) + return false + + return true + } + + /** + * returns a string representation of the entry containing x-index and value + */ + override fun toString(): String { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + "${this.javaClass.typeName.substringAfterLast(".")} x=$x y=$y" + } else { + "EntryDouble x=$x y=$y" + } + } + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeDouble(this.x) + dest.writeDouble(this.y) + if (data != null) { + if (data is Parcelable) { + dest.writeInt(1) + dest.writeParcelable(data as Parcelable?, flags) + } else { + throw ParcelFormatException("Cannot parcel an EntryDouble with non-parcelable data") + } + } else { + dest.writeInt(0) + } + } + + protected constructor(`in`: Parcel) { + this._x = `in`.readDouble() + this.yBase = `in`.readDouble() + if (`in`.readInt() == 1) { + this.data = if (Build.VERSION.SDK_INT >= 33) { + `in`.readParcelable(Any::class.java.classLoader, Any::class.java) + } else { + @Suppress("DEPRECATION") + `in`.readParcelable(Any::class.java.classLoader) + } + } + } + + companion object { + @JvmField + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(source: Parcel): EntryDouble { + return EntryDouble(source) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + } +} diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt index b9a2b0e008..f5cfd86142 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt @@ -7,6 +7,7 @@ import android.view.VelocityTracker import android.view.ViewConfiguration import info.appdev.charting.formatter.DefaultValueFormatter import info.appdev.charting.formatter.IValueFormatter +import java.lang.Float.intBitsToFloat import kotlin.math.abs import kotlin.math.cos import kotlin.math.sin @@ -23,6 +24,7 @@ object Utils { const val FDEG2RAD: Float = (Math.PI.toFloat() / 180f) val FLOAT_EPSILON: Float = java.lang.Float.intBitsToFloat(1) + val DOUBLE_EPSILON: Double = java.lang.Double.longBitsToDouble(1L) /** * initialize method, called inside the Chart.init() method. From 29a5b72adae047ae68bef54956c5294f3d7ab385 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 10:53:45 +0200 Subject: [PATCH 2/9] Rename Entry to EntryFloat --- .../appdev/chartexample/AnotherBarActivity.kt | 6 +- .../appdev/chartexample/BarChartActivity.kt | 16 ++--- .../BarChartActivityMultiDataset.kt | 24 ++++---- .../chartexample/BarChartActivitySinus.kt | 6 +- .../chartexample/BarChartPositiveNegative.kt | 10 ++-- .../chartexample/BubbleChartActivity.kt | 20 +++---- .../chartexample/CandleStickChartActivity.kt | 6 +- .../chartexample/CombinedChartActivity.kt | 32 +++++----- .../chartexample/CubicLineChartActivity.kt | 6 +- .../info/appdev/chartexample/DataTools.kt | 10 ++-- .../appdev/chartexample/DrawChartActivity.kt | 16 ++--- .../chartexample/DynamicalAddingActivity.kt | 12 ++-- .../appdev/chartexample/FilledLineActivity.kt | 10 ++-- .../appdev/chartexample/GradientActivity.kt | 6 +- .../chartexample/HalfPieChartActivity.kt | 6 +- .../HorizontalBarChartActivity.kt | 14 ++--- .../HorizontalBarNegativeChartActivity.kt | 14 ++--- .../chartexample/InvertedLineChartActivity.kt | 10 ++-- .../appdev/chartexample/LineChartActivity.kt | 6 +- .../chartexample/LineChartActivityColored.kt | 6 +- .../chartexample/LineChartDualAxisActivity.kt | 20 +++---- .../chartexample/LineChartTimeActivity.kt | 6 +- .../chartexample/ListViewBarChartActivity.kt | 6 +- .../ListViewMultiChartActivity.kt | 22 +++---- .../chartexample/MultiLineChartActivity.kt | 10 ++-- .../chartexample/PerformanceLineChart.kt | 6 +- .../appdev/chartexample/PieChartActivity.kt | 12 ++-- .../chartexample/PieChartRoundedActivity.kt | 12 ++-- .../chartexample/PiePolylineChartActivity.kt | 12 ++-- .../appdev/chartexample/RadarChartActivity.kt | 10 ++-- .../chartexample/RealtimeLineChartActivity.kt | 8 +-- .../chartexample/ScatterChartActivity.kt | 18 +++--- .../appdev/chartexample/ScrollViewActivity.kt | 6 +- .../SpecificPositionsLineChartActivity.kt | 12 ++-- .../appdev/chartexample/StackedBarActivity.kt | 12 ++-- .../StackedBarActivityNegative.kt | 36 +++++------ .../appdev/chartexample/TimeLineActivity.kt | 22 +++---- .../compose/HorizontalBarComposeActivity.kt | 14 ++--- .../HorizontalBarFullComposeActivity.kt | 6 +- .../compose/MultiLineComposeActivity.kt | 6 +- .../chartexample/custom/MyMarkerView.kt | 14 ++--- .../chartexample/custom/RadarMarkerView.kt | 8 +-- .../custom/StackedBarsMarkerView.kt | 18 +++--- .../chartexample/custom/TimeMarkerView.kt | 14 ++--- .../chartexample/custom/XYMarkerView.kt | 8 +-- .../formatter/MyValueFormatter.kt | 4 +- .../chartexample/fragments/SimpleFragment.kt | 18 +++--- .../info/appdev/charting/charts/BarChart.kt | 6 +- .../charting/charts/BarLineChartBase.kt | 8 +-- .../info/appdev/charting/charts/Chart.kt | 14 ++--- .../appdev/charting/charts/CombinedChart.kt | 4 +- .../charting/charts/HorizontalBarChart.kt | 8 +-- .../charting/charts/PieRadarChartBase.kt | 4 +- .../appdev/charting/components/IMarker.kt | 6 +- .../appdev/charting/components/MarkerImage.kt | 4 +- .../appdev/charting/components/MarkerView.kt | 4 +- .../info/appdev/charting/data/BarDataSet.kt | 12 ++-- .../data/{BarEntry.kt => BarEntryFloat.kt} | 6 +- .../data/BarLineScatterCandleBubbleData.kt | 4 +- .../data/BarLineScatterCandleBubbleDataSet.kt | 2 +- .../info/appdev/charting/data/BaseDataSet.kt | 2 +- .../appdev/charting/data/BubbleDataSet.kt | 8 +-- .../{BubbleEntry.kt => BubbleEntryFloat.kt} | 6 +- .../appdev/charting/data/CandleDataSet.kt | 10 ++-- .../{CandleEntry.kt => CandleEntryFloat.kt} | 6 +- .../info/appdev/charting/data/ChartData.kt | 26 ++++---- .../info/appdev/charting/data/CombinedData.kt | 12 ++-- .../info/appdev/charting/data/DataSet.kt | 16 ++--- .../charting/data/{Entry.kt => EntryFloat.kt} | 32 +++++----- .../info/appdev/charting/data/LineDataSet.kt | 6 +- .../appdev/charting/data/LineRadarDataSet.kt | 2 +- .../data/LineScatterCandleRadarDataSet.kt | 2 +- .../info/appdev/charting/data/PieData.kt | 2 +- .../info/appdev/charting/data/PieDataSet.kt | 8 +-- .../data/{PieEntry.kt => PieEntryFloat.kt} | 6 +- .../info/appdev/charting/data/RadarData.kt | 2 +- .../info/appdev/charting/data/RadarDataSet.kt | 6 +- .../{RadarEntry.kt => RadarEntryFloat.kt} | 6 +- .../appdev/charting/data/ScatterDataSet.kt | 6 +- .../charting/formatter/ColorFormatter.kt | 6 +- .../formatter/DefaultValueFormatter.kt | 4 +- .../charting/formatter/IValueFormatter.kt | 6 +- .../charting/formatter/LargeValueFormatter.kt | 4 +- .../charting/formatter/PercentFormatter.kt | 4 +- .../formatter/StackedValueFormatter.kt | 10 ++-- .../charting/highlight/ChartHighlighter.kt | 4 +- .../highlight/HorizontalBarHighlighter.kt | 6 +- .../charting/highlight/PieHighlighter.kt | 8 +-- .../charting/highlight/RadarHighlighter.kt | 8 +-- .../interfaces/datasets/IBarDataSet.kt | 4 +- .../IBarLineScatterCandleBubbleDataSet.kt | 4 +- .../interfaces/datasets/IBubbleDataSet.kt | 4 +- .../interfaces/datasets/ICandleDataSet.kt | 5 +- .../charting/interfaces/datasets/IDataSet.kt | 4 +- .../interfaces/datasets/ILineDataSet.kt | 4 +- .../interfaces/datasets/ILineRadarDataSet.kt | 4 +- .../ILineScatterCandleRadarDataSet.kt | 4 +- .../interfaces/datasets/IPieDataSet.kt | 4 +- .../interfaces/datasets/IRadarDataSet.kt | 4 +- .../interfaces/datasets/IScatterDataSet.kt | 4 +- .../listener/BarLineChartTouchListener.kt | 6 +- .../listener/OnChartValueSelectedListener.kt | 6 +- .../charting/listener/OnDrawListener.kt | 8 +-- .../BarLineScatterCandleBubbleRenderer.kt | 6 +- .../appdev/charting/renderer/DataRenderer.kt | 8 +-- .../charting/renderer/LineChartRenderer.kt | 42 ++++++------- .../charting/renderer/PieChartRenderer.kt | 2 +- .../charting/utils/AssetManagerUtils.kt | 18 +++--- .../appdev/charting/utils/EntryXComparator.kt | 8 +-- .../info/appdev/charting/utils/Transformer.kt | 4 +- .../info/appdev/charting/test/BarDataTest.kt | 10 ++-- .../appdev/charting/test/ChartDataTest.kt | 44 +++++++------- .../info/appdev/charting/test/DataSetTest.kt | 60 +++++++++---------- .../charting/compose/BarChartComposable.kt | 8 +-- .../charting/compose/BubbleChartComposable.kt | 6 +- .../compose/CandleStickChartComposable.kt | 6 +- .../compose/CombinedChartComposable.kt | 6 +- .../compose/HorizontalBarChartComposable.kt | 6 +- .../charting/compose/LineChartComposable.kt | 8 +-- .../charting/compose/PieChartComposable.kt | 8 +-- .../charting/compose/RadarChartComposable.kt | 6 +- .../compose/ScatterChartComposable.kt | 6 +- .../compose/examples/ChartExamples.kt | 36 +++++------ 123 files changed, 622 insertions(+), 623 deletions(-) rename chartLib/src/main/kotlin/info/appdev/charting/data/{BarEntry.kt => BarEntryFloat.kt} (97%) rename chartLib/src/main/kotlin/info/appdev/charting/data/{BubbleEntry.kt => BubbleEntryFloat.kt} (90%) rename chartLib/src/main/kotlin/info/appdev/charting/data/{CandleEntry.kt => CandleEntryFloat.kt} (95%) rename chartLib/src/main/kotlin/info/appdev/charting/data/{Entry.kt => EntryFloat.kt} (80%) rename chartLib/src/main/kotlin/info/appdev/charting/data/{PieEntry.kt => PieEntryFloat.kt} (92%) rename chartLib/src/main/kotlin/info/appdev/charting/data/{RadarEntry.kt => RadarEntryFloat.kt} (80%) diff --git a/app/src/main/kotlin/info/appdev/chartexample/AnotherBarActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/AnotherBarActivity.kt index f0cb980374..5db7c77a8c 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/AnotherBarActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/AnotherBarActivity.kt @@ -16,7 +16,7 @@ import info.appdev.chartexample.notimportant.DemoBase import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.data.BarData import info.appdev.charting.data.BarDataSet -import info.appdev.charting.data.BarEntry +import info.appdev.charting.data.BarEntryFloat import info.appdev.charting.interfaces.datasets.IBarDataSet import info.appdev.charting.utils.ColorTemplate @@ -62,13 +62,13 @@ class AnotherBarActivity : DemoBase(), OnSeekBarChangeListener { binding.tvXMax.text = binding.seekBarX.progress.toString() binding.tvYMax.text = binding.seekBarY.progress.toString() - val values = ArrayList() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0..() + val values = ArrayList() val sampleValues = getValues(100) var i = start.toInt() @@ -130,9 +130,9 @@ class BarChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSelect val `val` = (sampleValues[i]!!.toFloat() * (range + 1)) if (`val` * 100 < 25) { - values.add(BarEntry(i.toFloat(), `val`, ResourcesCompat.getDrawable(resources, R.drawable.star, null))) + values.add(BarEntryFloat(i.toFloat(), `val`, ResourcesCompat.getDrawable(resources, R.drawable.star, null))) } else { - values.add(BarEntry(i.toFloat(), `val`)) + values.add(BarEntryFloat(i.toFloat(), `val`)) } i++ } @@ -281,10 +281,10 @@ class BarChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSelect private val onValueSelectedRectF = RectF() - override fun onValueSelected(entry: Entry, highlight: Highlight) { + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { val bounds = onValueSelectedRectF - binding.chart1.getBarBounds(entry as BarEntry, bounds) - val position = binding.chart1.getPosition(entry, AxisDependency.LEFT) + binding.chart1.getBarBounds(entryFloat as BarEntryFloat, bounds) + val position = binding.chart1.getPosition(entryFloat, AxisDependency.LEFT) Timber.i("bounds $bounds") Timber.i("position = $position") diff --git a/app/src/main/kotlin/info/appdev/chartexample/BarChartActivityMultiDataset.kt b/app/src/main/kotlin/info/appdev/chartexample/BarChartActivityMultiDataset.kt index 522a876def..eba9e3c41e 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/BarChartActivityMultiDataset.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/BarChartActivityMultiDataset.kt @@ -19,8 +19,8 @@ import info.appdev.charting.components.AxisBase import info.appdev.charting.components.Legend import info.appdev.charting.data.BarData import info.appdev.charting.data.BarDataSet -import info.appdev.charting.data.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.formatter.IAxisValueFormatter import info.appdev.charting.formatter.LargeValueFormatter import info.appdev.charting.highlight.Highlight @@ -110,19 +110,19 @@ class BarChartActivityMultiDataset : DemoBase(), OnSeekBarChangeListener, OnChar binding.tvXMax.text = String.format(Locale.ENGLISH, "%d-%d", startYear, endYear) binding.tvYMax.text = binding.seekBarY.progress.toString() - val values1 = ArrayList() - val values2 = ArrayList() - val values3 = ArrayList() - val values4 = ArrayList() + val values1 = ArrayList() + val values2 = ArrayList() + val values3 = ArrayList() + val values4 = ArrayList() val randomMultiplier = binding.seekBarY.progress * 100000f val sampleValues = getValues(100 + 2) for (i in startYear.. + private lateinit var dataSinus: MutableList private lateinit var binding: ActivityBarchartSinusBinding @@ -87,7 +87,7 @@ class BarChartActivitySinus : DemoBase(), OnSeekBarChangeListener { } private fun setData(count: Int) { - val entries = ArrayList() + val entries = ArrayList() for (i in 0..) { - val values = ArrayList() + val values = ArrayList() val colors: MutableList = ArrayList() val green = Color.rgb(110, 190, 102) @@ -95,7 +95,7 @@ class BarChartPositiveNegative : DemoBase() { for (i in dataList.indices) { val d = dataList[i] - val entry = BarEntry(d.xValue, d.yValue) + val entry = BarEntryFloat(d.xValue, d.yValue) values.add(entry) // specific colors @@ -136,7 +136,7 @@ class BarChartPositiveNegative : DemoBase() { private class ValueFormatter : IValueFormatter { private val mFormat: DecimalFormat = DecimalFormat("######.0") - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { return mFormat.format(value.toDouble()) } } diff --git a/app/src/main/kotlin/info/appdev/chartexample/BubbleChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/BubbleChartActivity.kt index a478a0f649..7207e77449 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/BubbleChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/BubbleChartActivity.kt @@ -19,8 +19,8 @@ import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.data.BubbleData import info.appdev.charting.data.BubbleDataSet -import info.appdev.charting.data.BubbleEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BubbleEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.interfaces.datasets.IBubbleDataSet import info.appdev.charting.listener.OnChartValueSelectedListener @@ -82,14 +82,14 @@ class BubbleChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSel binding.tvXMax.text = count.toString() binding.tvYMax.text = range.toString() - val values1 = ArrayList() - val values2 = ArrayList() - val values3 = ArrayList() + val values1 = ArrayList() + val values2 = ArrayList() + val values3 = ArrayList() val sampleValues = getValues(100) for (i in 0..() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0..() + val entries = ArrayList() - for (index in 0..() - val entries2 = ArrayList() + val entries1 = ArrayList() + val entries2 = ArrayList() for (index in 0..() + val entries = ArrayList() var index = 0f while (index < sampleCount) { - entries.add(Entry(index + 0.25f, values[(index * 2).roundToInt()]!!.toFloat() * 10 + 55)) + entries.add(EntryFloat(index + 0.25f, values[(index * 2).roundToInt()]!!.toFloat() * 10 + 55)) index += 0.5f } @@ -183,11 +183,11 @@ class CombinedChartActivity : DemoBase() { private fun generateCandleData(): CandleData { val d = CandleData() - val entries = ArrayList() + val entries = ArrayList() var index = 0 while (index < sampleCount) { - entries.add(CandleEntry(index + 1f, 90f, 70f, 85f, 75f)) + entries.add(CandleEntryFloat(index + 1f, 90f, 70f, 85f, 75f)) index += 2 } @@ -205,12 +205,12 @@ class CombinedChartActivity : DemoBase() { private fun generateBubbleData(): BubbleData { val bd = BubbleData() - val entries = ArrayList() + val entries = ArrayList() for (index in 0..() + val values = ArrayList() val sampleValues = getMuchValues(count) for (i in 0 until count) { val `val` = (sampleValues[i]!!.toFloat() * (range + 1)) + 20 - values.add(Entry(i.toFloat(), `val`)) + values.add(EntryFloat(i.toFloat(), `val`)) } val set1: LineDataSet diff --git a/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt b/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt index a3f09c0987..1c004b4eed 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt @@ -5,7 +5,7 @@ import android.graphics.Color import android.graphics.DashPathEffect import androidx.core.content.ContextCompat import info.appdev.charting.charts.LineChart -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.formatter.IFillFormatter @@ -164,15 +164,15 @@ class DataTools { fun setData(context: Context, lineChart: LineChart, count: Int = VAL_COUNT, range: Float = VAL_RANGE) { Timber.d("count=$count range=$range") - val values = ArrayList() + val values = ArrayList() if (count == VAL_COUNT) { VAL_FIX.forEachIndexed { index, d -> - values.add(Entry(index.toFloat(), d.toFloat(), ContextCompat.getDrawable(context, R.drawable.star))) + values.add(EntryFloat(index.toFloat(), d.toFloat(), ContextCompat.getDrawable(context, R.drawable.star))) } } else { for (i in 0 until count) { val value = (Math.random() * range).toFloat() - 30 - values.add(Entry(i.toFloat(), value, ContextCompat.getDrawable(context, R.drawable.star))) + values.add(EntryFloat(i.toFloat(), value, ContextCompat.getDrawable(context, R.drawable.star))) } } lineChart.data?.let { @@ -190,7 +190,7 @@ class DataTools { } private fun createDataset( - values: ArrayList, + values: ArrayList, lineChart: LineChart, context: Context ) { diff --git a/app/src/main/kotlin/info/appdev/chartexample/DrawChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/DrawChartActivity.kt index 9194ee49cb..826c3c09bc 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/DrawChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/DrawChartActivity.kt @@ -10,7 +10,7 @@ import androidx.core.content.ContextCompat import info.appdev.chartexample.databinding.ActivityDrawChartBinding import info.appdev.chartexample.notimportant.DemoBase import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.highlight.Highlight @@ -57,7 +57,7 @@ class DrawChartActivity : DemoBase(), OnChartValueSelectedListener, OnDrawListen } private fun initWithDummyData() { - val values = ArrayList() + val values = ArrayList() // create a dataset and give it a type (0) val set1 = LineDataSet(values, "DataSet") @@ -116,15 +116,15 @@ class DrawChartActivity : DemoBase(), OnChartValueSelectedListener, OnDrawListen saveToGallery(binding.chart1, "DrawChartActivity") } - override fun onValueSelected(entry: Entry, highlight: Highlight) { - Timber.i(("Value: ${entry.y}, xIndex: ${entry.x}, DataSet index:${highlight.dataSetIndex}")) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + Timber.i(("Value: ${entryFloat.y}, xIndex: ${entryFloat.x}, DataSet index:${highlight.dataSetIndex}")) } override fun onNothingSelected() = Unit /** callback for each new entry drawn with the finger */ - override fun onEntryAdded(entry: Entry) { - Timber.i(entry.toString()) + override fun onEntryAdded(entryFloat: EntryFloat) { + Timber.i(entryFloat.toString()) } /** callback when a DataSet has been drawn (when lifting the finger) */ @@ -135,7 +135,7 @@ class DrawChartActivity : DemoBase(), OnChartValueSelectedListener, OnDrawListen binding.chart1.data?.let { binding.chart1.legendRenderer?.computeLegend(it) } } - override fun onEntryMoved(entry: Entry) { - Timber.i("Point moved $entry") + override fun onEntryMoved(entryFloat: EntryFloat) { + Timber.i("Point moved $entryFloat") } } diff --git a/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt index aa371611fa..82b3f64ae3 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt @@ -14,7 +14,7 @@ import info.appdev.chartexample.DataTools.Companion.getValues import info.appdev.chartexample.databinding.ActivityLinechartNoseekbarBinding import info.appdev.chartexample.notimportant.DemoBase import info.appdev.charting.components.YAxis.AxisDependency -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.highlight.Highlight @@ -66,7 +66,7 @@ class DynamicalAddingActivity : DemoBase(), OnChartValueSelectedListener { val value = (sampleValues[cycleValue]!!.toFloat() * 50) + 50f * (lastDataSetIndex + 1) - data.addEntry(Entry(lastSet.entryCount.toFloat(), value), lastDataSetIndex) + data.addEntry(EntryFloat(lastSet.entryCount.toFloat(), value), lastDataSetIndex) data.notifyDataChanged() // let the chart know it's data has changed @@ -109,12 +109,12 @@ class DynamicalAddingActivity : DemoBase(), OnChartValueSelectedListener { val count = (data.dataSetCount + 1) val amount = data.getDataSetByIndex(0)?.entryCount ?: 0 - val values = ArrayList() + val values = ArrayList() for (i in 0..() + val valuesArray1 = ArrayList() val sampleValues = getValues(count + 2) for (i in 0..() + val valuesArray2 = ArrayList() for (i in 0..(200) + val entries = kotlin.collections.ArrayList(200) val k = 2.5f for (i in 0 until 200) { - entries.add(Entry(i.toFloat(), i * k)) + entries.add(EntryFloat(i.toFloat(), i * k)) } val dataSet = LineDataSet(entries, "Linear").apply { diff --git a/app/src/main/kotlin/info/appdev/chartexample/HalfPieChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/HalfPieChartActivity.kt index ef11617bb0..41d041fa1e 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/HalfPieChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/HalfPieChartActivity.kt @@ -20,7 +20,7 @@ import info.appdev.charting.animation.Easing import info.appdev.charting.components.Legend import info.appdev.charting.data.PieData import info.appdev.charting.data.PieDataSet -import info.appdev.charting.data.PieEntry +import info.appdev.charting.data.PieEntryFloat import info.appdev.charting.formatter.PercentFormatter import info.appdev.charting.utils.ColorTemplate @@ -83,11 +83,11 @@ class HalfPieChartActivity : DemoBase() { private fun setData(range: Float) { val count = 4 - val values = ArrayList() + val values = ArrayList() val sampleValues = getValues(count) for (i in 0..() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0..() + val values = ArrayList() val sampleValues = getValues(count + 2) for (i in 0..() + val entries = ArrayList() val sampleValues = getValues(count + 2) for (i in 0..() + val values = ArrayList() val sampleValues = getValues(count) for (i in 0..() + val values1 = ArrayList() val sampleValues = getValues(count) for (i in 0..() + val values2 = ArrayList() for (i in 0..() + val values3 = ArrayList() for (i in 0..() + val values = ArrayList() // count = hours val to = (now + count).toFloat() @@ -118,7 +118,7 @@ class LineChartTimeActivity : DemoBase(), OnSeekBarChangeListener { (valuesData[x.roundToInt()])!!.toFloat() * 50 + 50 else (Math.random() * 50 + 50).toFloat() // manually triggered - values.add(Entry(x, y)) // add one entry per hour + values.add(EntryFloat(x, y)) // add one entry per hour x++ } diff --git a/app/src/main/kotlin/info/appdev/chartexample/ListViewBarChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/ListViewBarChartActivity.kt index 08b1c2040e..af361132d9 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/ListViewBarChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/ListViewBarChartActivity.kt @@ -19,7 +19,7 @@ import info.appdev.charting.charts.BarChart import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.data.BarData import info.appdev.charting.data.BarDataSet -import info.appdev.charting.data.BarEntry +import info.appdev.charting.data.BarEntryFloat import info.appdev.charting.interfaces.datasets.IBarDataSet import info.appdev.charting.utils.ColorTemplate @@ -110,11 +110,11 @@ class ListViewBarChartActivity : DemoBase() { */ private fun generateData(cnt: Int): BarData { val count = 12 - val entries = ArrayList() + val entries = ArrayList() val sampleValues = getValues(count) for (i in 0..() + val values1 = ArrayList() val count = 12 val sampleValues = getValues(count) for (i in 0..() + val values2 = ArrayList() for (i in 0..() + val entries = ArrayList() val sampleValues = getValues(count) for (i in 0..() + val entries = ArrayList() val sampleValues = getValues(cnt) for (i in 0..() for (datasetNumber in 0..2) { - val values = ArrayList() + val values = ArrayList() val sampleValues = when (datasetNumber) { 1 -> getValues(100).reversedArray() 2 -> generateSineWaves(3, 30).toTypedArray() @@ -96,7 +96,7 @@ class MultiLineChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartGestu for (i in 0..() + val values = ArrayList() val sampleValues = getMuchValues(count) for (i in 0..() + val entries = ArrayList() val sampleValues = getValues(100) // NOTE: The order of the entries when being added to the entries array determines their position around the center of // the chart. for (i in 0..() + val entries = ArrayList() val sampleValues = getValues(100) // NOTE: The order of the entries when being added to the entries array determines their position around the center of // the chart. for (i in 0..() + val entries = ArrayList() // NOTE: The order of the entries when being added to the entries array determines their position around the center of // the chart. for (i in 0..() - val entries2 = ArrayList() + val entries1 = ArrayList() + val entries2 = ArrayList() // NOTE: The order of the entries when being added to the entries array determines their position around the center of // the chart. for (i in 0..() - val values2 = ArrayList() - val values3 = ArrayList() + val values1 = ArrayList() + val values2 = ArrayList() + val values3 = ArrayList() val sampleValues = getValues(100 + 2) for (i in 0..() + val values = ArrayList() for (i in 0..() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0 until count) { val `val` = (sampleValues[i]!!.toFloat() * range) + 3 - values.add(Entry(i.toFloat(), `val`)) + values.add(EntryFloat(i.toFloat(), `val`)) } binding.chart1.data?.let { if (it.dataSetCount > 0) { @@ -245,7 +245,7 @@ class SpecificPositionsLineChartActivity : DemoBase(), OnSeekBarChangeListener, } } - private fun createDataset(values: ArrayList) { + private fun createDataset(values: ArrayList) { // create a dataset and give it a type val set11 = LineDataSet(values, "DataSet 1") @@ -316,8 +316,8 @@ class SpecificPositionsLineChartActivity : DemoBase(), OnSeekBarChangeListener, Timber.i("dX: $dX, dY: $dY") } - override fun onValueSelected(entry: Entry, highlight: Highlight) { - Timber.i(entry.toString()) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + Timber.i(entryFloat.toString()) Timber.i("LOWHIGH low: ${binding.chart1.lowestVisibleX}, high: ${binding.chart1.highestVisibleX}") Timber.i("MIN MAX xmin: ${binding.chart1.xChartMin}, xmax: ${binding.chart1.xChartMax}, ymin: ${binding.chart1.yChartMin}, ymax: ${binding.chart1.yChartMax}") } diff --git a/app/src/main/kotlin/info/appdev/chartexample/StackedBarActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/StackedBarActivity.kt index 443cc16ca3..b28b1ce4c3 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/StackedBarActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/StackedBarActivity.kt @@ -21,8 +21,8 @@ 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.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.interfaces.datasets.IBarDataSet import info.appdev.charting.listener.OnChartValueSelectedListener @@ -91,7 +91,7 @@ class StackedBarActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSele binding.tvXMax.text = binding.seekBarX.progress.toString() binding.tvYMax.text = binding.seekBarY.progress.toString() - val values = ArrayList() + val values = ArrayList() val sampleValues = getValues(100 + 2) for (i in 0..() - values.add(BarEntry(5f, floatArrayOf(-10f, 10f))) - values.add(BarEntry(15f, floatArrayOf(-12f, 13f))) - values.add(BarEntry(25f, floatArrayOf(-15f, 15f))) - values.add(BarEntry(35f, floatArrayOf(-17f, 17f))) - values.add(BarEntry(45f, floatArrayOf(-19f, 20f))) - values.add(BarEntry(45f, floatArrayOf(-19f, 20f), ResourcesCompat.getDrawable(resources, R.drawable.star, null))) - values.add(BarEntry(55f, floatArrayOf(-19f, 19f))) - values.add(BarEntry(65f, floatArrayOf(-16f, 16f))) - values.add(BarEntry(75f, floatArrayOf(-13f, 14f))) - values.add(BarEntry(85f, floatArrayOf(-10f, 11f))) - values.add(BarEntry(95f, floatArrayOf(-5f, 6f))) - values.add(BarEntry(105f, floatArrayOf(-1f, 2f))) + val values = ArrayList() + values.add(BarEntryFloat(5f, floatArrayOf(-10f, 10f))) + values.add(BarEntryFloat(15f, floatArrayOf(-12f, 13f))) + values.add(BarEntryFloat(25f, floatArrayOf(-15f, 15f))) + values.add(BarEntryFloat(35f, floatArrayOf(-17f, 17f))) + values.add(BarEntryFloat(45f, floatArrayOf(-19f, 20f))) + values.add(BarEntryFloat(45f, floatArrayOf(-19f, 20f), ResourcesCompat.getDrawable(resources, R.drawable.star, null))) + values.add(BarEntryFloat(55f, floatArrayOf(-19f, 19f))) + values.add(BarEntryFloat(65f, floatArrayOf(-16f, 16f))) + values.add(BarEntryFloat(75f, floatArrayOf(-13f, 14f))) + values.add(BarEntryFloat(85f, floatArrayOf(-10f, 11f))) + values.add(BarEntryFloat(95f, floatArrayOf(-5f, 6f))) + values.add(BarEntryFloat(105f, floatArrayOf(-1f, 2f))) val set = BarDataSet(values, "Age Distribution") set.isDrawIcons = false @@ -194,8 +194,8 @@ class StackedBarActivityNegative : DemoBase(), OnChartValueSelectedListener { saveToGallery(binding.chart1, "StackedBarActivityNegative") } - override fun onValueSelected(entry: Entry, highlight: Highlight) { - val barEntry = entry as BarEntry + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + val barEntry = entryFloat as BarEntryFloat Timber.i("Value: ${abs(barEntry.yVals!![highlight.stackIndex])}") } @@ -205,7 +205,7 @@ class StackedBarActivityNegative : DemoBase(), OnChartValueSelectedListener { private val decimalFormat: DecimalFormat = DecimalFormat("###") // data - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { return decimalFormat.format(abs(value).toDouble()) + "m" } diff --git a/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt index 7b71841fdc..096c308e71 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt @@ -17,7 +17,7 @@ import info.appdev.charting.components.Description import info.appdev.charting.components.Legend.LegendForm import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.components.YAxis -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.formatter.IFillFormatter @@ -97,24 +97,24 @@ class TimeLineActivity : DemoBase() { val sampleEntries = if (sinus) generateSineWaves(3, 30).mapIndexed { index, data -> val valueY = (data.toFloat() * range) + 50 - Entry(timeOffset + index.toFloat() * 1000, valueY) + EntryFloat(timeOffset + index.toFloat() * 1000, valueY) } else { - var previousEntry: Entry? = null + var previousEntryFloat: EntryFloat? = null getSawtoothValues(14).mapIndexed { index, data -> val valueY = data.toFloat() * 20 - val entry = previousEntry?.let { + val entryFloat = previousEntryFloat?.let { // nay third value is 0, so we add here more than 1 second, otherwise we have a one-second entry if (index % 3 == 0) { - Entry(it.x + 3000, valueY) + EntryFloat(it.x + 3000, valueY) } else - Entry(it.x + 1000, valueY) + EntryFloat(it.x + 1000, valueY) } ?: run { - Entry(timeOffset + index.toFloat() * 1000, valueY) + EntryFloat(timeOffset + index.toFloat() * 1000, valueY) } - previousEntry = entry + previousEntryFloat = entryFloat // Now you can use 'prev' which holds the previous Entry - entry + entryFloat } } @@ -209,9 +209,9 @@ class TimeLineActivity : DemoBase() { val first = this[0] val second = this[1] // needed to get time diff val last = this[size - 1] - val timeDiff = (second as Entry).x - (first as Entry).x + val timeDiff = (second as EntryFloat).x - (first as EntryFloat).x removeAt(0) - first.x = (last as Entry).x + timeDiff + first.x = (last as EntryFloat).x + timeDiff add(first) } diff --git a/app/src/main/kotlin/info/appdev/chartexample/compose/HorizontalBarComposeActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/compose/HorizontalBarComposeActivity.kt index af8d6733d1..713bce7423 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/compose/HorizontalBarComposeActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/compose/HorizontalBarComposeActivity.kt @@ -44,8 +44,8 @@ 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.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.interfaces.datasets.IBarDataSet import info.appdev.charting.listener.OnChartValueSelectedListener @@ -268,14 +268,14 @@ class HorizontalBarComposeActivity : DemoBaseCompose() { private fun setupChart(chart: HorizontalBarChart) { chart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) { + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { val bounds = RectF() - chart.getBarBounds(entry as BarEntry, bounds) + chart.getBarBounds(entryFloat as BarEntryFloat, bounds) val data = chart.barData if (data != null) { val position = chart.getPosition( - entry, data.getDataSetByIndex(highlight.dataSetIndex)?.axisDependency + entryFloat, data.getDataSetByIndex(highlight.dataSetIndex)?.axisDependency ) Timber.tag("bounds $bounds") @@ -335,12 +335,12 @@ class HorizontalBarComposeActivity : DemoBaseCompose() { val barWidth = 9f val spaceForBar = 10f - val values = ArrayList() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0..() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0..() for (datasetNumber in 0..2) { - val values = ArrayList() + val values = ArrayList() val sampleValues = when (datasetNumber) { 1 -> getValues(100).reversedArray() 2 -> generateSineWaves(3, 30).toTypedArray() @@ -338,7 +338,7 @@ class MultiLineComposeActivity : DemoBaseCompose() { for (i in 0.. - val myIndex = dataset?.getEntryIndex(entry) + val dataset = this.chartView?.data?.dataSets[0] as? IDataSet + val myIndex = dataset?.getEntryIndex(entryFloat) val nextEntry = myIndex?.let { if (it < dataset.entryCount - 1) dataset.getEntryForIndex(myIndex + 1) @@ -30,9 +30,9 @@ class TimeMarkerView(context: Context?, layoutResource: Int, val format: String 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) + val duration = if (nextEntry != null) " - duration:${(nextEntry.x - entryFloat.x)}" else "" + tvContent.text = "${simpleDateFormat.format(entryFloat.x)}$duration" + super.refreshContent(entryFloat, highlight) } override var offset: PointF = PointF() diff --git a/app/src/main/kotlin/info/appdev/chartexample/custom/XYMarkerView.kt b/app/src/main/kotlin/info/appdev/chartexample/custom/XYMarkerView.kt index ffc7ce814c..68a9ba4db2 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/custom/XYMarkerView.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/custom/XYMarkerView.kt @@ -5,7 +5,7 @@ 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.data.EntryFloat import info.appdev.charting.formatter.IAxisValueFormatter import info.appdev.charting.highlight.Highlight import info.appdev.charting.utils.PointF @@ -21,10 +21,10 @@ class XYMarkerView(context: Context?, private val xAxisValueFormatter: IAxisValu private val format: DecimalFormat = DecimalFormat("###.0") // runs every time the MarkerView is redrawn, can be used to update the content (user-interface) - override fun refreshContent(entry: Entry, highlight: Highlight) { - tvContent.text = String.format("x: %s, y: %s", xAxisValueFormatter.getFormattedValue(entry.x, null), format.format(entry.y.toDouble())) + override fun refreshContent(entryFloat: EntryFloat, highlight: Highlight) { + tvContent.text = String.format("x: %s, y: %s", xAxisValueFormatter.getFormattedValue(entryFloat.x, null), format.format(entryFloat.y.toDouble())) - super.refreshContent(entry, highlight) + super.refreshContent(entryFloat, highlight) } override var offset: PointF = PointF() diff --git a/app/src/main/kotlin/info/appdev/chartexample/formatter/MyValueFormatter.kt b/app/src/main/kotlin/info/appdev/chartexample/formatter/MyValueFormatter.kt index a32ce54136..a61d8c58c2 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/formatter/MyValueFormatter.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/formatter/MyValueFormatter.kt @@ -1,6 +1,6 @@ package info.appdev.chartexample.formatter -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.formatter.IValueFormatter import info.appdev.charting.utils.ViewPortHandler import java.text.DecimalFormat @@ -8,7 +8,7 @@ import java.text.DecimalFormat class MyValueFormatter : IValueFormatter { private val decimalFormat = DecimalFormat("###,###,###,##0.0") - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { return decimalFormat.format(value.toDouble()) + " $" } } diff --git a/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt b/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt index 6a9053ea57..e5f5797ef3 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt @@ -11,13 +11,13 @@ import info.appdev.chartexample.DataTools.Companion.getValues import info.appdev.charting.charts.ScatterChart.ScatterShape import info.appdev.charting.data.BarData import info.appdev.charting.data.BarDataSet -import info.appdev.charting.data.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.data.PieData import info.appdev.charting.data.PieDataSet -import info.appdev.charting.data.PieEntry +import info.appdev.charting.data.PieEntryFloat import info.appdev.charting.data.ScatterData import info.appdev.charting.data.ScatterDataSet import info.appdev.charting.interfaces.datasets.IBarDataSet @@ -41,10 +41,10 @@ abstract class SimpleFragment : Fragment() { val sets = ArrayList() for (i in 0..() + val entries = ArrayList() for (j in 0..() + val entries = ArrayList() for (j in 0..() + val entries1 = ArrayList() for (i in 0.., BarDataProvider { * Returns the bounding box of the specified Entry in the specified DataSet. Returns null if the Entry could not be * found in the charts data. Performance-intensive code should use void getBarBounds(BarEntry, RectF) instead. */ - fun getBarBounds(barEntry: BarEntry): RectF { + fun getBarBounds(barEntry: BarEntryFloat): RectF { val bounds = RectF() getBarBounds(barEntry, bounds) @@ -157,7 +157,7 @@ open class BarChart : BarLineChartBase, BarDataProvider { * The passed outputRect will be assigned the values of the bounding box of the specified Entry in the specified DataSet. * The rect will be assigned Float.MIN_VALUE in all locations if the Entry could not be found in the charts data. */ - open fun getBarBounds(barEntry: BarEntry, outputRect: RectF) { + open fun getBarBounds(barEntry: BarEntryFloat, outputRect: RectF) { mData?.let { barData -> val set = barData.getDataSetForEntry(barEntry) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt index a4eab0f84b..cf38afb165 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt @@ -16,7 +16,7 @@ import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.components.YAxis import info.appdev.charting.components.YAxis.AxisDependency import info.appdev.charting.data.BarLineScatterCandleBubbleData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.ChartHighlighter import info.appdev.charting.interfaces.dataprovider.base.BarLineScatterCandleBubbleDataProvider import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet @@ -46,7 +46,7 @@ import kotlin.math.min */ @Suppress("unused") @SuppressLint("RtlHardcoded") -abstract class BarLineChartBase>> : Chart, +abstract class BarLineChartBase>> : Chart, BarLineScatterCandleBubbleDataProvider { /** * the maximum number of entries to which values will be drawn @@ -956,7 +956,7 @@ abstract class BarLineChartBase>> : ViewGroup, IBaseProvider { +abstract class Chart>> : ViewGroup, IBaseProvider { /** * Returns true if log-output is enabled for the chart, fals if not. */ @@ -527,7 +527,7 @@ abstract class Chart>> : ViewGroup, IBaseP */ fun highlightValue(high: Highlight?, callListener: Boolean) { var high = high - var entry: Entry? = null + var entryFloat: EntryFloat? = null if (high == null) { this.highlighted = null @@ -536,8 +536,8 @@ abstract class Chart>> : ViewGroup, IBaseP Timber.i("Highlighted: $high") } - entry = mData!!.getEntryForHighlight(high) - if (entry == null) { + entryFloat = mData!!.getEntryForHighlight(high) + if (entryFloat == null) { this.highlighted = null high = null } else { @@ -554,7 +554,7 @@ abstract class Chart>> : ViewGroup, IBaseP listener.onNothingSelected() } else { // notify the listener - listener.onValueSelected(entry!!, high!!) + listener.onValueSelected(entryFloat!!, high!!) } } // redraw the chart @@ -623,7 +623,7 @@ abstract class Chart>> : ViewGroup, IBaseP // Cast to non-star-projected type to allow calling getEntryIndex @Suppress("UNCHECKED_CAST") - val set = dataset as IDataSet + val set = dataset as IDataSet val entryIndex = set.getEntryIndex(entry) if (entryIndex > set.entryCount * mAnimator.phaseX) { diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/CombinedChart.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/CombinedChart.kt index 013bfc8816..5a008d2346 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/CombinedChart.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/CombinedChart.kt @@ -7,7 +7,7 @@ import info.appdev.charting.data.BarData import info.appdev.charting.data.BubbleData import info.appdev.charting.data.CandleData import info.appdev.charting.data.CombinedData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.ScatterData import info.appdev.charting.highlight.CombinedHighlighter @@ -488,7 +488,7 @@ open class CombinedChart : BarLineChartBase, CombinedDataProvider } @Suppress("UNCHECKED_CAST") - val set = dataset as IDataSet + val set = dataset as IDataSet val entryIndex = set.getEntryIndex(entry) // make sure entry not null diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/HorizontalBarChart.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/HorizontalBarChart.kt index 2ed51233dd..33506ae2f2 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/HorizontalBarChart.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/HorizontalBarChart.kt @@ -8,8 +8,8 @@ import info.appdev.charting.components.Legend.LegendOrientation import info.appdev.charting.components.Legend.LegendVerticalAlignment import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.components.YAxis.AxisDependency -import info.appdev.charting.data.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.highlight.HorizontalBarHighlighter import info.appdev.charting.renderer.HorizontalBarChartRenderer @@ -206,7 +206,7 @@ open class HorizontalBarChart : BarChart { return floatArrayOf(high.drawY, high.drawX) } - override fun getBarBounds(barEntry: BarEntry, outputRect: RectF) { + override fun getBarBounds(barEntry: BarEntryFloat, outputRect: RectF) { mData?.let { data -> val set = data.getDataSetForEntry(barEntry) @@ -231,7 +231,7 @@ open class HorizontalBarChart : BarChart { /** * Returns a recyclable PointF instance. */ - override fun getPosition(e: Entry?, axis: AxisDependency?): PointF? { + override fun getPosition(e: EntryFloat?, axis: AxisDependency?): PointF? { if (e == null) { return null } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/PieRadarChartBase.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/PieRadarChartBase.kt index 76b043d60b..a5d0d82f51 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/PieRadarChartBase.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/PieRadarChartBase.kt @@ -10,7 +10,7 @@ import info.appdev.charting.components.Legend.LegendHorizontalAlignment import info.appdev.charting.components.Legend.LegendOrientation import info.appdev.charting.components.Legend.LegendVerticalAlignment import info.appdev.charting.data.ChartData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.datasets.IDataSet import info.appdev.charting.listener.PieRadarChartTouchListener import info.appdev.charting.utils.PointF @@ -30,7 +30,7 @@ import kotlin.math.sqrt /** * Baseclass of PieChart and RadarChart. */ -abstract class PieRadarChartBase>> +abstract class PieRadarChartBase>> : Chart { /** * holds the normalized version of the current rotation angle of the chart diff --git a/chartLib/src/main/kotlin/info/appdev/charting/components/IMarker.kt b/chartLib/src/main/kotlin/info/appdev/charting/components/IMarker.kt index 61af265af9..52cc7dc8ab 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/components/IMarker.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/components/IMarker.kt @@ -1,7 +1,7 @@ package info.appdev.charting.components import android.graphics.Canvas -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.utils.PointF @@ -27,12 +27,12 @@ interface IMarker { /** * This method enables a specified custom IMarker to update it's content every time the IMarker is redrawn. * - * @param entry The Entry the IMarker belongs to. This can also be any subclass of Entry, like BarEntry or + * @param entryFloat The Entry the IMarker belongs to. This can also be any subclass of Entry, like BarEntry or * CandleEntry, simply cast it at runtime. * @param highlight The highlight object contains information about the highlighted value such as it's dataset-index, the * selected range or stack-index (only stacked bar entries). */ - fun refreshContent(entry: Entry, highlight: Highlight) + fun refreshContent(entryFloat: EntryFloat, highlight: Highlight) /** * Draws the IMarker on the given position on the screen with the given Canvas object. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerImage.kt b/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerImage.kt index c6ce670267..0db59d9b98 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerImage.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerImage.kt @@ -5,7 +5,7 @@ import android.graphics.Canvas import android.graphics.Rect import android.graphics.drawable.Drawable import info.appdev.charting.charts.Chart -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.utils.FSize import info.appdev.charting.utils.PointF @@ -94,7 +94,7 @@ class MarkerImage(private var mContext: Context, drawableResourceId: Int) : IMar return mOffset2 } - override fun refreshContent(entry: Entry, highlight: Highlight) = Unit + override fun refreshContent(entryFloat: EntryFloat, highlight: Highlight) = Unit override fun draw(canvas: Canvas, posX: Float, posY: Float) { if (drawable == null) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerView.kt b/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerView.kt index 7592d71e40..f7cf73ea0e 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerView.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/components/MarkerView.kt @@ -5,7 +5,7 @@ import android.graphics.Canvas import android.view.LayoutInflater import android.widget.RelativeLayout import info.appdev.charting.charts.Chart -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.utils.PointF import java.lang.ref.WeakReference @@ -74,7 +74,7 @@ open class MarkerView(context: Context?, layoutResource: Int) : RelativeLayout(c return mOffset2 } - override fun refreshContent(entry: Entry, highlight: Highlight) { + override fun refreshContent(entryFloat: EntryFloat, highlight: Highlight) { measure( MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BarDataSet.kt index c4114435ee..1e94ef0ca8 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BarDataSet.kt @@ -5,7 +5,7 @@ import androidx.annotation.ColorInt import info.appdev.charting.interfaces.datasets.IBarDataSet import info.appdev.charting.utils.Fill -open class BarDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), IBarDataSet { +open class BarDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), IBarDataSet { /** * the maximum number of bars that are stacked upon each other, this value * is calculated from the Entries that are added to the DataSet @@ -50,8 +50,8 @@ open class BarDataSet(yVals: MutableList, label: String) : BarLineScat calcEntryCountIncludingStacks(yVals) } - override fun copy(): DataSet? { - val entries: MutableList = mutableListOf() + override fun copy(): DataSet? { + val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } @@ -101,7 +101,7 @@ open class BarDataSet(yVals: MutableList, label: String) : BarLineScat * Calculates the total number of entries this DataSet represents, including * stacks. All values belonging to a stack are calculated separately. */ - private fun calcEntryCountIncludingStacks(yVals: MutableList) { + private fun calcEntryCountIncludingStacks(yVals: MutableList) { this.entryCountStacks = 0 for (i in yVals.indices) { @@ -115,7 +115,7 @@ open class BarDataSet(yVals: MutableList, label: String) : BarLineScat /** * calculates the maximum stackSize that occurs in the Entries array of this DataSet */ - private fun calcStackSize(yVals: MutableList) { + private fun calcStackSize(yVals: MutableList) { for (i in yVals.indices) { val vals = yVals[i].yVals @@ -123,7 +123,7 @@ open class BarDataSet(yVals: MutableList, label: String) : BarLineScat } } - override fun calcMinMax(entry: BarEntry) { + override fun calcMinMax(entry: BarEntryFloat) { if (!entry.y.isNaN()) { if (entry.yVals == null) { if (entry.y < yMin) yMin = entry.y diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryFloat.kt similarity index 97% rename from chartLib/src/main/kotlin/info/appdev/charting/data/BarEntry.kt rename to chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryFloat.kt index 1e4f78b3d9..1ce910a01b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryFloat.kt @@ -9,7 +9,7 @@ import kotlin.math.abs * Entry class for the BarChart. (especially stacked bars) */ @SuppressLint("ParcelCreator") -open class BarEntry : Entry { +open class BarEntryFloat : EntryFloat { /** * Returns the stacked values this BarEntry represents, or null, if only a single value is represented (then, use * getY()). @@ -123,8 +123,8 @@ open class BarEntry : Entry { /** * Returns an exact copy of the BarEntry. */ - override fun copy(): BarEntry { - val copied = BarEntry(x, y, data) + override fun copy(): BarEntryFloat { + val copied = BarEntryFloat(x, y, data) copied.setVals(this.yVals) return copied } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleData.kt index 96c08ef04b..f58db38602 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleData.kt @@ -7,8 +7,8 @@ import info.appdev.charting.interfaces.datasets.IDataSet * Baseclass for all Line, Bar, Scatter, Candle and Bubble data. */ abstract class BarLineScatterCandleBubbleData : ChartData<@UnsafeVariance T> - where T : IDataSet, - T : IBarLineScatterCandleBubbleDataSet { + where T : IDataSet, + T : IBarLineScatterCandleBubbleDataSet { constructor() : super() diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt index fbc22d82ee..40096e1968 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt @@ -7,7 +7,7 @@ import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataS /** * Baseclass of all DataSets for Bar-, Line-, Scatter- and CandleStickChart. */ -abstract class BarLineScatterCandleBubbleDataSet(yVals: MutableList, label: String) : +abstract class BarLineScatterCandleBubbleDataSet(yVals: MutableList, label: String) : DataSet(yVals, label), IBarLineScatterCandleBubbleDataSet { /** * Sets the color that is used for drawing the highlight indicators. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt index 10208d61fd..6ba5af0633 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt @@ -19,7 +19,7 @@ import info.appdev.charting.utils.convertDpToPixel * This is the base dataset of all DataSets. Its purpose is to implement critical methods * provided by the IDataSet interface. */ -abstract class BaseDataSet() : IDataSet { +abstract class BaseDataSet() : IDataSet { /** * List representing all colors that are used for this DataSet */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleDataSet.kt index 05c8183c6a..4bf3132830 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleDataSet.kt @@ -3,13 +3,13 @@ package info.appdev.charting.data import info.appdev.charting.interfaces.datasets.IBubbleDataSet import info.appdev.charting.utils.convertDpToPixel -open class BubbleDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), IBubbleDataSet { +open class BubbleDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), IBubbleDataSet { protected var mMaxSize: Float = 0f protected var mNormalizeSize: Boolean = true private var mHighlightCircleWidth = 2.5f - override fun calcMinMax(entry: BubbleEntry) { + override fun calcMinMax(entry: BubbleEntryFloat) { super.calcMinMax(entry) val size = entry.size @@ -19,8 +19,8 @@ open class BubbleDataSet(yVals: MutableList, label: String) : BarLi } } - override fun copy(): DataSet { - val entries: MutableList = ArrayList() + override fun copy(): DataSet { + val entries: MutableList = ArrayList() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleEntryFloat.kt similarity index 90% rename from chartLib/src/main/kotlin/info/appdev/charting/data/BubbleEntry.kt rename to chartLib/src/main/kotlin/info/appdev/charting/data/BubbleEntryFloat.kt index 0ea928773e..8cba5b64ea 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BubbleEntryFloat.kt @@ -8,7 +8,7 @@ import android.graphics.drawable.Drawable * chart implementation: Copyright 2015 Pierre-Marc Airoldi Licensed under Apache License 2.0 */ @SuppressLint("ParcelCreator") -class BubbleEntry : Entry { +class BubbleEntryFloat : EntryFloat { /** * Returns the size of this entry (the size of the bubble). */ @@ -49,7 +49,7 @@ class BubbleEntry : Entry { this.size = size } - override fun copy(): BubbleEntry { - return BubbleEntry(x, y, this.size, data) + override fun copy(): BubbleEntryFloat { + return BubbleEntryFloat(x, y, this.size, data) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/CandleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/CandleDataSet.kt index 685d9afacd..79e4d142df 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/CandleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/CandleDataSet.kt @@ -9,7 +9,7 @@ import info.appdev.charting.utils.convertDpToPixel /** * DataSet for the CandleStickChart. */ -open class CandleDataSet(yVals: MutableList, label: String = "") : LineScatterCandleRadarDataSet(yVals, label), ICandleDataSet { +open class CandleDataSet(yVals: MutableList, label: String = "") : LineScatterCandleRadarDataSet(yVals, label), ICandleDataSet { /** * the width of the shadow of the candle */ @@ -69,8 +69,8 @@ open class CandleDataSet(yVals: MutableList, label: String = "") : @ColorInt protected var mShadowColor: Int = ColorTemplate.COLOR_SKIP - override fun copy(): DataSet { - val entries: MutableList = mutableListOf() + override fun copy(): DataSet { + val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } @@ -95,7 +95,7 @@ open class CandleDataSet(yVals: MutableList, label: String = "") : candleDataSet.mShadowColor = mShadowColor } - override fun calcMinMax(entry: CandleEntry) { + override fun calcMinMax(entry: CandleEntryFloat) { entry.let { if (entry.low < yMin) yMin = entry.low @@ -104,7 +104,7 @@ open class CandleDataSet(yVals: MutableList, label: String = "") : calcMinMaxX(entry) } - override fun calcMinMaxY(entry: CandleEntry) { + override fun calcMinMaxY(entry: CandleEntryFloat) { entry.let { if (entry.high < yMin) yMin = entry.high diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/CandleEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/CandleEntryFloat.kt similarity index 95% rename from chartLib/src/main/kotlin/info/appdev/charting/data/CandleEntry.kt rename to chartLib/src/main/kotlin/info/appdev/charting/data/CandleEntryFloat.kt index 82c07b47c4..a138d18811 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/CandleEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/CandleEntryFloat.kt @@ -8,7 +8,7 @@ import kotlin.math.abs * Subclass of Entry that holds all values for one entry in a CandleStickChart. */ @SuppressLint("ParcelCreator") -class CandleEntry : Entry { +class CandleEntryFloat : EntryFloat { /** * Returns the upper shadows highest value. */ @@ -121,7 +121,7 @@ class CandleEntry : Entry { super.y = value } - override fun copy(): CandleEntry { - return CandleEntry(x, this.high, this.low, this.open, this.close, data) + override fun copy(): CandleEntryFloat { + return CandleEntryFloat(x, this.high, this.low, this.open, this.close, data) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt index 698d142be0..7902f3ecd9 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt @@ -12,7 +12,7 @@ import java.io.Serializable * Class that holds all relevant data that represents the chart. That involves at least one (or more) DataSets, and an array of x-values. */ @Suppress("unused") -abstract class ChartData> : Serializable { +abstract class ChartData> : Serializable { /** * maximum y-value in the value array across all axes */ @@ -243,7 +243,7 @@ abstract class ChartData> : Serializable { * Get the Entry for a corresponding highlight object * @return the entry that is highlighted */ - open fun getEntryForHighlight(highlight: Highlight): Entry? { + open fun getEntryForHighlight(highlight: Highlight): EntryFloat? { return if (highlight.dataSetIndex >= dataSets.size) { null } else { @@ -326,17 +326,17 @@ abstract class ChartData> : Serializable { * Entries are added to the end of the list. */ @Suppress("UNCHECKED_CAST") - fun addEntry(entry: Entry, dataSetIndex: Int) { + fun addEntry(entryFloat: EntryFloat, dataSetIndex: Int) { if (dataSets.size > dataSetIndex && dataSetIndex >= 0) { val set: T = dataSets[dataSetIndex] // add the entry to the dataset // We need to cast here because T is covariant (out) but addEntry needs to consume T - val dataSet = set as IDataSet - if (!dataSet.addEntry(entry)) { + val dataSet = set as IDataSet + if (!dataSet.addEntry(entryFloat)) { return } - calcMinMax(entry, set.axisDependency) + calcMinMax(entryFloat, set.axisDependency) } else { Timber.e("Cannot add Entry because dataSetIndex too high or too low.") } @@ -345,7 +345,7 @@ abstract class ChartData> : Serializable { /** * Adjusts the current minimum and maximum values based on the provided Entry object. */ - protected fun calcMinMax(e: Entry, axis: AxisDependency?) { + protected fun calcMinMax(e: EntryFloat, axis: AxisDependency?) { if (this.yMax < e.y) { this.yMax = e.y } @@ -416,7 +416,7 @@ abstract class ChartData> : Serializable { * Removes the given Entry object from the DataSet at the specified index. */ @Suppress("UNCHECKED_CAST") - open fun removeEntry(entry: Entry, dataSetIndex: Int): Boolean { + open fun removeEntry(entryFloat: EntryFloat, dataSetIndex: Int): Boolean { // entry null, out of bounds if (dataSetIndex >= dataSets.size) { return false @@ -425,8 +425,8 @@ abstract class ChartData> : Serializable { val set: T = dataSets[dataSetIndex] // remove the entry from the dataset - val dataSet = set as IDataSet - val removed: Boolean = dataSet.removeEntry(entry) + val dataSet = set as IDataSet + val removed: Boolean = dataSet.removeEntry(entryFloat) if (removed) { notifyDataChanged() @@ -446,15 +446,15 @@ abstract class ChartData> : Serializable { } val dataSet: IDataSet<*> = dataSets[dataSetIndex] - val entry: Entry = dataSet.getEntryForXValue(xValue, Float.NaN) ?: return false + val entryFloat: EntryFloat = dataSet.getEntryForXValue(xValue, Float.NaN) ?: return false - return removeEntry(entry, dataSetIndex) + return removeEntry(entryFloat, dataSetIndex) } /** * Returns the DataSet that contains the provided Entry, or null, if no DataSet contains this Entry. */ - fun getDataSetForEntry(e: Entry): T? { + fun getDataSetForEntry(e: EntryFloat): T? { for (i in dataSets.indices) { val set = dataSets[i] diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/CombinedData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/CombinedData.kt index f90fe2b56f..c2a18bd669 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/CombinedData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/CombinedData.kt @@ -9,7 +9,7 @@ import timber.log.Timber * Data object that allows the combination of Line-, Bar-, Scatter-, Bubble- and * CandleData. Used in the CombinedChart class. */ -class CombinedData : BarLineScatterCandleBubbleData>() { +class CombinedData : BarLineScatterCandleBubbleData>() { var lineData: LineData? = null private set var barData: BarData? = null @@ -130,7 +130,7 @@ class CombinedData : BarLineScatterCandleBubbleData= this.allData.size || highlight.dataIndex < 0) return null @@ -156,7 +156,7 @@ class CombinedData : BarLineScatterCandleBubbleData? { + fun getDataSetByHighlight(highlight: Highlight): IBarLineScatterCandleBubbleDataSet? { if (highlight.dataIndex >= this.allData.size) return null @@ -165,14 +165,14 @@ class CombinedData : BarLineScatterCandleBubbleData= data.dataSetCount) return null - return data.dataSets[highlight.dataSetIndex] as IBarLineScatterCandleBubbleDataSet? + return data.dataSets[highlight.dataSetIndex] as IBarLineScatterCandleBubbleDataSet? } fun getDataIndex(data: ChartData<*>?): Int { return this.allData.indexOf(data) } - override fun removeDataSet(d: IBarLineScatterCandleBubbleDataSet?): Boolean { + override fun removeDataSet(d: IBarLineScatterCandleBubbleDataSet?): Boolean { val datas = this.allData var success = false @@ -195,7 +195,7 @@ class CombinedData : BarLineScatterCandleBubbleData( +abstract class DataSet( protected var entriesInternal: MutableList, label: String = "" ) : BaseDataSet(label), Serializable { @@ -219,12 +219,12 @@ abstract class DataSet( while (low < high) { val m = low + (high - low) / 2 - val currentEntry: Entry = entriesInternal[m] + val currentEntryFloat: EntryFloat = entriesInternal[m] - val nextEntry: Entry = entriesInternal[m + 1] + val nextEntryFloat: EntryFloat = entriesInternal[m + 1] - val d1 = currentEntry.x - xValue - val d2 = nextEntry.x - xValue + val d1 = currentEntryFloat.x - xValue + val d2 = nextEntryFloat.x - xValue val ad1 = abs(d1) val ad2 = abs(d2) @@ -251,8 +251,8 @@ abstract class DataSet( closest = high } - val closestEntry: Entry = entriesInternal[closest] - val closestXValue = closestEntry.x + val closestEntryFloat: EntryFloat = entriesInternal[closest] + val closestXValue = closestEntryFloat.x if (rounding == Rounding.UP) { // If rounding up, and found x-value is lower than specified x, and we can go upper... if (closestXValue < xValue && closest < entriesInternal.size - 1) { @@ -271,7 +271,7 @@ abstract class DataSet( closest -= 1 } - var closestYValue = closestEntry.y + var closestYValue = closestEntryFloat.y var closestYIndex = closest while (true) { diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt similarity index 80% rename from chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt rename to chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt index 9a0b9fd191..431d261551 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/Entry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt @@ -13,7 +13,7 @@ import kotlin.math.abs * Class representing one entry in the chart. Might contain multiple values. * Might only contain a single value depending on the used constructor. */ -open class Entry : BaseEntry, Parcelable, Serializable { +open class EntryFloat : BaseEntry, Parcelable, Serializable { private var _x: Float = 0f open var x: Float @@ -25,7 +25,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { constructor() /** - * A Entry represents one single entry in the chart. + * A EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) @@ -35,7 +35,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { } /** - * A Entry represents one single entry in the chart. + * A EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) @@ -46,7 +46,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { } /** - * A Entry represents one single entry in the chart. + * A EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) @@ -57,12 +57,12 @@ open class Entry : BaseEntry, Parcelable, Serializable { } /** - * A Entry represents one single entry in the chart. + * A EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param icon icon image - * @param data Spot for additional data this Entry represents. + * @param data Spot for additional data this EntryFloat represents. */ constructor(x: Float, y: Float, icon: Drawable?, data: Any?) : super(y, icon, data) { this._x = x @@ -71,8 +71,8 @@ open class Entry : BaseEntry, Parcelable, Serializable { /** * returns an exact copy of the entry */ - open fun copy(): Entry { - val e = Entry(x, y, data) + open fun copy(): EntryFloat { + val e = EntryFloat(x, y, data) return e } @@ -81,7 +81,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { * are equal in those points, false if not. Does not check by hash-code like * it's done by the "equals" method. */ - fun equalTo(e: Entry?): Boolean { + fun equalTo(e: EntryFloat?): Boolean { if (e == null) return false @@ -104,7 +104,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { "${this.javaClass.typeName.substringAfterLast(".")} x=$x y=$y" } else { - "Entry x=$x y=$y" + "EntryFloat x=$x y=$y" } } @@ -120,7 +120,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { dest.writeInt(1) dest.writeParcelable(data as Parcelable?, flags) } else { - throw ParcelFormatException("Cannot parcel an Entry with non-parcelable data") + throw ParcelFormatException("Cannot parcel an EntryFloat with non-parcelable data") } } else { dest.writeInt(0) @@ -131,7 +131,7 @@ open class Entry : BaseEntry, Parcelable, Serializable { this._x = `in`.readFloat() this.yBase = `in`.readFloat() if (`in`.readInt() == 1) { - this.data = if (android.os.Build.VERSION.SDK_INT >= 33) { + this.data = if (Build.VERSION.SDK_INT >= 33) { `in`.readParcelable(Any::class.java.classLoader, Any::class.java) } else { @Suppress("DEPRECATION") @@ -142,12 +142,12 @@ open class Entry : BaseEntry, Parcelable, Serializable { companion object { @JvmField - val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): Entry { - return Entry(source) + val CREATOR: Parcelable.Creator = object : Parcelable.Creator { + override fun createFromParcel(source: Parcel): EntryFloat { + return EntryFloat(source) } - override fun newArray(size: Int): Array { + override fun newArray(size: Int): Array { return arrayOfNulls(size) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt index be22ee8e57..161aa24ebf 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt @@ -12,7 +12,7 @@ import info.appdev.charting.utils.ColorTemplate import info.appdev.charting.utils.convertDpToPixel import timber.log.Timber -open class LineDataSet(yVals: MutableList = mutableListOf(), label: String = "") : LineRadarDataSet(yVals, label), ILineDataSet { +open class LineDataSet(yVals: MutableList = mutableListOf(), label: String = "") : LineRadarDataSet(yVals, label), ILineDataSet { /** * Drawing mode for this line dataset */ @@ -73,8 +73,8 @@ open class LineDataSet(yVals: MutableList = mutableListOf(), label: Strin circleColors.add(Color.rgb(140, 234, 255)) } - override fun copy(): DataSet { - val entries: MutableList = mutableListOf() + override fun copy(): DataSet { + val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt index db3e593324..cb52f42bca 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt @@ -9,7 +9,7 @@ import info.appdev.charting.utils.convertDpToPixel /** * Base dataset for line and radar DataSets. */ -abstract class LineRadarDataSet(yVals: MutableList, label: String) : LineScatterCandleRadarDataSet(yVals, label), ILineRadarDataSet { +abstract class LineRadarDataSet(yVals: MutableList, label: String) : LineScatterCandleRadarDataSet(yVals, label), ILineRadarDataSet { // TODO: Move to using `Fill` class /** * the color that is used for filling the line surface diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt index 1f9535dff2..c5f782fc4a 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt @@ -4,7 +4,7 @@ import android.graphics.DashPathEffect import info.appdev.charting.interfaces.datasets.ILineScatterCandleRadarDataSet import info.appdev.charting.utils.convertDpToPixel -abstract class LineScatterCandleRadarDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), +abstract class LineScatterCandleRadarDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), ILineScatterCandleRadarDataSet { override var isVerticalHighlightIndicator: Boolean = true override var isHorizontalHighlightIndicator: Boolean = true diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/PieData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/PieData.kt index 3404885483..cdf80df625 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/PieData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/PieData.kt @@ -58,7 +58,7 @@ class PieData : ChartData { null } - override fun getEntryForHighlight(highlight: Highlight): Entry? { + override fun getEntryForHighlight(highlight: Highlight): EntryFloat? { return this.dataSet.getEntryForIndex(highlight.x.toInt()) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/PieDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/PieDataSet.kt index fd1f5ca4e3..aa0161ee4f 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/PieDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/PieDataSet.kt @@ -4,7 +4,7 @@ import androidx.annotation.ColorInt import info.appdev.charting.interfaces.datasets.IPieDataSet import info.appdev.charting.utils.convertDpToPixel -open class PieDataSet(yVals: MutableList, label: String) : DataSet(yVals, label), IPieDataSet { +open class PieDataSet(yVals: MutableList, label: String) : DataSet(yVals, label), IPieDataSet { /** * the space in pixels between the chart-slices, default 0f */ @@ -29,8 +29,8 @@ open class PieDataSet(yVals: MutableList, label: String) : DataSet { - val entries: MutableList = mutableListOf() + override fun copy(): DataSet { + val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } @@ -42,7 +42,7 @@ open class PieDataSet(yVals: MutableList, label: String) : DataSet?)!!) } - override fun calcMinMax(entry: PieEntry) { + override fun calcMinMax(entry: PieEntryFloat) { calcMinMaxY(entry) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/PieEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/PieEntryFloat.kt similarity index 92% rename from chartLib/src/main/kotlin/info/appdev/charting/data/PieEntry.kt rename to chartLib/src/main/kotlin/info/appdev/charting/data/PieEntryFloat.kt index 172e62dcfa..4ed9dc5121 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/PieEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/PieEntryFloat.kt @@ -5,7 +5,7 @@ import android.graphics.drawable.Drawable import timber.log.Timber @SuppressLint("ParcelCreator") -class PieEntry : Entry { +class PieEntryFloat : EntryFloat { var label: String? = null constructor(value: Float) : super(0f, value) @@ -50,7 +50,7 @@ class PieEntry : Entry { Timber.i("Pie entries do not have x values") } - override fun copy(): PieEntry { - return PieEntry(y, label, data) + override fun copy(): PieEntryFloat { + return PieEntryFloat(y, label, data) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/RadarData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/RadarData.kt index fc5e4d8bbb..74427ee3a7 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/RadarData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/RadarData.kt @@ -14,7 +14,7 @@ class RadarData : ChartData { constructor(dataSets: MutableList) : super(dataSets) - override fun getEntryForHighlight(highlight: Highlight): Entry? { + override fun getEntryForHighlight(highlight: Highlight): EntryFloat? { return getDataSetByIndex(highlight.dataSetIndex)!!.getEntryForIndex(highlight.x.toInt()) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/RadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/RadarDataSet.kt index 8a93eebe26..d4d3ce2612 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/RadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/RadarDataSet.kt @@ -5,7 +5,7 @@ import androidx.annotation.ColorInt import info.appdev.charting.interfaces.datasets.IRadarDataSet import info.appdev.charting.utils.ColorTemplate -open class RadarDataSet(yVals: MutableList, label: String = "") : LineRadarDataSet(yVals, label), IRadarDataSet { +open class RadarDataSet(yVals: MutableList, label: String = "") : LineRadarDataSet(yVals, label), IRadarDataSet { /** flag indicating whether highlight circle should be drawn or not */ protected var mIsDrawHighlightCircle: Boolean = false @@ -58,8 +58,8 @@ open class RadarDataSet(yVals: MutableList, label: String = "") : Li mHighlightCircleStrokeWidth = value } - override fun copy(): DataSet { - val entries: MutableList = mutableListOf() + override fun copy(): DataSet { + val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/RadarEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/RadarEntryFloat.kt similarity index 80% rename from chartLib/src/main/kotlin/info/appdev/charting/data/RadarEntry.kt rename to chartLib/src/main/kotlin/info/appdev/charting/data/RadarEntryFloat.kt index 0b6e6a3065..5b37a6769b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/RadarEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/RadarEntryFloat.kt @@ -3,7 +3,7 @@ package info.appdev.charting.data import android.annotation.SuppressLint @SuppressLint("ParcelCreator") -class RadarEntry : Entry { +class RadarEntryFloat : EntryFloat { constructor(value: Float) : super(0f, value) constructor(value: Float, data: Any?) : super(0f, value, data) @@ -14,8 +14,8 @@ class RadarEntry : Entry { val value: Float get() = y - override fun copy(): RadarEntry { - return RadarEntry(y, data) + override fun copy(): RadarEntryFloat { + return RadarEntryFloat(y, data) } @get:Deprecated("") diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/ScatterDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/ScatterDataSet.kt index d9c1ef47f8..aadb8848eb 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/ScatterDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/ScatterDataSet.kt @@ -13,7 +13,7 @@ import info.appdev.charting.renderer.scatter.TriangleShapeRenderer import info.appdev.charting.renderer.scatter.XShapeRenderer import info.appdev.charting.utils.ColorTemplate -open class ScatterDataSet(yVals: MutableList, label: String = "") : LineScatterCandleRadarDataSet(yVals, label), IScatterDataSet { +open class ScatterDataSet(yVals: MutableList, label: String = "") : LineScatterCandleRadarDataSet(yVals, label), IScatterDataSet { /** * the size the scatterShape will have, in density pixels */ @@ -38,8 +38,8 @@ open class ScatterDataSet(yVals: MutableList, label: String = "") : LineS @ColorInt private var mScatterShapeHoleColor = ColorTemplate.COLOR_NONE - override fun copy(): DataSet { - val entries: MutableList = mutableListOf() + override fun copy(): DataSet { + val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { entries.add(entriesInternal[i].copy()) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/ColorFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/ColorFormatter.kt index 3293e103c0..b015dbed96 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/ColorFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/ColorFormatter.kt @@ -1,6 +1,6 @@ package info.appdev.charting.formatter -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.datasets.IDataSet /** @@ -11,8 +11,8 @@ interface ColorFormatter { * Returns the color to be used for the given Entry at the given index (in the entries array) * * @param index index in the entries array - * @param entry the entry to color + * @param entryFloat the entry to color * @param set the DataSet the entry belongs to */ - fun getColor(index: Int, entry: Entry?, set: IDataSet<*>?): Int + fun getColor(index: Int, entryFloat: EntryFloat?, set: IDataSet<*>?): Int } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultValueFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultValueFormatter.kt index b722ff0843..1164c220a9 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultValueFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultValueFormatter.kt @@ -1,6 +1,6 @@ package info.appdev.charting.formatter -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.utils.ViewPortHandler import java.text.DecimalFormat @@ -42,7 +42,7 @@ open class DefaultValueFormatter(digits: Int) : IValueFormatter { decimalFormat = DecimalFormat("###,###,###,##0$b") } - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? { + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? { // put more logic here ... // avoid memory allocations here (for performance reasons) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/IValueFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/IValueFormatter.kt index 8e05dedc0d..8275036a1e 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/IValueFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/IValueFormatter.kt @@ -1,6 +1,6 @@ package info.appdev.charting.formatter -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.utils.ViewPortHandler /** @@ -16,10 +16,10 @@ interface IValueFormatter { * and memory allocations inside this method. * * @param value the value to be formatted - * @param entry the entry the value belongs to - in e.g. BarChart, this is of class BarEntry + * @param entryFloat the entry the value belongs to - in e.g. BarChart, this is of class BarEntry * @param dataSetIndex the index of the DataSet the entry in focus belongs to * @param viewPortHandler provides information about the current chart state (scale, translation, ...) * @return the formatted label ready for being drawn */ - fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? + fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/LargeValueFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/LargeValueFormatter.kt index 12692b54ca..4bdc969007 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/LargeValueFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/LargeValueFormatter.kt @@ -1,7 +1,7 @@ package info.appdev.charting.formatter import info.appdev.charting.components.AxisBase -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.utils.ViewPortHandler import java.text.DecimalFormat @@ -32,7 +32,7 @@ open class LargeValueFormatter() : IValueFormatter, IAxisValueFormatter { } // IValueFormatter - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { return makePretty(value.toDouble()) + text } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/PercentFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/PercentFormatter.kt index 271fab7bfa..e785c9833c 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/PercentFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/PercentFormatter.kt @@ -1,7 +1,7 @@ package info.appdev.charting.formatter import info.appdev.charting.components.AxisBase -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.utils.ViewPortHandler import java.text.DecimalFormat @@ -23,7 +23,7 @@ open class PercentFormatter : IValueFormatter, IAxisValueFormatter { } // IValueFormatter - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? { + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? { return decimalFormat.format(value.toDouble()) + " %" } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/StackedValueFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/StackedValueFormatter.kt index 957957acd1..606bfeb0c7 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/StackedValueFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/StackedValueFormatter.kt @@ -1,7 +1,7 @@ package info.appdev.charting.formatter -import info.appdev.charting.data.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.utils.ViewPortHandler import java.text.DecimalFormat @@ -29,9 +29,9 @@ open class StackedValueFormatter(private val drawWholeStack: Boolean, private va this.decimalFormat = DecimalFormat("###,###,###,##0$b") } - override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { - if (!drawWholeStack && entry is BarEntry) { - val barEntry = entry + override fun getFormattedValue(value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + if (!drawWholeStack && entryFloat is BarEntryFloat) { + val barEntry = entryFloat val vals = barEntry.yVals if (vals != null) { diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt index fb54b536d2..9d0eac051b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt @@ -3,7 +3,7 @@ package info.appdev.charting.highlight import info.appdev.charting.components.YAxis.AxisDependency import info.appdev.charting.data.ChartData import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.dataprovider.base.BarLineScatterCandleBubbleDataProvider import info.appdev.charting.interfaces.datasets.IDataSet import info.appdev.charting.utils.PointD @@ -125,7 +125,7 @@ open class ChartHighlighter>(prote var entries = set.getEntriesForXValue(xVal) if (entries != null && entries.isEmpty()) { // Try to find closest x-value and take all entries for that x-value - val closest: Entry? = set.getEntryForXValue(xVal, Float.NaN, rounding) + val closest: EntryFloat? = set.getEntryForXValue(xVal, Float.NaN, rounding) if (closest != null) { entries = set.getEntriesForXValue(closest.x) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt index 9ac9af9629..8354c9fe44 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt @@ -1,7 +1,7 @@ package info.appdev.charting.highlight import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.dataprovider.BarDataProvider import info.appdev.charting.interfaces.datasets.IDataSet import info.appdev.charting.utils.PointD @@ -38,8 +38,8 @@ class HorizontalBarHighlighter(dataProvider: BarDataProvider) : BarHighlighter(d var entries = set.getEntriesForXValue(xVal) if (entries != null && entries.isEmpty()) { // Try to find closest x-value and take all entries for that x-value - val closestEntry: Entry? = set.getEntryForXValue(xVal, Float.NaN, rounding) - closestEntry?.let { closestE -> + val closestEntryFloat: EntryFloat? = set.getEntryForXValue(xVal, Float.NaN, rounding) + closestEntryFloat?.let { closestE -> entries = set.getEntriesForXValue(closestE.x) } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/PieHighlighter.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/PieHighlighter.kt index d846dcf66f..388229271a 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/highlight/PieHighlighter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/PieHighlighter.kt @@ -1,16 +1,16 @@ package info.appdev.charting.highlight import info.appdev.charting.charts.PieChart -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat open class PieHighlighter(chart: PieChart) : PieRadarHighlighter(chart) { override fun getClosestHighlight(index: Int, x: Float, y: Float): Highlight? { val pieDataSet = chartPieRadar.data?.dataSets[0] - val entry: Entry? = pieDataSet?.getEntryForIndex(index) + val entryFloat: EntryFloat? = pieDataSet?.getEntryForIndex(index) - entry?.let { - return Highlight(index.toFloat(), entry.y, x, y, 0, pieDataSet.axisDependency) + entryFloat?.let { + return Highlight(index.toFloat(), entryFloat.y, x, y, 0, pieDataSet.axisDependency) } return null } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/RadarHighlighter.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/RadarHighlighter.kt index 7e7450be5c..5002eb762b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/highlight/RadarHighlighter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/RadarHighlighter.kt @@ -1,7 +1,7 @@ package info.appdev.charting.highlight import info.appdev.charting.charts.RadarChart -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.utils.PointF import info.appdev.charting.utils.changePosition import kotlin.math.abs @@ -47,16 +47,16 @@ open class RadarHighlighter(chart: RadarChart) : PieRadarHighlighter for (i in 0.. { +interface IBarDataSet : IBarLineScatterCandleBubbleDataSet { var fills: MutableList fun getFill(index: Int): Fill? diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt index c547744254..ead34a8bc4 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt @@ -1,8 +1,8 @@ package info.appdev.charting.interfaces.datasets -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat -interface IBarLineScatterCandleBubbleDataSet : IDataSet { +interface IBarLineScatterCandleBubbleDataSet : IDataSet { val highLightColor: Int } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBubbleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBubbleDataSet.kt index 43f8efb491..faa14a164c 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBubbleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBubbleDataSet.kt @@ -1,8 +1,8 @@ package info.appdev.charting.interfaces.datasets -import info.appdev.charting.data.BubbleEntry +import info.appdev.charting.data.BubbleEntryFloat -interface IBubbleDataSet : IBarLineScatterCandleBubbleDataSet { +interface IBubbleDataSet : IBarLineScatterCandleBubbleDataSet { val maxSize: Float val isNormalizeSizeEnabled: Boolean diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ICandleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ICandleDataSet.kt index 366c783441..ce86fccf2b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ICandleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ICandleDataSet.kt @@ -1,10 +1,9 @@ package info.appdev.charting.interfaces.datasets import android.graphics.Paint -import androidx.annotation.ColorInt -import info.appdev.charting.data.CandleEntry +import info.appdev.charting.data.CandleEntryFloat -interface ICandleDataSet : ILineScatterCandleRadarDataSet { +interface ICandleDataSet : ILineScatterCandleRadarDataSet { /** * Returns the space that is left out on the left and right side of each candle. */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt index c401c661fd..43db6096f6 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt @@ -5,11 +5,11 @@ import android.graphics.Typeface import info.appdev.charting.components.Legend import info.appdev.charting.components.YAxis import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.formatter.IValueFormatter import info.appdev.charting.utils.PointF -interface IDataSet { +interface IDataSet { /** * returns the minimum y-value this DataSet holds */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt index 3f2ccd2dc7..adb3554159 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt @@ -1,11 +1,11 @@ package info.appdev.charting.interfaces.datasets import android.graphics.DashPathEffect -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineDataSet import info.appdev.charting.formatter.IFillFormatter -interface ILineDataSet : ILineRadarDataSet { +interface ILineDataSet : ILineRadarDataSet { /** * Returns the drawing mode for this line dataset */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt index d0ccfe7d96..050bc462f2 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt @@ -1,9 +1,9 @@ package info.appdev.charting.interfaces.datasets import android.graphics.drawable.Drawable -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat -interface ILineRadarDataSet : ILineScatterCandleRadarDataSet { +interface ILineRadarDataSet : ILineScatterCandleRadarDataSet { /** * Returns the color that is used for filling the line surface area. */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt index 56cb229508..f260a293e3 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt @@ -1,9 +1,9 @@ package info.appdev.charting.interfaces.datasets import android.graphics.DashPathEffect -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat -interface ILineScatterCandleRadarDataSet : IBarLineScatterCandleBubbleDataSet { +interface ILineScatterCandleRadarDataSet : IBarLineScatterCandleBubbleDataSet { /** * Returns true if vertical highlight indicator lines are enabled (drawn) */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IPieDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IPieDataSet.kt index 658602dc72..13df4852b5 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IPieDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IPieDataSet.kt @@ -1,9 +1,9 @@ package info.appdev.charting.interfaces.datasets import info.appdev.charting.data.PieDataSet.ValuePosition -import info.appdev.charting.data.PieEntry +import info.appdev.charting.data.PieEntryFloat -interface IPieDataSet : IDataSet { +interface IPieDataSet : IDataSet { /** * Returns the space that is set to be between the PieChart-slices of this DataSet, in pixels. */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IRadarDataSet.kt index 986849fcf0..6406f1c89b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IRadarDataSet.kt @@ -1,8 +1,8 @@ package info.appdev.charting.interfaces.datasets -import info.appdev.charting.data.RadarEntry +import info.appdev.charting.data.RadarEntryFloat -interface IRadarDataSet : ILineRadarDataSet { +interface IRadarDataSet : ILineRadarDataSet { /** flag indicating whether highlight circle should be drawn or not */ /** Sets whether highlight circle should be drawn or not */ var isDrawHighlightCircle: Boolean diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IScatterDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IScatterDataSet.kt index 9e44a32511..796808a2eb 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IScatterDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IScatterDataSet.kt @@ -1,9 +1,9 @@ package info.appdev.charting.interfaces.datasets -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.renderer.scatter.IShapeRenderer -interface IScatterDataSet : ILineScatterCandleRadarDataSet { +interface IScatterDataSet : ILineScatterCandleRadarDataSet { /** * the currently set scatter shape size */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/listener/BarLineChartTouchListener.kt b/chartLib/src/main/kotlin/info/appdev/charting/listener/BarLineChartTouchListener.kt index 786af91c67..faaaeca8de 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/listener/BarLineChartTouchListener.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/listener/BarLineChartTouchListener.kt @@ -9,7 +9,7 @@ import android.view.animation.AnimationUtils import info.appdev.charting.charts.BarLineChartBase import info.appdev.charting.charts.HorizontalBarChart import info.appdev.charting.data.BarLineScatterCandleBubbleData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet import info.appdev.charting.interfaces.datasets.IDataSet import info.appdev.charting.utils.PointF @@ -25,11 +25,11 @@ import kotlin.math.sqrt */ @Suppress("MemberVisibilityCanBePrivate") class BarLineChartTouchListener( - chart: BarLineChartBase>>, + chart: BarLineChartBase>>, touchMatrix: Matrix, dragTriggerDistance: Float ) : - ChartTouchListener>>>(chart) { + ChartTouchListener>>>(chart) { /** * the original touch-matrix from the chart */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/listener/OnChartValueSelectedListener.kt b/chartLib/src/main/kotlin/info/appdev/charting/listener/OnChartValueSelectedListener.kt index 188ed5ea10..5e54d6db32 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/listener/OnChartValueSelectedListener.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/listener/OnChartValueSelectedListener.kt @@ -1,6 +1,6 @@ package info.appdev.charting.listener -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight /** @@ -11,11 +11,11 @@ interface OnChartValueSelectedListener { /** * Called when a value has been selected inside the chart. * - * @param entry The selected Entry + * @param entryFloat The selected Entry * @param highlight The corresponding highlight object that contains information * about the highlighted position such as dataSetIndex, ... */ - fun onValueSelected(entry: Entry, highlight: Highlight) + fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) /** * Called when nothing has been selected or an "un-select" has been made. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/listener/OnDrawListener.kt b/chartLib/src/main/kotlin/info/appdev/charting/listener/OnDrawListener.kt index 6e755a23e1..45b9af8ac7 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/listener/OnDrawListener.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/listener/OnDrawListener.kt @@ -1,7 +1,7 @@ package info.appdev.charting.listener import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat /** * Listener for callbacks when drawing on the chart. @@ -11,14 +11,14 @@ interface OnDrawListener { * Called whenever an entry is added with the finger. Note this is also called for entries that are generated by the * library, when the touch gesture is too fast and skips points. * - * @param entry the last drawn entry + * @param entryFloat the last drawn entry */ - fun onEntryAdded(entry: Entry) + fun onEntryAdded(entryFloat: EntryFloat) /** * Called whenever an entry is moved by the user after being highlighted */ - fun onEntryMoved(entry: Entry) + fun onEntryMoved(entryFloat: EntryFloat) /** * Called when drawing finger is lifted and the draw is finished. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt index d54b178d90..577b42a86b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt @@ -2,7 +2,7 @@ package info.appdev.charting.renderer import info.appdev.charting.animation.ChartAnimator import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.dataprovider.base.BarLineScatterCandleBubbleDataProvider import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet import info.appdev.charting.interfaces.datasets.IDataSet @@ -29,7 +29,7 @@ abstract class BarLineScatterCandleBubbleRenderer( /** * Checks if the provided entry object is in bounds for drawing considering the current animation phase. */ - protected fun isInBoundsX(entry: T, set: IBarLineScatterCandleBubbleDataSet): Boolean { + protected fun isInBoundsX(entry: T, set: IBarLineScatterCandleBubbleDataSet): Boolean { val entryIndex = set.getEntryIndex(entry).toFloat() return if (entryIndex >= set.entryCount * animator.phaseX) { @@ -61,7 +61,7 @@ abstract class BarLineScatterCandleBubbleRenderer( /** * Calculates the minimum and maximum x values as well as the range between them. */ - fun set(chart: BarLineScatterCandleBubbleDataProvider<*>, dataSet: IBarLineScatterCandleBubbleDataSet) { + fun set(chart: BarLineScatterCandleBubbleDataProvider<*>, dataSet: IBarLineScatterCandleBubbleDataSet) { val phaseX = max(0f, min(1f, animator.phaseX)) val low = chart.lowestVisibleX diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/DataRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/DataRenderer.kt index 09b1c3acdf..ba5e970ad3 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/DataRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/DataRenderer.kt @@ -5,7 +5,7 @@ import android.graphics.Color import android.graphics.Paint import android.graphics.Paint.Align import info.appdev.charting.animation.ChartAnimator -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.formatter.IValueFormatter import info.appdev.charting.highlight.Highlight import info.appdev.charting.interfaces.dataprovider.base.IBaseProvider @@ -98,14 +98,14 @@ abstract class DataRenderer( * @param canvas canvas * @param formatter formatter for custom value-formatting * @param value the value to be drawn - * @param entry the entry the value belongs to + * @param entryFloat the entry the value belongs to * @param dataSetIndex the index of the DataSet the drawn Entry belongs to * @param x position * @param y position */ - fun drawValue(canvas: Canvas, formatter: IValueFormatter, value: Float, entry: Entry?, dataSetIndex: Int, x: Float, y: Float, color: Int) { + fun drawValue(canvas: Canvas, formatter: IValueFormatter, value: Float, entryFloat: EntryFloat?, dataSetIndex: Int, x: Float, y: Float, color: Int) { paintValues.color = color - canvas.drawText(formatter.getFormattedValue(value, entry, dataSetIndex, viewPortHandler)!!, x, y, paintValues) + canvas.drawText(formatter.getFormattedValue(value, entryFloat, dataSetIndex, viewPortHandler)!!, x, y, paintValues) } /** diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt index 9745460e60..dbadb870de 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt @@ -7,7 +7,7 @@ import android.graphics.Color import android.graphics.Paint import android.graphics.Path import info.appdev.charting.animation.ChartAnimator -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineDataSet import info.appdev.charting.highlight.Highlight import info.appdev.charting.interfaces.dataprovider.LineDataProvider @@ -175,7 +175,7 @@ open class LineChartRenderer( // And in the `lastIndex`, add +1 val firstIndex = xBounds.min + 1 - var prevPrev: Entry? + var prevPrev: EntryFloat? var prev = dataSet.getEntryForIndex(max((firstIndex - 2).toDouble(), 0.0).toInt()) var cur = dataSet.getEntryForIndex(max((firstIndex - 1).toDouble(), 0.0).toInt()) var next = cur @@ -286,24 +286,24 @@ open class LineChartRenderer( val max = xBounds.min + xBounds.range for (j in xBounds.min.. { - val entries: MutableList = ArrayList() +fun AssetManager.loadEntriesFromAssets(path: String): MutableList { + val entries: MutableList = ArrayList() try { BufferedReader( @@ -31,7 +31,7 @@ fun AssetManager.loadEntriesFromAssets(path: String): MutableList { val split: Array = line.split("#".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() if (split.size <= 2) { - entries.add(Entry(split[1]!!.toFloat(), split[0]!!.toFloat())) + entries.add(EntryFloat(split[1]!!.toFloat(), split[0]!!.toFloat())) } else { val vals = FloatArray(split.size - 1) @@ -39,7 +39,7 @@ fun AssetManager.loadEntriesFromAssets(path: String): MutableList { vals[i] = split[i]!!.toFloat() } - entries.add(BarEntry(split[split.size - 1]!!.toInt().toFloat(), vals)) + entries.add(BarEntryFloat(split[split.size - 1]!!.toInt().toFloat(), vals)) } line = reader.readLine() } @@ -51,15 +51,15 @@ fun AssetManager.loadEntriesFromAssets(path: String): MutableList { return entries } -fun AssetManager.loadBarEntriesFromAssets(path: String): MutableList { - val entries: MutableList = ArrayList() +fun AssetManager.loadBarEntriesFromAssets(path: String): MutableList { + val entries: MutableList = ArrayList() try { BufferedReader(InputStreamReader(this.open(path), StandardCharsets.UTF_8)).use { reader -> var line = reader.readLine() while (line != null) { val split: Array = line.split("#".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - entries.add(BarEntry(split[1]!!.toFloat(), split[0]!!.toFloat())) + entries.add(BarEntryFloat(split[1]!!.toFloat(), split[0]!!.toFloat())) line = reader.readLine() } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/EntryXComparator.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/EntryXComparator.kt index d380b4debb..3aaafeb5f2 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/EntryXComparator.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/EntryXComparator.kt @@ -1,13 +1,13 @@ package info.appdev.charting.utils -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat /** * Comparator for comparing Entry-objects by their x-value. */ -class EntryXComparator : Comparator { - override fun compare(entry1: Entry, entry2: Entry): Int { - val diff = entry1.x - entry2.x +class EntryXComparator : Comparator { + override fun compare(entryFloat1: EntryFloat, entryFloat2: EntryFloat): Int { + val diff = entryFloat1.x - entryFloat2.x return diff.compareTo(0f) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt index e43e585822..0836d38570 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt @@ -3,7 +3,7 @@ package info.appdev.charting.utils import android.graphics.Matrix import android.graphics.Path import android.graphics.RectF -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.interfaces.datasets.IBubbleDataSet import info.appdev.charting.interfaces.datasets.ICandleDataSet import info.appdev.charting.interfaces.datasets.ILineDataSet @@ -118,7 +118,7 @@ open class Transformer(protected var viewPortHandler: ViewPortHandler) { var j = 0 while (j < count) { - val e: Entry? = data.getEntryForIndex(j / 2 + from) + val e: EntryFloat? = data.getEntryForIndex(j / 2 + from) if (e != null) { valuePoints[j] = e.x diff --git a/chartLib/src/test/kotlin/info/appdev/charting/test/BarDataTest.kt b/chartLib/src/test/kotlin/info/appdev/charting/test/BarDataTest.kt index 0869e638d6..51deb135a5 100644 --- a/chartLib/src/test/kotlin/info/appdev/charting/test/BarDataTest.kt +++ b/chartLib/src/test/kotlin/info/appdev/charting/test/BarDataTest.kt @@ -2,7 +2,7 @@ package info.appdev.charting.test import info.appdev.charting.data.BarData import info.appdev.charting.data.BarDataSet -import info.appdev.charting.data.BarEntry +import info.appdev.charting.data.BarEntryFloat import org.junit.Assert import org.junit.Test @@ -12,12 +12,12 @@ class BarDataTest { val groupSpace = 5f val barSpace = 1f - val values1: MutableList = ArrayList() - val values2: MutableList = ArrayList() + val values1: MutableList = ArrayList() + val values2: MutableList = ArrayList() for (i in 0..4) { - values1.add(BarEntry(i.toFloat(), 50f)) - values2.add(BarEntry(i.toFloat(), 60f)) + values1.add(BarEntryFloat(i.toFloat(), 50f)) + values2.add(BarEntryFloat(i.toFloat(), 60f)) } val barDataSet1 = BarDataSet(values1, "Set1") diff --git a/chartLib/src/test/kotlin/info/appdev/charting/test/ChartDataTest.kt b/chartLib/src/test/kotlin/info/appdev/charting/test/ChartDataTest.kt index 468aaf40b2..2f4b84cada 100644 --- a/chartLib/src/test/kotlin/info/appdev/charting/test/ChartDataTest.kt +++ b/chartLib/src/test/kotlin/info/appdev/charting/test/ChartDataTest.kt @@ -1,7 +1,7 @@ package info.appdev.charting.test import info.appdev.charting.components.YAxis -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.data.ScatterData @@ -12,17 +12,17 @@ import org.junit.Test class ChartDataTest { @Test fun testDynamicChartData() { - val entries1: MutableList = ArrayList() - entries1.add(Entry(10f, 10f)) - entries1.add(Entry(15f, -2f)) - entries1.add(Entry(21f, 50f)) + val entries1: MutableList = ArrayList() + entries1.add(EntryFloat(10f, 10f)) + entries1.add(EntryFloat(15f, -2f)) + entries1.add(EntryFloat(21f, 50f)) val set1 = ScatterDataSet(entries1, "") - val entries2: MutableList = ArrayList() - entries2.add(Entry(-1f, 10f)) - entries2.add(Entry(10f, 2f)) - entries2.add(Entry(20f, 5f)) + val entries2: MutableList = ArrayList() + entries2.add(EntryFloat(-1f, 10f)) + entries2.add(EntryFloat(10f, 2f)) + entries2.add(EntryFloat(20f, 5f)) val set2 = ScatterDataSet(entries2, "") @@ -42,7 +42,7 @@ class ChartDataTest { Assert.assertEquals(3, data.maxEntryCountSet?.entryCount) // now add and remove values - data.addEntry(Entry(-10f, -10f), 0) + data.addEntry(EntryFloat(-10f, -10f), 0) Assert.assertEquals(set1, data.maxEntryCountSet) Assert.assertEquals(4, data.maxEntryCountSet?.entryCount) @@ -56,8 +56,8 @@ class ChartDataTest { Assert.assertEquals(-10f, data.yMin, 0.01f) Assert.assertEquals(50f, data.yMax, 0.01f) - data.addEntry(Entry(-100f, 100f), 0) - data.addEntry(Entry(0f, -100f), 0) + data.addEntry(EntryFloat(-100f, 100f), 0) + data.addEntry(EntryFloat(0f, -100f), 0) Assert.assertEquals(-100f, data.getYMin(YAxis.AxisDependency.LEFT), 0.01f) Assert.assertEquals(100f, data.getYMax(YAxis.AxisDependency.LEFT), 0.01f) @@ -66,9 +66,9 @@ class ChartDataTest { Assert.assertEquals(-100f, data.getYMin(YAxis.AxisDependency.RIGHT), 0.01f) Assert.assertEquals(100f, data.getYMax(YAxis.AxisDependency.RIGHT), 0.01f) - val entries3: MutableList = ArrayList() - entries3.add(Entry(0f, 200f)) - entries3.add(Entry(0f, -50f)) + val entries3: MutableList = ArrayList() + entries3.add(EntryFloat(0f, 200f)) + entries3.add(EntryFloat(0f, -50f)) val set3 = ScatterDataSet(entries3, "") set3.axisDependency = YAxis.AxisDependency.RIGHT @@ -96,9 +96,9 @@ class ChartDataTest { Assert.assertEquals(0, lineData.dataSetCount) - val lineEntries1: MutableList = ArrayList() - lineEntries1.add(Entry(10f, 90f)) - lineEntries1.add(Entry(1000f, 1000f)) + val lineEntries1: MutableList = ArrayList() + lineEntries1.add(EntryFloat(10f, 90f)) + lineEntries1.add(EntryFloat(1000f, 1000f)) val lineSet1 = LineDataSet(lineEntries1, "") @@ -120,11 +120,11 @@ class ChartDataTest { Assert.assertEquals(90f, lineData.getYMin(YAxis.AxisDependency.RIGHT), 0.01f) Assert.assertEquals(1000f, lineData.getYMax(YAxis.AxisDependency.RIGHT), 0.01f) - val lineEntries2: MutableList = ArrayList() - lineEntries2.add(Entry(-1000f, 2000f)) - lineEntries2.add(Entry(2000f, -3000f)) + val lineEntries2: MutableList = ArrayList() + lineEntries2.add(EntryFloat(-1000f, 2000f)) + lineEntries2.add(EntryFloat(2000f, -3000f)) - val e = Entry(-1000f, 2500f) + val e = EntryFloat(-1000f, 2500f) lineEntries2.add(e) val lineSet2 = LineDataSet(lineEntries2, "") diff --git a/chartLib/src/test/kotlin/info/appdev/charting/test/DataSetTest.kt b/chartLib/src/test/kotlin/info/appdev/charting/test/DataSetTest.kt index 62b0b0efb9..482c1b9532 100644 --- a/chartLib/src/test/kotlin/info/appdev/charting/test/DataSetTest.kt +++ b/chartLib/src/test/kotlin/info/appdev/charting/test/DataSetTest.kt @@ -1,7 +1,7 @@ package info.appdev.charting.test import info.appdev.charting.data.DataSet -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.ScatterDataSet import org.junit.Assert import org.junit.Test @@ -9,10 +9,10 @@ import org.junit.Test class DataSetTest { @Test fun testCalcMinMax() { - val entries: MutableList = mutableListOf() - entries.add(Entry(10f, 10f)) - entries.add(Entry(15f, 2f)) - entries.add(Entry(21f, 5f)) + val entries: MutableList = mutableListOf() + entries.add(EntryFloat(10f, 10f)) + entries.add(EntryFloat(15f, 2f)) + entries.add(EntryFloat(21f, 5f)) val set = ScatterDataSet(entries, "") @@ -24,7 +24,7 @@ class DataSetTest { Assert.assertEquals(3, set.entryCount) - set.addEntry(Entry(25f, 1f)) + set.addEntry(EntryFloat(25f, 1f)) Assert.assertEquals(10f, set.xMin, 0.01f) Assert.assertEquals(25f, set.xMax, 0.01f) @@ -45,16 +45,16 @@ class DataSetTest { @Test fun testAddRemoveEntry() { - val entries: MutableList = mutableListOf() - entries.add(Entry(10f, 10f)) - entries.add(Entry(15f, 2f)) - entries.add(Entry(21f, 5f)) + val entries: MutableList = mutableListOf() + entries.add(EntryFloat(10f, 10f)) + entries.add(EntryFloat(15f, 2f)) + entries.add(EntryFloat(21f, 5f)) val set = ScatterDataSet(entries, "") Assert.assertEquals(3, set.entryCount) - set.addEntryOrdered(Entry(5f, 1f)) + set.addEntryOrdered(EntryFloat(5f, 1f)) Assert.assertEquals(4, set.entryCount) @@ -67,7 +67,7 @@ class DataSetTest { Assert.assertEquals(5f, set.getEntryForIndex(0)!!.x, 0.01f) Assert.assertEquals(1f, set.getEntryForIndex(0)!!.y, 0.01f) - set.addEntryOrdered(Entry(20f, 50f)) + set.addEntryOrdered(EntryFloat(20f, 50f)) Assert.assertEquals(5, set.entryCount) @@ -91,7 +91,7 @@ class DataSetTest { Assert.assertEquals(10f, set.getEntryForIndex(0)!!.x, 0.01f) Assert.assertEquals(10f, set.getEntryForIndex(0)!!.y, 0.01f) - set.addEntryOrdered(Entry(15f, 3f)) + set.addEntryOrdered(EntryFloat(15f, 3f)) Assert.assertEquals(4, set.entryCount) @@ -129,10 +129,10 @@ class DataSetTest { @Test fun testGetEntryForXValue() { - val entries: MutableList = mutableListOf() - entries.add(Entry(10f, 10f)) - entries.add(Entry(15f, 5f)) - entries.add(Entry(21f, 5f)) + val entries: MutableList = mutableListOf() + entries.add(EntryFloat(10f, 10f)) + entries.add(EntryFloat(15f, 5f)) + entries.add(EntryFloat(21f, 5f)) val set = ScatterDataSet(entries, "") @@ -169,19 +169,19 @@ class DataSetTest { fun testGetEntryForXValueWithDuplicates() { // sorted list of values (by x position) - val values: MutableList = ArrayList() - values.add(Entry(0f, 10f)) - values.add(Entry(1f, 20f)) - values.add(Entry(2f, 30f)) - values.add(Entry(3f, 40f)) - values.add(Entry(3f, 50f)) // duplicate - values.add(Entry(4f, 60f)) - values.add(Entry(4f, 70f)) // duplicate - values.add(Entry(5f, 80f)) - values.add(Entry(6f, 90f)) - values.add(Entry(7f, 100f)) - values.add(Entry(8f, 110f)) - values.add(Entry(8f, 120f)) // duplicate + val values: MutableList = ArrayList() + values.add(EntryFloat(0f, 10f)) + values.add(EntryFloat(1f, 20f)) + values.add(EntryFloat(2f, 30f)) + values.add(EntryFloat(3f, 40f)) + values.add(EntryFloat(3f, 50f)) // duplicate + values.add(EntryFloat(4f, 60f)) + values.add(EntryFloat(4f, 70f)) // duplicate + values.add(EntryFloat(5f, 80f)) + values.add(EntryFloat(6f, 90f)) + values.add(EntryFloat(7f, 100f)) + values.add(EntryFloat(8f, 110f)) + values.add(EntryFloat(8f, 120f)) // duplicate val set = ScatterDataSet(values, "") diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BarChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BarChartComposable.kt index 66541d4e85..a63a0f5643 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BarChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BarChartComposable.kt @@ -14,7 +14,7 @@ import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis import info.appdev.charting.data.BarData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -53,7 +53,7 @@ fun BarChart( data: BarData?, modifier: Modifier = Modifier, state: BarChartState = rememberBarChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -140,8 +140,8 @@ fun BarChart( // Selection listener if (onValueSelected != null) { barChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) { - onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + onValueSelected(entryFloat, highlight) } override fun onNothingSelected() { diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BubbleChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BubbleChartComposable.kt index 42134afa16..f2175a2810 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BubbleChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/BubbleChartComposable.kt @@ -14,7 +14,7 @@ import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis import info.appdev.charting.data.BubbleData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -26,7 +26,7 @@ fun BubbleChart( data: BubbleData?, modifier: Modifier = Modifier, state: BubbleChartState = rememberBubbleChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -92,7 +92,7 @@ fun BubbleChart( if (onValueSelected != null) { bubbleChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) = onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = onValueSelected(entryFloat, highlight) override fun onNothingSelected() = onValueSelected(null, null) }) } diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CandleStickChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CandleStickChartComposable.kt index 892d2fbf6b..de893eaf8b 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CandleStickChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CandleStickChartComposable.kt @@ -14,7 +14,7 @@ import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis import info.appdev.charting.data.CandleData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -26,7 +26,7 @@ fun CandleStickChart( data: CandleData?, modifier: Modifier = Modifier, state: CandleStickChartState = rememberCandleStickChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -92,7 +92,7 @@ fun CandleStickChart( if (onValueSelected != null) { candleChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) = onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = onValueSelected(entryFloat, highlight) override fun onNothingSelected() = onValueSelected(null, null) }) } diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CombinedChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CombinedChartComposable.kt index 3c196f4718..e5a9d7fe4d 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CombinedChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/CombinedChartComposable.kt @@ -14,7 +14,7 @@ import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis import info.appdev.charting.data.CombinedData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -26,7 +26,7 @@ fun CombinedChart( data: CombinedData?, modifier: Modifier = Modifier, state: CombinedChartState = rememberCombinedChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -108,7 +108,7 @@ fun CombinedChart( if (onValueSelected != null) { combinedChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) = onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = onValueSelected(entryFloat, highlight) override fun onNothingSelected() = onValueSelected(null, null) }) } diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/HorizontalBarChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/HorizontalBarChartComposable.kt index d76bae0ff4..6a0a433203 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/HorizontalBarChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/HorizontalBarChartComposable.kt @@ -14,7 +14,7 @@ import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis import info.appdev.charting.data.BarData -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -26,7 +26,7 @@ fun HorizontalBarChart( data: BarData?, modifier: Modifier = Modifier, state: HorizontalBarChartState = rememberHorizontalBarChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -88,7 +88,7 @@ fun HorizontalBarChart( if (onValueSelected != null) { horizontalBarChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) = onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = onValueSelected(entryFloat, highlight) override fun onNothingSelected() = onValueSelected(null, null) }) } diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/LineChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/LineChartComposable.kt index 97c511ac92..fd7de38fdf 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/LineChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/LineChartComposable.kt @@ -13,7 +13,7 @@ import info.appdev.charting.charts.LineChart import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -54,7 +54,7 @@ fun LineChart( data: LineData?, modifier: Modifier = Modifier, state: LineChartState = rememberLineChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -145,8 +145,8 @@ fun LineChart( // Selection listener if (onValueSelected != null) { lineChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) { - onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + onValueSelected(entryFloat, highlight) } override fun onNothingSelected() { diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/PieChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/PieChartComposable.kt index 987c4f27f9..bd89574331 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/PieChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/PieChartComposable.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.viewinterop.AndroidView import info.appdev.charting.animation.Easing import info.appdev.charting.charts.PieChart import info.appdev.charting.components.Legend -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.PieData import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -47,7 +47,7 @@ fun PieChart( data: PieData?, modifier: Modifier = Modifier, state: PieChartState = rememberPieChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, backgroundColor: androidx.compose.ui.graphics.Color = androidx.compose.ui.graphics.Color.White, @@ -124,8 +124,8 @@ fun PieChart( // Selection listener if (onValueSelected != null) { pieChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) { - onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + onValueSelected(entryFloat, highlight) } override fun onNothingSelected() { diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/RadarChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/RadarChartComposable.kt index 42b23c9635..c433742684 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/RadarChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/RadarChartComposable.kt @@ -13,7 +13,7 @@ import info.appdev.charting.charts.RadarChart import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.RadarData import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -26,7 +26,7 @@ fun RadarChart( data: RadarData?, modifier: Modifier = Modifier, state: RadarChartState = rememberRadarChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -82,7 +82,7 @@ fun RadarChart( if (onValueSelected != null) { radarChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) = onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = onValueSelected(entryFloat, highlight) override fun onNothingSelected() = onValueSelected(null, null) }) } diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/ScatterChartComposable.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/ScatterChartComposable.kt index 0ec1bef766..7e84575c60 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/ScatterChartComposable.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/ScatterChartComposable.kt @@ -13,7 +13,7 @@ import info.appdev.charting.charts.ScatterChart import info.appdev.charting.components.Legend import info.appdev.charting.components.XAxis import info.appdev.charting.components.YAxis -import info.appdev.charting.data.Entry +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.ScatterData import info.appdev.charting.highlight.Highlight import info.appdev.charting.listener.OnChartValueSelectedListener @@ -26,7 +26,7 @@ fun ScatterChart( data: ScatterData?, modifier: Modifier = Modifier, state: ScatterChartState = rememberScatterChartState(), - onValueSelected: ((Entry?, Highlight?) -> Unit)? = null, + onValueSelected: ((EntryFloat?, Highlight?) -> Unit)? = null, description: String? = null, legend: ((Legend) -> Unit)? = null, xAxisConfig: ((XAxis) -> Unit)? = null, @@ -92,7 +92,7 @@ fun ScatterChart( if (onValueSelected != null) { scatterChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { - override fun onValueSelected(entry: Entry, highlight: Highlight) = onValueSelected(entry, highlight) + override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) = onValueSelected(entryFloat, highlight) override fun onNothingSelected() = onValueSelected(null, null) }) } diff --git a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/examples/ChartExamples.kt b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/examples/ChartExamples.kt index df3e438487..7ffb5fbca0 100644 --- a/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/examples/ChartExamples.kt +++ b/chartLibCompose/src/main/kotlin/info/appdev/charting/compose/examples/ChartExamples.kt @@ -33,16 +33,16 @@ import info.appdev.charting.compose.ScatterChart import info.appdev.charting.compose.rememberLineChartState import info.appdev.charting.data.BarData import info.appdev.charting.data.BarDataSet -import info.appdev.charting.data.BarEntry -import info.appdev.charting.data.Entry +import info.appdev.charting.data.BarEntryFloat +import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet import info.appdev.charting.data.PieData import info.appdev.charting.data.PieDataSet -import info.appdev.charting.data.PieEntry +import info.appdev.charting.data.PieEntryFloat import info.appdev.charting.data.RadarData import info.appdev.charting.data.RadarDataSet -import info.appdev.charting.data.RadarEntry +import info.appdev.charting.data.RadarEntryFloat import info.appdev.charting.data.ScatterData import info.appdev.charting.data.ScatterDataSet @@ -77,7 +77,7 @@ fun LineChartExample() { Spacer(modifier = Modifier.height(8.dp)) val entries = remember { - (0..10).map { Entry(it.toFloat(), (10..50).random().toFloat()) } + (0..10).map { EntryFloat(it.toFloat(), (10..50).random().toFloat()) } } val dataSet = remember(entries) { @@ -144,7 +144,7 @@ fun BarChartExample() { Spacer(modifier = Modifier.height(8.dp)) val entries = remember { - (0..5).map { BarEntry(it.toFloat(), (20..80).random().toFloat()) } + (0..5).map { BarEntryFloat(it.toFloat(), (20..80).random().toFloat()) } } val dataSet = remember(entries) { @@ -188,11 +188,11 @@ fun PieChartExample() { val entries = remember { listOf( - PieEntry(30f, "Product A"), - PieEntry(25f, "Product B"), - PieEntry(20f, "Product C"), - PieEntry(15f, "Product D"), - PieEntry(10f, "Product E") + PieEntryFloat(30f, "Product A"), + PieEntryFloat(25f, "Product B"), + PieEntryFloat(20f, "Product C"), + PieEntryFloat(15f, "Product D"), + PieEntryFloat(10f, "Product E") ) } @@ -247,7 +247,7 @@ fun ScatterChartExample() { val entries = remember { (0..20).map { - Entry(it.toFloat(), (10..50).random().toFloat()) + EntryFloat(it.toFloat(), (10..50).random().toFloat()) } } @@ -286,11 +286,11 @@ fun RadarChartExample() { val entries = remember { listOf( - RadarEntry(8f, "Speed"), - RadarEntry(7f, "Strength"), - RadarEntry(6f, "Defense"), - RadarEntry(9f, "Agility"), - RadarEntry(7f, "Intelligence") + RadarEntryFloat(8f, "Speed"), + RadarEntryFloat(7f, "Strength"), + RadarEntryFloat(6f, "Defense"), + RadarEntryFloat(9f, "Agility"), + RadarEntryFloat(7f, "Intelligence") ) } @@ -367,7 +367,7 @@ fun DynamicChartExample() { Button( onClick = { val entries = (0 until dataPoints).map { - Entry(it.toFloat(), (10..50).random().toFloat()) + EntryFloat(it.toFloat(), (10..50).random().toFloat()) } val dataSet = LineDataSet(entries.toMutableList(), "Random Data") state.data = LineData(dataSet) From a39367112eb3cb7c7cfada9573be21fcb5dd5516 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 11:40:14 +0200 Subject: [PATCH 3/9] IDataSet generic Use BaseEntry instead of FloatEntry --- .../src/main/kotlin/info/appdev/charting/data/ChartData.kt | 4 ++-- .../info/appdev/charting/highlight/ChartHighlighter.kt | 6 +++--- .../appdev/charting/highlight/HorizontalBarHighlighter.kt | 6 +++--- .../datasets/IBarLineScatterCandleBubbleDataSet.kt | 4 ++-- .../info/appdev/charting/interfaces/datasets/IDataSet.kt | 4 ++-- .../charting/interfaces/datasets/ILineRadarDataSet.kt | 4 ++-- .../interfaces/datasets/ILineScatterCandleRadarDataSet.kt | 4 ++-- .../charting/renderer/BarLineScatterCandleBubbleRenderer.kt | 6 +++--- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt index 7902f3ecd9..84ee4ea1cf 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/ChartData.kt @@ -52,7 +52,7 @@ abstract class ChartData> : Serializable { protected set constructor() { - this.dataSets = ArrayList() + this.dataSets = ArrayList() } constructor(vararg dataSets: T) { @@ -446,7 +446,7 @@ abstract class ChartData> : Serializable { } val dataSet: IDataSet<*> = dataSets[dataSetIndex] - val entryFloat: EntryFloat = dataSet.getEntryForXValue(xValue, Float.NaN) ?: return false + val entryFloat: EntryFloat = dataSet.getEntryForXValue(xValue, Float.NaN) as? EntryFloat ?: return false return removeEntry(entryFloat, dataSetIndex) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt index 9d0eac051b..ddd7606482 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/ChartHighlighter.kt @@ -122,12 +122,12 @@ open class ChartHighlighter>(prote ): MutableList { val highlights = ArrayList() - var entries = set.getEntriesForXValue(xVal) + var entries = set.getEntriesForXValue(xVal)?.map { it as EntryFloat }?.toMutableList() if (entries != null && entries.isEmpty()) { // Try to find closest x-value and take all entries for that x-value - val closest: EntryFloat? = set.getEntryForXValue(xVal, Float.NaN, rounding) + val closest: EntryFloat? = set.getEntryForXValue(xVal, Float.NaN, rounding) as? EntryFloat if (closest != null) { - entries = set.getEntriesForXValue(closest.x) + entries = set.getEntriesForXValue(closest.x)?.map { it as EntryFloat }?.toMutableList() } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt index 8354c9fe44..8e61df89df 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/HorizontalBarHighlighter.kt @@ -35,12 +35,12 @@ class HorizontalBarHighlighter(dataProvider: BarDataProvider) : BarHighlighter(d override fun buildHighlights(set: IDataSet<*>, dataSetIndex: Int, xVal: Float, rounding: DataSet.Rounding?): MutableList { val highlights = ArrayList() - var entries = set.getEntriesForXValue(xVal) + var entries = set.getEntriesForXValue(xVal)?.map { it as EntryFloat }?.toMutableList() if (entries != null && entries.isEmpty()) { // Try to find closest x-value and take all entries for that x-value - val closestEntryFloat: EntryFloat? = set.getEntryForXValue(xVal, Float.NaN, rounding) + val closestEntryFloat: EntryFloat? = set.getEntryForXValue(xVal, Float.NaN, rounding) as? EntryFloat closestEntryFloat?.let { closestE -> - entries = set.getEntriesForXValue(closestE.x) + entries = set.getEntriesForXValue(closestE.x)?.map { it as EntryFloat }?.toMutableList() } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt index ead34a8bc4..620d555cb9 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IBarLineScatterCandleBubbleDataSet.kt @@ -1,8 +1,8 @@ package info.appdev.charting.interfaces.datasets -import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.BaseEntry -interface IBarLineScatterCandleBubbleDataSet : IDataSet { +interface IBarLineScatterCandleBubbleDataSet> : IDataSet { val highLightColor: Int } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt index 43db6096f6..d0f0ceef28 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/IDataSet.kt @@ -5,11 +5,11 @@ import android.graphics.Typeface import info.appdev.charting.components.Legend import info.appdev.charting.components.YAxis import info.appdev.charting.data.DataSet -import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.BaseEntry import info.appdev.charting.formatter.IValueFormatter import info.appdev.charting.utils.PointF -interface IDataSet { +interface IDataSet> { /** * returns the minimum y-value this DataSet holds */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt index 050bc462f2..31ebc9986f 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineRadarDataSet.kt @@ -1,9 +1,9 @@ package info.appdev.charting.interfaces.datasets import android.graphics.drawable.Drawable -import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.BaseEntry -interface ILineRadarDataSet : ILineScatterCandleRadarDataSet { +interface ILineRadarDataSet> : ILineScatterCandleRadarDataSet { /** * Returns the color that is used for filling the line surface area. */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt index f260a293e3..8e1f2868e2 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineScatterCandleRadarDataSet.kt @@ -1,9 +1,9 @@ package info.appdev.charting.interfaces.datasets import android.graphics.DashPathEffect -import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.BaseEntry -interface ILineScatterCandleRadarDataSet : IBarLineScatterCandleBubbleDataSet { +interface ILineScatterCandleRadarDataSet> : IBarLineScatterCandleBubbleDataSet { /** * Returns true if vertical highlight indicator lines are enabled (drawn) */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt index 577b42a86b..8b256869fc 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/BarLineScatterCandleBubbleRenderer.kt @@ -2,7 +2,7 @@ package info.appdev.charting.renderer import info.appdev.charting.animation.ChartAnimator import info.appdev.charting.data.DataSet -import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.BaseEntry import info.appdev.charting.interfaces.dataprovider.base.BarLineScatterCandleBubbleDataProvider import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet import info.appdev.charting.interfaces.datasets.IDataSet @@ -29,7 +29,7 @@ abstract class BarLineScatterCandleBubbleRenderer( /** * Checks if the provided entry object is in bounds for drawing considering the current animation phase. */ - protected fun isInBoundsX(entry: T, set: IBarLineScatterCandleBubbleDataSet): Boolean { + protected fun > isInBoundsX(entry: T, set: IBarLineScatterCandleBubbleDataSet): Boolean { val entryIndex = set.getEntryIndex(entry).toFloat() return if (entryIndex >= set.entryCount * animator.phaseX) { @@ -61,7 +61,7 @@ abstract class BarLineScatterCandleBubbleRenderer( /** * Calculates the minimum and maximum x values as well as the range between them. */ - fun set(chart: BarLineScatterCandleBubbleDataProvider<*>, dataSet: IBarLineScatterCandleBubbleDataSet) { + fun > set(chart: BarLineScatterCandleBubbleDataProvider<*>, dataSet: IBarLineScatterCandleBubbleDataSet) { val phaseX = max(0f, min(1f, animator.phaseX)) val low = chart.lowestVisibleX From e76041b01e8142e24f7254abf25a5f6b898fc370 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 14:01:16 +0200 Subject: [PATCH 4/9] Add x to BaseEntry --- .../info/appdev/charting/data/BaseEntry.kt | 27 +++++++++- .../info/appdev/charting/data/EntryDouble.kt | 49 +++++++------------ .../info/appdev/charting/data/EntryFloat.kt | 49 +++++++------------ 3 files changed, 64 insertions(+), 61 deletions(-) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt index b3f2725b5f..fcc4bf3f1c 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseEntry.kt @@ -4,6 +4,13 @@ import android.graphics.drawable.Drawable abstract class BaseEntry where T : Number, T : Comparable { + protected lateinit var xBase: T + open var x: T + get() = xBase + set(value) { + xBase = value + } + protected lateinit var yBase: T open var y: T get() = yBase @@ -21,6 +28,11 @@ abstract class BaseEntry where T : Number, T : Comparable { this.yBase = y } + constructor(x: T, y: T) { + this.xBase = x + this.yBase = y + } + constructor(y: T, data: Any?) : this(y) { this.data = data } @@ -29,7 +41,20 @@ abstract class BaseEntry where T : Number, T : Comparable { this.icon = icon } - constructor(y: T, icon: Drawable?, data: Any?) : this(y) { + constructor(y: T, icon: Drawable?, data: Any?) : this(y = y) { + this.icon = icon + this.data = data + } + + constructor(x: T, y: T, data: Any?) : this(x = x, y = y) { + this.data = data + } + + constructor(x: T, y: T, icon: Drawable?) : this(x = x, y = y) { + this.icon = icon + } + + constructor(x: T, y: T, icon: Drawable?, data: Any?) : this(x = x, y = y) { this.icon = icon this.data = data } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt index 955460af82..0a88e0bedc 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt @@ -11,64 +11,53 @@ import kotlin.math.abs open class EntryDouble : BaseEntry, Parcelable, Serializable { - private var _x: Double = 0.0 - open var x: Double - get() = _x - set(value) { - _x = value - } - constructor() /** - * A Entry represents one single entry in the chart. + * An Entry represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) */ - constructor(x: Double, y: Double) : super(y) { - this._x = x - } + constructor(x: Double, y: Double) : super(x = x, y = y) /** - * A Entry represents one single entry in the chart. + * An Entry represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param data Spot for additional data this Entry represents. */ - constructor(x: Double, y: Double, data: Any?) : super(y, data) { - this._x = x - } + constructor(x: Double, y: Double, data: Any?) : super(x = x, y = y, data = data) /** - * A Entry represents one single entry in the chart. + * An Entry represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param icon icon image */ - constructor(x: Double, y: Double, icon: Drawable?) : super(y, icon) { - this._x = x - } + constructor(x: Double, y: Double, icon: Drawable?) : super(x = x, y = y, icon = icon) /** - * A Entry represents one single entry in the chart. + * An Entry represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param icon icon image * @param data Spot for additional data this Entry represents. */ - constructor(x: Double, y: Double, icon: Drawable?, data: Any?) : super(y, icon, data) { - this._x = x - } + constructor(x: Double, y: Double, icon: Drawable?, data: Any?) : super(x = x, y = y, icon = icon, data = data) /** * returns an exact copy of the entry */ open fun copy(): EntryDouble { - val e = EntryDouble(x, y, data) + val e = EntryDouble( + x = x, + y = y, + data = data + ) return e } @@ -77,17 +66,17 @@ open class EntryDouble : BaseEntry, Parcelable, Serializable { * are equal in those points, false if not. Does not check by hash-code like * it's done by the "equals" method. */ - fun equalTo(e: EntryDouble?): Boolean { - if (e == null) + fun equalTo(entryDouble: EntryDouble?): Boolean { + if (entryDouble == null) return false - if (e.data !== this.data) + if (entryDouble.data !== this.data) return false - if (abs((e.x - this.x)) > Utils.DOUBLE_EPSILON) + if (abs((entryDouble.x - this.x)) > Utils.DOUBLE_EPSILON) return false - if (abs((e.y - this.y)) > Utils.DOUBLE_EPSILON) + if (abs((entryDouble.y - this.y)) > Utils.DOUBLE_EPSILON) return false return true @@ -124,7 +113,7 @@ open class EntryDouble : BaseEntry, Parcelable, Serializable { } protected constructor(`in`: Parcel) { - this._x = `in`.readDouble() + this.x = `in`.readDouble() this.yBase = `in`.readDouble() if (`in`.readInt() == 1) { this.data = if (Build.VERSION.SDK_INT >= 33) { diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt index 431d261551..f25202e989 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryFloat.kt @@ -15,64 +15,53 @@ import kotlin.math.abs */ open class EntryFloat : BaseEntry, Parcelable, Serializable { - private var _x: Float = 0f - open var x: Float - get() = _x - set(value) { - _x = value - } - constructor() /** - * A EntryFloat represents one single entry in the chart. + * An EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) */ - constructor(x: Float, y: Float) : super(y) { - this._x = x - } + constructor(x: Float, y: Float) : super(x = x, y = y) /** - * A EntryFloat represents one single entry in the chart. + * An EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param data Spot for additional data this Entry represents. */ - constructor(x: Float, y: Float, data: Any?) : super(y, data) { - this._x = x - } + constructor(x: Float, y: Float, data: Any?) : super(x = x, y = y, data = data) /** - * A EntryFloat represents one single entry in the chart. + * An EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param icon icon image */ - constructor(x: Float, y: Float, icon: Drawable?) : super(y, icon) { - this._x = x - } + constructor(x: Float, y: Float, icon: Drawable?) : super(x = x, y = y, icon = icon) /** - * A EntryFloat represents one single entry in the chart. + * An EntryFloat represents one single entry in the chart. * * @param x the x value * @param y the y value (the actual value of the entry) * @param icon icon image * @param data Spot for additional data this EntryFloat represents. */ - constructor(x: Float, y: Float, icon: Drawable?, data: Any?) : super(y, icon, data) { - this._x = x - } + constructor(x: Float, y: Float, icon: Drawable?, data: Any?) : super(x = x, y = y, icon = icon, data = data) /** * returns an exact copy of the entry */ open fun copy(): EntryFloat { - val e = EntryFloat(x, y, data) + val e = EntryFloat( + x = x, + y = y, + data = data + ) return e } @@ -81,17 +70,17 @@ open class EntryFloat : BaseEntry, Parcelable, Serializable { * are equal in those points, false if not. Does not check by hash-code like * it's done by the "equals" method. */ - fun equalTo(e: EntryFloat?): Boolean { - if (e == null) + fun equalTo(entryFloat: EntryFloat?): Boolean { + if (entryFloat == null) return false - if (e.data !== this.data) + if (entryFloat.data !== this.data) return false - if (abs((e.x - this.x).toDouble()) > Utils.FLOAT_EPSILON) + if (abs((entryFloat.x - this.x).toDouble()) > Utils.FLOAT_EPSILON) return false - if (abs((e.y - this.y).toDouble()) > Utils.FLOAT_EPSILON) + if (abs((entryFloat.y - this.y).toDouble()) > Utils.FLOAT_EPSILON) return false return true @@ -128,7 +117,7 @@ open class EntryFloat : BaseEntry, Parcelable, Serializable { } protected constructor(`in`: Parcel) { - this._x = `in`.readFloat() + this.x = `in`.readFloat() this.yBase = `in`.readFloat() if (`in`.readInt() == 1) { this.data = if (Build.VERSION.SDK_INT >= 33) { From ab5e1493425e3ce50280ba7c7641c9084d7e165c Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 14:43:16 +0200 Subject: [PATCH 5/9] DataSet more generic --- .../data/BarLineScatterCandleBubbleDataSet.kt | 2 +- .../info/appdev/charting/data/BaseDataSet.kt | 2 +- .../info/appdev/charting/data/DataSet.kt | 37 +++++-------------- .../appdev/charting/data/LineRadarDataSet.kt | 2 +- .../data/LineScatterCandleRadarDataSet.kt | 2 +- 5 files changed, 14 insertions(+), 31 deletions(-) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt index 40096e1968..2751e47033 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BarLineScatterCandleBubbleDataSet.kt @@ -7,7 +7,7 @@ import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataS /** * Baseclass of all DataSets for Bar-, Line-, Scatter- and CandleStickChart. */ -abstract class BarLineScatterCandleBubbleDataSet(yVals: MutableList, label: String) : +abstract class BarLineScatterCandleBubbleDataSet>(yVals: MutableList, label: String) : DataSet(yVals, label), IBarLineScatterCandleBubbleDataSet { /** * Sets the color that is used for drawing the highlight indicators. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt index 6ba5af0633..110ae26cb0 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BaseDataSet.kt @@ -19,7 +19,7 @@ import info.appdev.charting.utils.convertDpToPixel * This is the base dataset of all DataSets. Its purpose is to implement critical methods * provided by the IDataSet interface. */ -abstract class BaseDataSet() : IDataSet { +abstract class BaseDataSet>() : IDataSet { /** * List representing all colors that are used for this DataSet */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/DataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/DataSet.kt index 9a0d5059e1..33b87d3151 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/DataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/DataSet.kt @@ -10,7 +10,7 @@ import kotlin.math.abs * groups of values inside the Chart (e.g. the values for a specific line in the * LineChart, or the values of a specific group of bars in the BarChart). */ -abstract class DataSet( +abstract class DataSet>( protected var entriesInternal: MutableList, label: String = "" ) : BaseDataSet(label), Serializable { @@ -219,31 +219,22 @@ abstract class DataSet( while (low < high) { val m = low + (high - low) / 2 - val currentEntryFloat: EntryFloat = entriesInternal[m] + val current = entriesInternal[m] + val next = entriesInternal[m + 1] - val nextEntryFloat: EntryFloat = entriesInternal[m + 1] - - val d1 = currentEntryFloat.x - xValue - val d2 = nextEntryFloat.x - xValue + val d1 = current.x - xValue + val d2 = next.x - xValue val ad1 = abs(d1) val ad2 = abs(d2) if (ad2 < ad1) { - // [m + 1] is closer to xValue - // Search in a higher place low = m + 1 } else if (ad1 < ad2) { - // [m] is closer to xValue - // Search in a lower place high = m } else { - // We have multiple sequential x-value with same distance - if (d1 >= 0.0) { - // Search in a lower place high = m } else if (d1 < 0.0) { - // Search in a higher place low = m + 1 } } @@ -251,40 +242,32 @@ abstract class DataSet( closest = high } - val closestEntryFloat: EntryFloat = entriesInternal[closest] - val closestXValue = closestEntryFloat.x + val closestEntry = entriesInternal[closest] + val closestXValue = closestEntry.x if (rounding == Rounding.UP) { - // If rounding up, and found x-value is lower than specified x, and we can go upper... if (closestXValue < xValue && closest < entriesInternal.size - 1) { ++closest } } else if (rounding == Rounding.DOWN) { - // If rounding down, and found x-value is upper than specified x, and we can go lower... if (closestXValue > xValue && closest > 0) { --closest } } - // Search by closest to y-value if (!closestToY.isNaN()) { while (closest > 0 && entriesInternal[closest - 1].x == closestXValue) { closest -= 1 } - var closestYValue = closestEntryFloat.y + var closestYValue = closestEntry.y var closestYIndex = closest while (true) { closest += 1 - if (closest >= entriesInternal.size) { - break - } + if (closest >= entriesInternal.size) break val value: T = entriesInternal[closest] - - if (value.x != closestXValue) { - break - } + if (value.x != closestXValue) break if (abs(value.y - closestToY) <= abs(closestYValue - closestToY)) { closestYValue = closestToY diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt index cb52f42bca..c1b270955d 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineRadarDataSet.kt @@ -9,7 +9,7 @@ import info.appdev.charting.utils.convertDpToPixel /** * Base dataset for line and radar DataSets. */ -abstract class LineRadarDataSet(yVals: MutableList, label: String) : LineScatterCandleRadarDataSet(yVals, label), ILineRadarDataSet { +abstract class LineRadarDataSet>(yVals: MutableList, label: String) : LineScatterCandleRadarDataSet(yVals, label), ILineRadarDataSet { // TODO: Move to using `Fill` class /** * the color that is used for filling the line surface diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt index c5f782fc4a..5a2a9a8111 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineScatterCandleRadarDataSet.kt @@ -4,7 +4,7 @@ import android.graphics.DashPathEffect import info.appdev.charting.interfaces.datasets.ILineScatterCandleRadarDataSet import info.appdev.charting.utils.convertDpToPixel -abstract class LineScatterCandleRadarDataSet(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), +abstract class LineScatterCandleRadarDataSet>(yVals: MutableList, label: String) : BarLineScatterCandleBubbleDataSet(yVals, label), ILineScatterCandleRadarDataSet { override var isVerticalHighlightIndicator: Boolean = true override var isHorizontalHighlightIndicator: Boolean = true From 9004471b1ddffc5f71f8efc9d451846f6da96ae3 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 18:33:54 +0200 Subject: [PATCH 6/9] DataSet generic --- .../chartexample/CubicLineChartActivity.kt | 6 +- .../info/appdev/chartexample/DataTools.kt | 4 +- .../chartexample/DynamicalAddingActivity.kt | 4 +- .../appdev/chartexample/FilledLineActivity.kt | 14 +- .../appdev/chartexample/GradientActivity.kt | 2 +- .../appdev/chartexample/LineChartActivity.kt | 8 +- .../chartexample/LineChartDualAxisActivity.kt | 12 +- .../ListViewMultiChartActivity.kt | 2 +- .../chartexample/MultiLineChartActivity.kt | 4 +- .../chartexample/RealtimeLineChartActivity.kt | 6 +- .../SpecificPositionsLineChartActivity.kt | 2 +- .../compose/MultiLineComposeActivity.kt | 5 +- .../chartexample/formatter/MyFillFormatter.kt | 2 +- .../chartexample/fragments/SimpleFragment.kt | 4 +- .../charting/charts/BarLineChartBase.kt | 1 + .../info/appdev/charting/data/EntryDouble.kt | 160 ++++++------------ .../info/appdev/charting/data/LineData.kt | 6 +- .../info/appdev/charting/data/LineDataSet.kt | 13 +- .../formatter/DefaultFillFormatter.kt | 2 +- .../charting/formatter/IFillFormatter.kt | 2 +- .../interfaces/datasets/ILineDataSet.kt | 4 +- .../charting/renderer/LineChartRenderer.kt | 33 ++-- .../info/appdev/charting/utils/Transformer.kt | 2 +- 23 files changed, 123 insertions(+), 175 deletions(-) diff --git a/app/src/main/kotlin/info/appdev/chartexample/CubicLineChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/CubicLineChartActivity.kt index f20c39e379..73642a52fc 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/CubicLineChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/CubicLineChartActivity.kt @@ -91,10 +91,10 @@ class CubicLineChartActivity : DemoBase(), OnSeekBarChangeListener { values.add(EntryFloat(i.toFloat(), `val`)) } - val set1: LineDataSet + val set1: LineDataSet if (binding.chart1.lineData.dataSetCount > 0) { - set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet + set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet set1.entries = values binding.chart1.lineData.notifyDataChanged() binding.chart1.notifyDataSetChanged() @@ -115,7 +115,7 @@ class CubicLineChartActivity : DemoBase(), OnSeekBarChangeListener { set1.fillAlpha = 100 set1.isHorizontalHighlightIndicator = false set1.fillFormatter = object : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { return binding.chart1.axisLeft.axisMinimum } } diff --git a/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt b/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt index 1c004b4eed..0ae78e9827 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/DataTools.kt @@ -226,7 +226,7 @@ class DataTools { // set the filled area lineDataSet01.isDrawFilled = true lineDataSet01.fillFormatter = object : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { return lineChart.axisLeft.axisMinimum } } @@ -239,7 +239,7 @@ class DataTools { } else { lineDataSet01.fillColor = Color.BLACK } - val dataSets = ArrayList() + val dataSets = ArrayList>() dataSets.add(lineDataSet01) // add the data sets // create a data object with the data sets diff --git a/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt index 82b3f64ae3..e5a00dcc0f 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/DynamicalAddingActivity.kt @@ -147,8 +147,8 @@ class DynamicalAddingActivity : DemoBase(), OnChartValueSelectedListener { } } - private fun createSet(): LineDataSet { - val set = LineDataSet(label = "DataSet 1") + private fun createSet(): LineDataSet { + val set = LineDataSet(label = "DataSet 1") set.lineWidth = 2.5f set.circleRadius = 4.5f set.color = Color.rgb(240, 99, 99) diff --git a/app/src/main/kotlin/info/appdev/chartexample/FilledLineActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/FilledLineActivity.kt index da3e9ea1f4..f8e0826379 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/FilledLineActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/FilledLineActivity.kt @@ -84,12 +84,12 @@ class FilledLineActivity : DemoBase() { valuesArray2.add(EntryFloat(i.toFloat(), valueY)) } - val set1: LineDataSet - val set2: LineDataSet + val set1: LineDataSet + val set2: LineDataSet if (binding.chart1.lineData.dataSetCount > 0) { - set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet - set2 = binding.chart1.lineData.getDataSetByIndex(1) as LineDataSet + set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet + set2 = binding.chart1.lineData.getDataSetByIndex(1) as LineDataSet set1.entries = valuesArray1 set2.entries = valuesArray2 binding.chart1.lineData.notifyDataChanged() @@ -109,7 +109,7 @@ class FilledLineActivity : DemoBase() { set1.highLightColor = Color.rgb(244, 117, 117) set1.isDrawCircleHoleEnabled = false set1.fillFormatter = object : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { // change the return value here to better understand the effect // return 0; return binding.chart1.axisLeft.axisMinimum @@ -129,14 +129,14 @@ class FilledLineActivity : DemoBase() { set2.isDrawCircleHoleEnabled = false set2.highLightColor = Color.rgb(244, 117, 117) set2.fillFormatter = object : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { // change the return value here to better understand the effect // return 600; return binding.chart1.axisLeft.axisMaximum } } - val dataSets = ArrayList() + val dataSets = ArrayList>() dataSets.add(set1) // add the data sets dataSets.add(set2) diff --git a/app/src/main/kotlin/info/appdev/chartexample/GradientActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/GradientActivity.kt index 405ab48d76..c3fda989b0 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/GradientActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/GradientActivity.kt @@ -62,7 +62,7 @@ class GradientActivity : DemoBase() { fillFormatter = object : IFillFormatter { override fun getFillLinePosition( - dataSet: ILineDataSet?, + dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider ): Float = binding.chart1.axisLeft.axisMinimum } diff --git a/app/src/main/kotlin/info/appdev/chartexample/LineChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/LineChartActivity.kt index 62531d99d4..ea61629c70 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/LineChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/LineChartActivity.kt @@ -181,14 +181,14 @@ class LineChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSelec } R.id.actionToggleCircles -> { - binding.chart1.data?.dataSets?.map { it as LineDataSet }?.forEach { set -> + binding.chart1.data?.dataSets?.map { it as LineDataSet<*> }?.forEach { set -> set.isDrawCircles = !set.isDrawCircles } binding.chart1.invalidate() } R.id.actionToggleCubic -> { - binding.chart1.data?.dataSets?.map { it as LineDataSet }?.forEach { set -> + binding.chart1.data?.dataSets?.map { it as LineDataSet<*> }?.forEach { set -> set.lineMode = if (set.lineMode == LineDataSet.Mode.CUBIC_BEZIER) LineDataSet.Mode.LINEAR else @@ -198,7 +198,7 @@ class LineChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSelec } R.id.actionToggleStepped -> { - binding.chart1.data?.dataSets?.map { it as LineDataSet }?.forEach { set -> + binding.chart1.data?.dataSets?.map { it as LineDataSet<*> }?.forEach { set -> set.lineMode = if (set.lineMode == LineDataSet.Mode.STEPPED) LineDataSet.Mode.LINEAR else @@ -208,7 +208,7 @@ class LineChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSelec } R.id.actionToggleHorizontalCubic -> { - binding.chart1.data?.dataSets?.map { it as LineDataSet }?.forEach { set -> + binding.chart1.data?.dataSets?.map { it as LineDataSet<*> }?.forEach { set -> set.lineMode = if (set.lineMode == LineDataSet.Mode.HORIZONTAL_BEZIER) LineDataSet.Mode.LINEAR else diff --git a/app/src/main/kotlin/info/appdev/chartexample/LineChartDualAxisActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/LineChartDualAxisActivity.kt index aa94d3eb37..99559b132f 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/LineChartDualAxisActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/LineChartDualAxisActivity.kt @@ -130,14 +130,14 @@ class LineChartDualAxisActivity : DemoBase(), OnSeekBarChangeListener, OnChartVa values3.add(EntryFloat(i.toFloat(), `val`)) } - val set1: LineDataSet - val set2: LineDataSet - val set3: LineDataSet + val set1: LineDataSet + val set2: LineDataSet + val set3: LineDataSet if (binding.chart1.lineData.dataSetCount > 0) { - set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet - set2 = binding.chart1.lineData.getDataSetByIndex(1) as LineDataSet - set3 = binding.chart1.lineData.getDataSetByIndex(2) as LineDataSet + set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet + set2 = binding.chart1.lineData.getDataSetByIndex(1) as LineDataSet + set3 = binding.chart1.lineData.getDataSetByIndex(2) as LineDataSet set1.entries = values1 set2.entries = values2 set3.entries = values3 diff --git a/app/src/main/kotlin/info/appdev/chartexample/ListViewMultiChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/ListViewMultiChartActivity.kt index 2465828a07..815516354c 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/ListViewMultiChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/ListViewMultiChartActivity.kt @@ -116,7 +116,7 @@ class ListViewMultiChartActivity : DemoBase() { d2.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[0]) d2.isDrawValues = false - val sets = ArrayList() + val sets = ArrayList>() sets.add(d1) sets.add(d2) diff --git a/app/src/main/kotlin/info/appdev/chartexample/MultiLineChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/MultiLineChartActivity.kt index 0f6222011c..3a45531cb6 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/MultiLineChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/MultiLineChartActivity.kt @@ -84,7 +84,7 @@ class MultiLineChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartGestu binding.tvXMax.text = binding.seekBarX.progress.toString() binding.tvYMax.text = binding.seekBarY.progress.toString() - val dataSets = ArrayList() + val dataSets = ArrayList>() for (datasetNumber in 0..2) { val values = ArrayList() @@ -111,7 +111,7 @@ class MultiLineChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartGestu } // make the first DataSet dashed - (dataSets[0] as LineDataSet).enableDashedLine(10f, 10f, 0f) + (dataSets[0] as LineDataSet<*>).enableDashedLine(10f, 10f, 0f) val data = LineData(dataSets) binding.chart1.data = data diff --git a/app/src/main/kotlin/info/appdev/chartexample/RealtimeLineChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/RealtimeLineChartActivity.kt index fbbe5ab59a..1e9b361f3b 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/RealtimeLineChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/RealtimeLineChartActivity.kt @@ -92,7 +92,7 @@ class RealtimeLineChartActivity : DemoBase(), OnChartValueSelectedListener { data.addDataSet(set) } - val cycleValue = (set.entryCount % 100.0).toInt() + val cycleValue = (set!!.entryCount % 100.0).toInt() data.addEntry(EntryFloat(set.entryCount.toFloat(), (sampleValues[cycleValue]!!.toFloat() * 40) + 30f), 0) data.notifyDataChanged() @@ -112,8 +112,8 @@ class RealtimeLineChartActivity : DemoBase(), OnChartValueSelectedListener { // AxisDependency.LEFT); } - private fun createSet(): LineDataSet { - val set = LineDataSet(label = "Dynamic Data") + private fun createSet(): LineDataSet { + val set = LineDataSet(label = "Dynamic Data") set.axisDependency = AxisDependency.LEFT set.color = ColorTemplate.holoBlue set.setCircleColor(Color.WHITE) diff --git a/app/src/main/kotlin/info/appdev/chartexample/SpecificPositionsLineChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/SpecificPositionsLineChartActivity.kt index d4e53c47be..a586736b0c 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/SpecificPositionsLineChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/SpecificPositionsLineChartActivity.kt @@ -269,7 +269,7 @@ class SpecificPositionsLineChartActivity : DemoBase(), OnSeekBarChangeListener, } else { set11.fillColor = Color.BLACK } - val dataSets = ArrayList() + val dataSets = ArrayList>() dataSets.add(set11) // add the datasets // create a data object with the datasets diff --git a/app/src/main/kotlin/info/appdev/chartexample/compose/MultiLineComposeActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/compose/MultiLineComposeActivity.kt index e693535957..5f7f4dbe0f 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/compose/MultiLineComposeActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/compose/MultiLineComposeActivity.kt @@ -326,7 +326,7 @@ class MultiLineComposeActivity : DemoBaseCompose() { showCircles: Boolean, lineMode: LineDataSet.Mode ): LineData { - val dataSets = ArrayList() + val dataSets = ArrayList>() for (datasetNumber in 0..2) { val values = ArrayList() @@ -359,6 +359,7 @@ class MultiLineComposeActivity : DemoBaseCompose() { // Make the first DataSet dashed dataSets[0].enableDashedLine(10f, 10f, 0f) - return LineData(ArrayList(dataSets.map { it as info.appdev.charting.interfaces.datasets.ILineDataSet })) + @Suppress("UNCHECKED_CAST") + return LineData(ArrayList(dataSets.map { it as info.appdev.charting.interfaces.datasets.ILineDataSet })) } } diff --git a/app/src/main/kotlin/info/appdev/chartexample/formatter/MyFillFormatter.kt b/app/src/main/kotlin/info/appdev/chartexample/formatter/MyFillFormatter.kt index 808db2daff..7f7b208527 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/formatter/MyFillFormatter.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/formatter/MyFillFormatter.kt @@ -6,7 +6,7 @@ import info.appdev.charting.interfaces.datasets.ILineDataSet @Suppress("unused") class MyFillFormatter(private val fillPos: Float) : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { // your logic could be here return fillPos } diff --git a/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt b/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt index e5f5797ef3..5907041a97 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/fragments/SimpleFragment.kt @@ -111,7 +111,7 @@ abstract class SimpleFragment : Fragment() { } protected fun generateLineData(): LineData { - val sets = ArrayList() + val sets = ArrayList>() val ds1 = LineDataSet(requireContext().assets.loadEntriesFromAssets("sine.txt"), "Sine function") val ds2 = LineDataSet(requireContext().assets.loadEntriesFromAssets("cosine.txt"), "Cosine function") @@ -135,7 +135,7 @@ abstract class SimpleFragment : Fragment() { protected val complexity: LineData get() { - val sets = ArrayList() + val sets = ArrayList>() val ds1 = LineDataSet(requireContext().assets.loadEntriesFromAssets("n.txt"), "O(n)") val ds2 = LineDataSet(requireContext().assets.loadEntriesFromAssets("nlogn.txt"), "O(nlogn)") diff --git a/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt b/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt index cf38afb165..350d7e1bf0 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/charts/BarLineChartBase.kt @@ -16,6 +16,7 @@ import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.components.YAxis import info.appdev.charting.components.YAxis.AxisDependency import info.appdev.charting.data.BarLineScatterCandleBubbleData +import info.appdev.charting.data.BaseEntry import info.appdev.charting.data.EntryFloat import info.appdev.charting.highlight.ChartHighlighter import info.appdev.charting.interfaces.dataprovider.base.BarLineScatterCandleBubbleDataProvider diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt index 0a88e0bedc..31b3138a9c 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/EntryDouble.kt @@ -2,139 +2,81 @@ package info.appdev.charting.data import android.graphics.drawable.Drawable import android.os.Build -import android.os.Parcel -import android.os.ParcelFormatException -import android.os.Parcelable -import info.appdev.charting.utils.Utils import java.io.Serializable import kotlin.math.abs +import info.appdev.charting.utils.Utils -open class EntryDouble : BaseEntry, Parcelable, Serializable { - - constructor() +/** + * High-precision entry that stores x and y as Double, but extends EntryFloat + * so it works seamlessly in the existing chart rendering pipeline. + * Use [xDouble] and [yDouble] to access the full-precision values. + */ +open class EntryDouble : EntryFloat, Serializable { - /** - * An Entry represents one single entry in the chart. - * - * @param x the x value - * @param y the y value (the actual value of the entry) - */ - constructor(x: Double, y: Double) : super(x = x, y = y) + var xDouble: Double = 0.0 + var yDouble: Double = 0.0 /** - * An Entry represents one single entry in the chart. - * - * @param x the x value - * @param y the y value (the actual value of the entry) - * @param data Spot for additional data this Entry represents. + * Override x to store/return via xDouble for high precision; + * the base chart pipeline reads x.toFloat() transparently. */ - constructor(x: Double, y: Double, data: Any?) : super(x = x, y = y, data = data) + override var x: Float + get() = xDouble.toFloat() + set(value) { + xDouble = value.toDouble() + } /** - * An Entry represents one single entry in the chart. - * - * @param x the x value - * @param y the y value (the actual value of the entry) - * @param icon icon image + * Override y to store/return via yDouble for high precision; + * the base chart pipeline reads y.toFloat() transparently. */ - constructor(x: Double, y: Double, icon: Drawable?) : super(x = x, y = y, icon = icon) + override var y: Float + get() = yDouble.toFloat() + set(value) { + yDouble = value.toDouble() + } - /** - * An Entry represents one single entry in the chart. - * - * @param x the x value - * @param y the y value (the actual value of the entry) - * @param icon icon image - * @param data Spot for additional data this Entry represents. - */ - constructor(x: Double, y: Double, icon: Drawable?, data: Any?) : super(x = x, y = y, icon = icon, data = data) + constructor() : super() - /** - * returns an exact copy of the entry - */ - open fun copy(): EntryDouble { - val e = EntryDouble( - x = x, - y = y, - data = data - ) - return e + constructor(x: Double, y: Double) : super() { + this.xDouble = x + this.yDouble = y } - /** - * Compares value, xIndex and data of the entries. Returns true if entries - * are equal in those points, false if not. Does not check by hash-code like - * it's done by the "equals" method. - */ - fun equalTo(entryDouble: EntryDouble?): Boolean { - if (entryDouble == null) - return false + constructor(x: Double, y: Double, data: Any?) : super() { + this.xDouble = x + this.yDouble = y + this.data = data + } - if (entryDouble.data !== this.data) - return false + constructor(x: Double, y: Double, icon: Drawable?) : super() { + this.xDouble = x + this.yDouble = y + this.icon = icon + } - if (abs((entryDouble.x - this.x)) > Utils.DOUBLE_EPSILON) - return false + constructor(x: Double, y: Double, icon: Drawable?, data: Any?) : super() { + this.xDouble = x + this.yDouble = y + this.icon = icon + this.data = data + } - if (abs((entryDouble.y - this.y)) > Utils.DOUBLE_EPSILON) - return false + open fun copyDouble(): EntryDouble = EntryDouble(xDouble, yDouble, data) + fun equalTo(other: EntryDouble?): Boolean { + if (other == null) return false + if (other.data !== this.data) return false + if (abs(other.xDouble - this.xDouble) > Utils.DOUBLE_EPSILON) return false + if (abs(other.yDouble - this.yDouble) > Utils.DOUBLE_EPSILON) return false return true } - /** - * returns a string representation of the entry containing x-index and value - */ override fun toString(): String { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - "${this.javaClass.typeName.substringAfterLast(".")} x=$x y=$y" - } else { - "EntryDouble x=$x y=$y" - } - } - - override fun describeContents(): Int { - return 0 - } - - override fun writeToParcel(dest: Parcel, flags: Int) { - dest.writeDouble(this.x) - dest.writeDouble(this.y) - if (data != null) { - if (data is Parcelable) { - dest.writeInt(1) - dest.writeParcelable(data as Parcelable?, flags) - } else { - throw ParcelFormatException("Cannot parcel an EntryDouble with non-parcelable data") - } + "${this.javaClass.typeName.substringAfterLast(".")} xDouble=$xDouble yDouble=$yDouble" } else { - dest.writeInt(0) - } - } - - protected constructor(`in`: Parcel) { - this.x = `in`.readDouble() - this.yBase = `in`.readDouble() - if (`in`.readInt() == 1) { - this.data = if (Build.VERSION.SDK_INT >= 33) { - `in`.readParcelable(Any::class.java.classLoader, Any::class.java) - } else { - @Suppress("DEPRECATION") - `in`.readParcelable(Any::class.java.classLoader) - } - } - } - - companion object { - @JvmField - val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): EntryDouble { - return EntryDouble(source) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } + "EntryDouble xDouble=$xDouble yDouble=$yDouble" } } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineData.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineData.kt index 4736b20213..eaf30862d8 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineData.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineData.kt @@ -5,10 +5,10 @@ import info.appdev.charting.interfaces.datasets.ILineDataSet /** * Data object that encapsulates all data associated with a LineChart. */ -class LineData : BarLineScatterCandleBubbleData { +class LineData : BarLineScatterCandleBubbleData> { constructor() : super() - constructor(vararg dataSets: ILineDataSet) : super(*dataSets) + constructor(vararg dataSets: ILineDataSet) : super(*dataSets) - constructor(dataSets: MutableList) : super(dataSets) + constructor(dataSets: MutableList>) : super(dataSets) } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt index 161aa24ebf..635c017d52 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/LineDataSet.kt @@ -12,7 +12,7 @@ import info.appdev.charting.utils.ColorTemplate import info.appdev.charting.utils.convertDpToPixel import timber.log.Timber -open class LineDataSet(yVals: MutableList = mutableListOf(), label: String = "") : LineRadarDataSet(yVals, label), ILineDataSet { +open class LineDataSet>(yVals: MutableList = mutableListOf(), label: String = "") : LineRadarDataSet(yVals, label), ILineDataSet { /** * Drawing mode for this line dataset */ @@ -73,17 +73,18 @@ open class LineDataSet(yVals: MutableList = mutableListOf(), label: circleColors.add(Color.rgb(140, 234, 255)) } - override fun copy(): DataSet { + @Suppress("UNCHECKED_CAST") + override fun copy(): DataSet? { val entries: MutableList = mutableListOf() for (i in entriesInternal.indices) { - entries.add(entriesInternal[i].copy()) + entries.add((entriesInternal[i] as EntryFloat).copy()) } - val copied = LineDataSet(entries, label) + val copied = LineDataSet(entries, label) copy(copied) - return copied + return copied as DataSet } - protected fun copy(lineDataSet: LineDataSet) { + protected fun copy(lineDataSet: LineDataSet<*>) { super.copy((lineDataSet as BaseDataSet<*>?)!!) lineDataSet.circleColors = this.circleColors lineDataSet.mCircleHoleColor = mCircleHoleColor diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultFillFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultFillFormatter.kt index cedd7eed51..6b403b6942 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultFillFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/DefaultFillFormatter.kt @@ -8,7 +8,7 @@ import info.appdev.charting.interfaces.datasets.ILineDataSet */ open class DefaultFillFormatter : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { val fillMin: Float val chartMaxY = dataProvider.yChartMax val chartMinY = dataProvider.yChartMin diff --git a/chartLib/src/main/kotlin/info/appdev/charting/formatter/IFillFormatter.kt b/chartLib/src/main/kotlin/info/appdev/charting/formatter/IFillFormatter.kt index cef5444c8e..a929003063 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/formatter/IFillFormatter.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/formatter/IFillFormatter.kt @@ -14,5 +14,5 @@ interface IFillFormatter { * @param dataSet the ILineDataSet that is currently drawn * @param dataProvider */ - fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float + fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt index adb3554159..e1465aa8cd 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/interfaces/datasets/ILineDataSet.kt @@ -1,11 +1,11 @@ package info.appdev.charting.interfaces.datasets import android.graphics.DashPathEffect -import info.appdev.charting.data.EntryFloat +import info.appdev.charting.data.BaseEntry import info.appdev.charting.data.LineDataSet import info.appdev.charting.formatter.IFillFormatter -interface ILineDataSet : ILineRadarDataSet { +interface ILineDataSet> : ILineRadarDataSet { /** * Returns the drawing mode for this line dataset */ diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt index dbadb870de..14a528102a 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/LineChartRenderer.kt @@ -7,10 +7,12 @@ import android.graphics.Color import android.graphics.Paint import android.graphics.Path import info.appdev.charting.animation.ChartAnimator +import info.appdev.charting.data.BaseEntry import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineDataSet import info.appdev.charting.highlight.Highlight import info.appdev.charting.interfaces.dataprovider.LineDataProvider +import info.appdev.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet import info.appdev.charting.interfaces.datasets.IDataSet import info.appdev.charting.interfaces.datasets.ILineDataSet import info.appdev.charting.utils.ColorTemplate @@ -85,7 +87,7 @@ open class LineChartRenderer( canvas.drawBitmap(drawBitmapLocal, 0f, 0f, null) } - protected fun drawDataSet(canvas: Canvas, dataSet: ILineDataSet) { + protected fun drawDataSet(canvas: Canvas, dataSet: ILineDataSet<*>) { if (dataSet.entryCount < 1) return @@ -102,7 +104,7 @@ open class LineChartRenderer( paintRender.pathEffect = null } - protected fun drawHorizontalBezier(dataSet: ILineDataSet) { + protected fun drawHorizontalBezier(dataSet: ILineDataSet<*>) { val phaseY = animator.phaseY val trans = dataProvider.getTransformer(dataSet.axisDependency) @@ -152,7 +154,7 @@ open class LineChartRenderer( paintRender.pathEffect = null } - protected fun drawCubicBezier(dataSet: ILineDataSet) { + protected fun drawCubicBezier(dataSet: ILineDataSet<*>) { val phaseY = animator.phaseY val trans = dataProvider.getTransformer(dataSet.axisDependency) @@ -175,7 +177,7 @@ open class LineChartRenderer( // And in the `lastIndex`, add +1 val firstIndex = xBounds.min + 1 - var prevPrev: EntryFloat? + var prevPrev: BaseEntry? var prev = dataSet.getEntryForIndex(max((firstIndex - 2).toDouble(), 0.0).toInt()) var cur = dataSet.getEntryForIndex(max((firstIndex - 1).toDouble(), 0.0).toInt()) var next = cur @@ -227,7 +229,7 @@ open class LineChartRenderer( paintRender.pathEffect = null } - protected fun drawCubicFill(canvas: Canvas, dataSet: ILineDataSet, spline: Path, trans: Transformer, bounds: XBounds) { + protected fun drawCubicFill(canvas: Canvas, dataSet: ILineDataSet<*>, spline: Path, trans: Transformer, bounds: XBounds) { val fillMin = dataSet.fillFormatter!!.getFillLinePosition(dataSet, dataProvider) dataSet.getEntryForIndex(bounds.min + bounds.range)?.let { @@ -251,7 +253,7 @@ open class LineChartRenderer( /** * Draws a normal line. */ - protected fun drawLinear(c: Canvas, dataSet: ILineDataSet) { + protected fun drawLinear(c: Canvas, dataSet: ILineDataSet<*>) { val entryCount = dataSet.entryCount val pointsPerEntryPair = if (dataSet.isDrawSteppedEnabled) 4 else 2 @@ -286,7 +288,7 @@ open class LineChartRenderer( val max = xBounds.min + xBounds.range for (j in xBounds.min.. = dataSet.getEntryForIndex(j) ?: continue lineBuffer[0] = entryFloat.x lineBuffer[1] = entryFloat.y * phaseY @@ -346,8 +348,8 @@ open class LineChartRenderer( (max(((entryCount) * pointsPerEntryPair).toDouble(), pointsPerEntryPair.toDouble()) * 4).toInt() ) - var e1: EntryFloat? - var e2: EntryFloat? + var e1: BaseEntry? + var e2: BaseEntry? e1 = dataSet.getEntryForIndex(xBounds.min) @@ -393,7 +395,7 @@ open class LineChartRenderer( /** * Draws a filled linear path on the canvas. */ - protected fun drawLinearFill(canvas: Canvas, dataSet: ILineDataSet, trans: Transformer, bounds: XBounds) { + protected fun drawLinearFill(canvas: Canvas, dataSet: ILineDataSet<*>, trans: Transformer, bounds: XBounds) { val filled = mGenerateFilledPathBuffer val startingIndex = bounds.min @@ -435,7 +437,7 @@ open class LineChartRenderer( * @param endIndex The index from which to stop reading the dataset * @param outputPath The path object that will be assigned the chart data. */ - private fun generateFilledPath(dataSet: ILineDataSet, startIndex: Int, endIndex: Int, outputPath: Path) { + private fun generateFilledPath(dataSet: ILineDataSet<*>, startIndex: Int, endIndex: Int, outputPath: Path) { val fillMin = dataSet.fillFormatter!!.getFillLinePosition(dataSet, dataProvider) val phaseY = animator.phaseY val isDrawSteppedEnabled = dataSet.lineMode == LineDataSet.Mode.STEPPED @@ -448,7 +450,7 @@ open class LineChartRenderer( outputPath.lineTo(entry.x, entry.y * phaseY) // create a new path - var currentEntryFloat: EntryFloat? = null + var currentEntryFloat: BaseEntry? = null var previousEntry = entry for (x in startIndex + 1..endIndex) { currentEntryFloat = dataSet.getEntryForIndex(x) @@ -650,7 +652,8 @@ open class LineChartRenderer( set.getEntryForXValue(high.x, high.y)?.let { entry -> - if (!isInBoundsX(entry, set)) + @Suppress("UNCHECKED_CAST") + if (!isInBoundsX(entry, set as IBarLineScatterCandleBubbleDataSet>)) continue val pix = dataProvider.getTransformer(set.axisDependency)!!.getPixelForValues( @@ -686,7 +689,7 @@ open class LineChartRenderer( /** * Sets up the cache, returns true if a change of cache was required. */ - fun init(set: ILineDataSet): Boolean { + fun init(set: ILineDataSet<*>): Boolean { val size = set.circleColorCount var changeRequired = false @@ -708,7 +711,7 @@ open class LineChartRenderer( * @param drawCircleHole * @param drawTransparentCircleHole */ - fun fill(set: ILineDataSet, drawCircleHole: Boolean, drawTransparentCircleHole: Boolean) { + fun fill(set: ILineDataSet<*>, drawCircleHole: Boolean, drawTransparentCircleHole: Boolean) { val colorCount = set.circleColorCount val circleRadius = set.circleRadius val circleHoleRadius = set.circleHoleRadius diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt index 0836d38570..e26be48d73 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/Transformer.kt @@ -142,7 +142,7 @@ open class Transformer(protected var viewPortHandler: ViewPortHandler) { * y values transformed with all matrices for the LINECHART. */ fun generateTransformedValuesLine( - data: ILineDataSet, + data: ILineDataSet<*>, phaseX: Float, phaseY: Float, min: Int, max: Int ): FloatArray { From ae2debc405aa6e03d8a4a397e70f3e9c8db438d1 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 18:45:19 +0200 Subject: [PATCH 7/9] BarEntry with high precision --- .../appdev/charting/data/BarEntryDouble.kt | 146 ++++++++++++++++++ .../appdev/charting/highlight/RangeDouble.kt | 12 ++ 2 files changed, 158 insertions(+) create mode 100644 chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryDouble.kt create mode 100644 chartLib/src/main/kotlin/info/appdev/charting/highlight/RangeDouble.kt diff --git a/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryDouble.kt b/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryDouble.kt new file mode 100644 index 0000000000..6560d5d26d --- /dev/null +++ b/chartLib/src/main/kotlin/info/appdev/charting/data/BarEntryDouble.kt @@ -0,0 +1,146 @@ +package info.appdev.charting.data + +import android.graphics.drawable.Drawable +import info.appdev.charting.highlight.RangeDouble +import kotlin.math.abs + +/** + * High-precision bar entry that stores x and y as Double, extending [BarEntryFloat] + * so it works seamlessly in the existing bar chart rendering pipeline. + * Use [xDouble] and [yDouble] for full-precision access. + * For stacked bars use [yValsDouble] and [rangesDouble]. + */ +open class BarEntryDouble : BarEntryFloat { + + var xDouble: Double = 0.0 + var yDouble: Double = 0.0 + + override var x: Float + get() = xDouble.toFloat() + set(value) { xDouble = value.toDouble() } + + /** + * Returns the double-precision stacked values, or null for simple bars. + */ + var yValsDouble: DoubleArray? = null + private set + + /** + * Double-precision ranges for stacked bars. + */ + var rangesDouble: Array = arrayOf() + private set + + var negativeDoubleSum: Double = 0.0 + private set + + var positiveDoubleSum: Double = 0.0 + private set + + // ── Simple bar constructors ────────────────────────────────────────────── + + constructor(x: Double, y: Double) : super(x.toFloat(), y.toFloat()) { + xDouble = x; yDouble = y + } + + constructor(x: Double, y: Double, data: Any?) : super(x.toFloat(), y.toFloat(), data) { + xDouble = x; yDouble = y + } + + constructor(x: Double, y: Double, icon: Drawable?) : super(x.toFloat(), y.toFloat(), icon) { + xDouble = x; yDouble = y + } + + constructor(x: Double, y: Double, icon: Drawable?, data: Any?) : super(x.toFloat(), y.toFloat(), icon, data) { + xDouble = x; yDouble = y + } + + // ── Stacked bar constructors ───────────────────────────────────────────── + + constructor(x: Double, vals: DoubleArray?) : super(x.toFloat(), calcDoubleSum(vals).toFloat()) { + xDouble = x + yDouble = calcDoubleSum(vals) + yValsDouble = vals + calcDoublePosNegSum() + calcDoubleRanges() + } + + constructor(x: Double, vals: DoubleArray?, data: Any?) : super(x.toFloat(), calcDoubleSum(vals).toFloat(), data) { + xDouble = x + yDouble = calcDoubleSum(vals) + yValsDouble = vals + calcDoublePosNegSum() + calcDoubleRanges() + } + + constructor(x: Double, vals: DoubleArray?, icon: Drawable?) : super(x.toFloat(), calcDoubleSum(vals).toFloat(), icon) { + xDouble = x + yDouble = calcDoubleSum(vals) + yValsDouble = vals + calcDoublePosNegSum() + calcDoubleRanges() + } + + // ── y override (always reflects yDouble) ──────────────────────────────── + + override var y: Float + get() = yDouble.toFloat() + set(value) { yDouble = value.toDouble() } + + // ── Stack helpers ──────────────────────────────────────────────────────── + + val isStackedDouble: Boolean get() = yValsDouble != null + + fun setValsDouble(vals: DoubleArray?) { + yDouble = calcDoubleSum(vals) + yValsDouble = vals + calcDoublePosNegSum() + calcDoubleRanges() + } + + fun getSumBelowDouble(stackIndex: Int): Double { + val vals = yValsDouble ?: return 0.0 + var remainder = 0.0 + var index = vals.size - 1 + while (index > stackIndex && index >= 0) { + remainder += vals[index] + index-- + } + return remainder + } + + private fun calcDoublePosNegSum() { + val vals = yValsDouble + if (vals == null) { negativeDoubleSum = 0.0; positiveDoubleSum = 0.0; return } + var sumNeg = 0.0; var sumPos = 0.0 + for (v in vals) { if (v <= 0.0) sumNeg += abs(v) else sumPos += v } + negativeDoubleSum = sumNeg; positiveDoubleSum = sumPos + } + + private fun calcDoubleRanges() { + val values = yValsDouble + if (values == null || values.isEmpty()) return + + rangesDouble = Array(values.size) { RangeDouble(0.0, 0.0) } + var negRemain = -negativeDoubleSum + var posRemain = 0.0 + + for (i in values.indices) { + val value = values[i] + if (value < 0) { + rangesDouble[i] = RangeDouble(negRemain, negRemain - value) + negRemain -= value + } else { + rangesDouble[i] = RangeDouble(posRemain, posRemain + value) + posRemain += value + } + } + } + + override fun toString(): String = "BarEntryDouble xDouble=$xDouble yDouble=$yDouble yValsDouble=${yValsDouble?.contentToString()}" + + companion object { + private fun calcDoubleSum(vals: DoubleArray?): Double = vals?.sum() ?: 0.0 + } +} + diff --git a/chartLib/src/main/kotlin/info/appdev/charting/highlight/RangeDouble.kt b/chartLib/src/main/kotlin/info/appdev/charting/highlight/RangeDouble.kt new file mode 100644 index 0000000000..cfaae498d6 --- /dev/null +++ b/chartLib/src/main/kotlin/info/appdev/charting/highlight/RangeDouble.kt @@ -0,0 +1,12 @@ +package info.appdev.charting.highlight + +/** + * Double-precision equivalent of [Range] for use with [info.appdev.charting.data.BarEntryDouble] + * stacked entries. e.g. stack values are -10.0, 5.0, 20.0 -> ranges are (-10 to 0, 0 to 5, 5 to 25). + */ +class RangeDouble(var from: Double, var to: Double) { + fun contains(value: Double): Boolean = value > from && value <= to + fun isLarger(value: Double): Boolean = value > to + fun isSmaller(value: Double): Boolean = value < from +} + From 95f37766ce3ba53dc7f0650b3b369ef100a5dbd6 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 18:45:57 +0200 Subject: [PATCH 8/9] HorizontalBarChartActivity with high precision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The problem is invariant generics. BarDataSet is DataSet, so entries expects MutableList. Even though BarEntryDouble : BarEntryFloat, MutableList is not a MutableList because MutableList is invariant (it's both a producer and consumer). MutableList is invariant in T because it both reads (get() → T) and writes (add(T)). Even though BarEntryDouble : BarEntryFloat, the compiler must reject the assignment to prevent this kind of unsound write: val list: MutableList = values // if allowed... list.add(BarEntryFloat(1f, 2f)) // would corrupt the original BarEntryDouble list! The @Suppress("UNCHECKED_CAST") cast is safe here because: * JVM erases generics at runtime — both are just MutableList on the heap * BarDataSet only reads entries from the list as BarEntryFloat, and BarEntryDouble IS a BarEntryFloat * Nothing writes a plain BarEntryFloat back into the list through BarDataSet --- .../HorizontalBarChartActivity.kt | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/info/appdev/chartexample/HorizontalBarChartActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/HorizontalBarChartActivity.kt index c87b4f068a..9340c22ee4 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/HorizontalBarChartActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/HorizontalBarChartActivity.kt @@ -19,6 +19,7 @@ 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.data.EntryFloat import info.appdev.charting.highlight.Highlight @@ -96,14 +97,14 @@ class HorizontalBarChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartV private fun setData(count: Int, range: Float) { val barWidth = 9f val spaceForBar = 10f - val values = ArrayList() + val values = ArrayList() val sampleValues = getValues(100) for (i in 0.. 0 ) { set1 = binding.chart1.barData!!.getDataSetByIndex(0) as BarDataSet - set1.entries = values + @Suppress("UNCHECKED_CAST") + set1.entries = values as MutableList binding.chart1.barData?.notifyDataChanged() binding.chart1.notifyDataSetChanged() } else { - set1 = BarDataSet(values, "DataSet 1") + @Suppress("UNCHECKED_CAST") + set1 = BarDataSet(values as MutableList, "DataSet 1") set1.isDrawIcons = false @@ -230,8 +237,9 @@ class HorizontalBarChartActivity : DemoBase(), OnSeekBarChangeListener, OnChartV private val mOnValueSelectedRectF = RectF() override fun onValueSelected(entryFloat: EntryFloat, highlight: Highlight) { + val barEntry = entryFloat as BarEntryDouble val bounds = mOnValueSelectedRectF - binding.chart1.getBarBounds(entryFloat as BarEntryFloat, bounds) + binding.chart1.getBarBounds(barEntry, bounds) val position = binding.chart1.getPosition( entryFloat, binding.chart1.barData!!.getDataSetByIndex(highlight.dataSetIndex)?.axisDependency From c3470d68654f5daeb3c3e5f43857ae3f43074dcd Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Sun, 29 Mar 2026 13:50:42 +0200 Subject: [PATCH 9/9] TimeLineActivity with high precision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The problem is invariant generics. LineDataSet is LineDataSet, so entries expects MutableList. Even though EntryDouble : EntryFloat, MutableList is not a MutableList because MutableList is invariant (it's both a producer and consumer). MutableList is invariant in T because it both reads (get() → T) and writes (add(T)). Even though EntryDouble : EntryFloat, the compiler must reject the assignment to prevent this kind of unsound write: val list: MutableList = values // if allowed... list.add(EntryFloat(1f, 2f)) // would corrupt the original EntryDouble list! The @Suppress("UNCHECKED_CAST") cast is safe here because: * JVM erases generics at runtime — both are just MutableList on the heap * LineDataSet only reads entries from the list as EntryFloat, and EntryDouble IS a EntryFloat * Nothing writes a plain EntryFloat back into the list through DataSet --- .../appdev/chartexample/TimeLineActivity.kt | 42 +++++++++++------- ...TimeLineActivity-Timeline-1SampleClick.png | Bin 19818 -> 19373 bytes 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt b/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt index 096c308e71..9e29813ef6 100644 --- a/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt +++ b/app/src/main/kotlin/info/appdev/chartexample/TimeLineActivity.kt @@ -17,6 +17,7 @@ import info.appdev.charting.components.Description import info.appdev.charting.components.Legend.LegendForm import info.appdev.charting.components.XAxis.XAxisPosition import info.appdev.charting.components.YAxis +import info.appdev.charting.data.EntryDouble import info.appdev.charting.data.EntryFloat import info.appdev.charting.data.LineData import info.appdev.charting.data.LineDataSet @@ -96,23 +97,23 @@ class TimeLineActivity : DemoBase() { val sampleEntries = if (sinus) generateSineWaves(3, 30).mapIndexed { index, data -> - val valueY = (data.toFloat() * range) + 50 - EntryFloat(timeOffset + index.toFloat() * 1000, valueY) + val valueY = (data * range) + 50 + EntryDouble(timeOffset + index * 1000.0, valueY) } else { - var previousEntryFloat: EntryFloat? = null + var previousEntryDouble: EntryDouble? = null getSawtoothValues(14).mapIndexed { index, data -> - val valueY = data.toFloat() * 20 - val entryFloat = previousEntryFloat?.let { + val valueY = data * 20 + val entryFloat = previousEntryDouble?.let { // nay third value is 0, so we add here more than 1 second, otherwise we have a one-second entry if (index % 3 == 0) { - EntryFloat(it.x + 3000, valueY) + EntryDouble(it.xDouble + 3000.0, valueY) } else - EntryFloat(it.x + 1000, valueY) + EntryDouble(it.xDouble + 1000.0, valueY) } ?: run { - EntryFloat(timeOffset + index.toFloat() * 1000, valueY) + EntryDouble(timeOffset + index.toFloat() * 1000.0, valueY) } - previousEntryFloat = entryFloat + previousEntryDouble = entryFloat // Now you can use 'prev' which holds the previous Entry entryFloat } @@ -120,14 +121,19 @@ class TimeLineActivity : DemoBase() { 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}" + val entryText = "Entry: x=${simpleDateFormat.format(entry.xDouble.toLong())} xDouble=${entry.xDouble}, y=${entry.y}" Timber.d(entryText) } - val set1: LineDataSet + val set1: LineDataSet + /*The @Suppress("UNCHECKED_CAST") cast is safe here because: + * JVM erases generics at runtime — both are just MutableList on the heap + * LineDataSet only reads entries from the list as EntryFloat, and EntryDouble IS a EntryFloat + * Nothing writes a plain EntryFloat back into the list through LineDataSet*/ if (binding.chart1.lineData.dataSetCount > 0) { - set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet + @Suppress("UNCHECKED_CAST") + set1 = binding.chart1.lineData.getDataSetByIndex(0) as LineDataSet set1.entries = sampleEntries.toMutableList() if (sinus) set1.lineMode = LineDataSet.Mode.LINEAR @@ -153,15 +159,17 @@ class TimeLineActivity : DemoBase() { set1.highLightColor = Color.rgb(244, 117, 117) set1.isDrawCircleHoleEnabled = false set1.fillFormatter = object : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider): Float { + override fun getFillLinePosition(dataSet: ILineDataSet<*>?, dataProvider: LineDataProvider): Float { // change the return value here to better understand the effect // return 0; return binding.chart1.axisLeft.axisMinimum } } - val dataSets = ArrayList() - dataSets.add(set1) // add the data sets + @Suppress("UNCHECKED_CAST") + val dataSets = ArrayList>() + @Suppress("UNCHECKED_CAST") + dataSets.add(set1 as ILineDataSet) // add the data sets // create a data object with the data sets val data = LineData(dataSets) @@ -209,9 +217,9 @@ class TimeLineActivity : DemoBase() { val first = this[0] val second = this[1] // needed to get time diff val last = this[size - 1] - val timeDiff = (second as EntryFloat).x - (first as EntryFloat).x + val timeDiff = (second as EntryDouble).xDouble - (first as EntryDouble).xDouble removeAt(0) - first.x = (last as EntryFloat).x + timeDiff + (first as EntryDouble).xDouble = (last as EntryDouble).xDouble + timeDiff add(first) } diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-45-TimeLineActivity-Timeline-1SampleClick.png b/screenshotsToCompare9/StartTest_smokeTestStart-45-TimeLineActivity-Timeline-1SampleClick.png index b291c3f2fac90168ce95725dd2cac4cb623c6322..95aa7ac05e3290fd09a4811b45ffbea7fbb524c0 100644 GIT binary patch literal 19373 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

Y3X^YngOf2eB9gnkPo&_tiIe2XzE&wvd5v6KUP z^cp60`qc||O~$>>|LIx3e^H}~lz6vA^r~YRpSW&N$-p4P53KrAxt-}6u3cB1a>GAB zn>x17?-+RU7jA~88gWx8^7>Wof4tL7^Wnhwa$RQ|(C&>UJ!S!@tRYV3Xe!%sQt_Q- zbNL2mE>45T#>Az-=egrk{W9+MzY_*Nlg)G8V22R@eNa2I#`o3IX}<0Kt6z04Q>NiK zZ4Rb|)lls+{qF7A=4%z2rp`H5ZEsmvZGS2m1m=6H+L9=o(G{QNY&87HuPx<6ZO%aX zsx?13KPr^K{K4rDO}Wl2Z*m{_F4iIg4a}+X9rk@%~l80Yj*q!P{&GPMbD0$#?fFo>7w4scF^z$nH?3h0~DLF20sIBu_tjh$U?QBef2liv6o zpvOON7FPVk->A6@N{C&S;-qWbe||N5zFtz%1k5QD8_SB9tv>^R3dgY%m_gKF~F&~0)r!noOfsJY$%6Ou2JEBxR5 za%_$PCpX;9umtD81joiC|MF691G*Jxh8inN7Mqm+Z(D#Z#T>Kf&;Q?pLZRTHQ{BJM z^FJTtubTiW-gF{2u_XKW{=a8df6hCr&VS~tC07Ohyb9l66dfH6N*&kZs?Y8PmbFgO z>vsURnB3)+Hrui8^{(@Fzt{X;n_qkS?$+$^lvH4uj9< zc2{$~bbH{p#x&2vzy6oS>fhrQ*DLw_vnFG{X|(7bz5AE#X#U=>*AAR6yL<5cZ-KCz z&8i1CoO<`>O$jg)x^3UP_iin4v7*!7>#e=>i?8!OpJxPIU^D&9eEa+LGSB|90}DvK z*se`)CIMSDn}A0dfeJ~`!9`m#FEi;&f7}1wc}8kHaP^%HFxO3-Vhe2D?zi5NcXwC7 z`_jb6&t(qnT<){R%vpj{`hD$%ix&?9o4kxWfCr~k05`q-xY%EJgqh#wz|8b{Gf!;- z_9>)a{x`qzGtxWz=1gEs_iUEnHC-`a@#O++0Y5(0`xsctCqF$kHKz1x=)yYO+4+^J=K0oHs*ZT zCVC5aECFzB=%KpXS}Wf?xcMv6JNf2H&jux>sa|I#7Ib(lCFcMsGP_{E{xkAb=2flQ T+#Lu!e~ZD>)z4*}Q$iB}XRY4v literal 19818 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