From 6a7500e5a902b8cb6b49d4da7133f920270506ec Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Tue, 2 Dec 2025 07:24:25 +0100 Subject: [PATCH 1/4] Kotlin items --- .../ListViewMultiChartActivity.kt | 6 +- .../listviewitems/BarChartItem.java | 92 --------------- .../listviewitems/BarChartItem.kt | 77 +++++++++++++ .../chartexample/listviewitems/ChartItem.java | 29 ----- .../chartexample/listviewitems/ChartItem.kt | 21 ++++ .../listviewitems/LineChartItem.java | 89 --------------- .../listviewitems/LineChartItem.kt | 73 ++++++++++++ .../listviewitems/PieChartItem.java | 106 ------------------ .../listviewitems/PieChartItem.kt | 96 ++++++++++++++++ .../chartexample/notimportant/MenuAdapter.kt | 2 +- 10 files changed, 271 insertions(+), 320 deletions(-) delete mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.java create mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.java create mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.java create mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.java create mode 100644 app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.kt diff --git a/app/src/main/java/info/appdev/chartexample/ListViewMultiChartActivity.kt b/app/src/main/java/info/appdev/chartexample/ListViewMultiChartActivity.kt index e7460e2f5b..270a5877ce 100644 --- a/app/src/main/java/info/appdev/chartexample/ListViewMultiChartActivity.kt +++ b/app/src/main/java/info/appdev/chartexample/ListViewMultiChartActivity.kt @@ -65,15 +65,15 @@ class ListViewMultiChartActivity : DemoBase() { } /** adapter that supports 3 different item types */ - private class ChartDataAdapter(context: Context, objects: MutableList) : ArrayAdapter(context, 0, objects) { + private class ChartDataAdapter(context: Context, objects: MutableList) : ArrayAdapter(context, 0, objects) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - return getItem(position)!!.getView(position, convertView, context) + return getItem(position)!!.getView(position, convertView, context)!! } override fun getItemViewType(position: Int): Int { // return the views type val ci = getItem(position) - return if (ci != null) ci.getItemType() else 0 + return if (ci != null) ci.itemType else 0 } override fun getViewTypeCount(): Int { diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.java b/app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.java deleted file mode 100644 index 20e34da0f4..0000000000 --- a/app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.java +++ /dev/null @@ -1,92 +0,0 @@ -package info.appdev.chartexample.listviewitems; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Typeface; -import android.view.LayoutInflater; -import android.view.View; - -import com.github.mikephil.charting.charts.BarChart; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.XAxis.XAxisPosition; -import com.github.mikephil.charting.components.YAxis; -import com.github.mikephil.charting.data.BarData; -import com.github.mikephil.charting.data.ChartData; - -import info.appdev.chartexample.R; - -public class BarChartItem extends ChartItem { - - private final Typeface mTf; - - public BarChartItem(ChartData cd, Context c) { - super(cd); - - mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf"); - } - - @Override - public int getItemType() { - return TYPE_BARCHART; - } - - @SuppressLint("InflateParams") - @Override - public View getView(int position, View convertView, Context c) { - - ViewHolder holder; - - if (convertView == null) { - - holder = new ViewHolder(); - - convertView = LayoutInflater.from(c).inflate( - R.layout.list_item_barchart, null); - holder.chart = convertView.findViewById(R.id.chart); - - convertView.setTag(holder); - - } else { - holder = (ViewHolder) convertView.getTag(); - } - - // apply styling - holder.chart.getDescription().setEnabled(false); - holder.chart.setDrawGridBackground(false); - holder.chart.setDrawBarShadow(false); - - XAxis xAxis = holder.chart.getXAxis(); - xAxis.setPosition(XAxisPosition.BOTTOM); - xAxis.setTypeface(mTf); - xAxis.setDrawGridLines(false); - xAxis.setDrawAxisLine(true); - - YAxis leftAxis = holder.chart.getAxisLeft(); - leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(5, false); - leftAxis.setSpaceTop(20f); - leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) - - YAxis rightAxis = holder.chart.getAxisRight(); - rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(5, false); - rightAxis.setSpaceTop(20f); - rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) - - mChartData.setValueTypeface(mTf); - - // set data - holder.chart.setData((BarData) mChartData); - holder.chart.setFitBars(true); - - // do not forget to refresh the chart -// holder.chart.invalidate(); - holder.chart.animateY(700); - - return convertView; - } - - private static class ViewHolder { - BarChart chart; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.kt b/app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.kt new file mode 100644 index 0000000000..675b033365 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/listviewitems/BarChartItem.kt @@ -0,0 +1,77 @@ +package info.appdev.chartexample.listviewitems + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Typeface +import android.view.LayoutInflater +import android.view.View +import com.github.mikephil.charting.charts.BarChart +import com.github.mikephil.charting.components.XAxis.XAxisPosition +import com.github.mikephil.charting.data.BarData +import com.github.mikephil.charting.data.ChartData +import info.appdev.chartexample.R + +class BarChartItem(cd: ChartData<*>, c: Context) : ChartItem(cd) { + private val typeface: Typeface? = Typeface.createFromAsset(c.assets, "OpenSans-Regular.ttf") + + override val itemType: Int + get() = TYPE_BARCHART + + @SuppressLint("InflateParams") + override fun getView(position: Int, convertView: View?, c: Context?): View? { + var convertView = convertView + val holder: ViewHolder + + if (convertView == null) { + holder = ViewHolder() + + convertView = LayoutInflater.from(c).inflate( + R.layout.list_item_barchart, null + ) + holder.chart = convertView.findViewById(R.id.chart) + + convertView.tag = holder + } else { + holder = convertView.tag as ViewHolder + } + + // apply styling + holder.chart!!.description.isEnabled = false + holder.chart!!.setDrawGridBackground(false) + holder.chart!!.setDrawBarShadow(false) + + val xAxis = holder.chart!!.xAxis + xAxis.position = XAxisPosition.BOTTOM + xAxis.typeface = typeface + xAxis.setDrawGridLines(false) + xAxis.setDrawAxisLine(true) + + val leftAxis = holder.chart!!.axisLeft + leftAxis.typeface = typeface + leftAxis.setLabelCount(5, false) + leftAxis.spaceTop = 20f + leftAxis.setAxisMinimum(0f) // this replaces setStartAtZero(true) + + val rightAxis = holder.chart!!.axisRight + rightAxis.typeface = typeface + rightAxis.setLabelCount(5, false) + rightAxis.spaceTop = 20f + rightAxis.setAxisMinimum(0f) // this replaces setStartAtZero(true) + + chartData.setValueTypeface(typeface) + + // set data + holder.chart!!.setData(chartData as BarData?) + holder.chart!!.setFitBars(true) + + // do not forget to refresh the chart +// holder.chart.invalidate(); + holder.chart!!.animateY(700) + + return convertView + } + + private class ViewHolder { + var chart: BarChart? = null + } +} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.java b/app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.java deleted file mode 100644 index eb5300c2ae..0000000000 --- a/app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.java +++ /dev/null @@ -1,29 +0,0 @@ -package info.appdev.chartexample.listviewitems; - -import android.content.Context; -import android.view.View; - -import com.github.mikephil.charting.data.ChartData; - -/** - * Base class of the Chart ListView items - * @author philipp - * - */ -@SuppressWarnings("unused") -public abstract class ChartItem { - - static final int TYPE_BARCHART = 0; - static final int TYPE_LINECHART = 1; - static final int TYPE_PIECHART = 2; - - ChartData mChartData; - - ChartItem(ChartData cd) { - this.mChartData = cd; - } - - public abstract int getItemType(); - - public abstract View getView(int position, View convertView, Context c); -} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.kt b/app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.kt new file mode 100644 index 0000000000..431814adc8 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/listviewitems/ChartItem.kt @@ -0,0 +1,21 @@ +package info.appdev.chartexample.listviewitems + +import android.content.Context +import android.view.View +import com.github.mikephil.charting.data.ChartData + +/** + * Base class of the Chart ListView items + */ +@Suppress("unused") +abstract class ChartItem internal constructor(@JvmField var chartData: ChartData<*>) { + abstract val itemType: Int + + abstract fun getView(position: Int, convertView: View?, c: Context?): View? + + companion object { + const val TYPE_BARCHART: Int = 0 + const val TYPE_LINECHART: Int = 1 + const val TYPE_PIECHART: Int = 2 + } +} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.java b/app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.java deleted file mode 100644 index 7d95061314..0000000000 --- a/app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.java +++ /dev/null @@ -1,89 +0,0 @@ - -package info.appdev.chartexample.listviewitems; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Typeface; -import android.view.LayoutInflater; -import android.view.View; - -import com.github.mikephil.charting.charts.LineChart; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.XAxis.XAxisPosition; -import com.github.mikephil.charting.components.YAxis; -import com.github.mikephil.charting.data.ChartData; -import com.github.mikephil.charting.data.LineData; - -import info.appdev.chartexample.R; - -public class LineChartItem extends ChartItem { - - private final Typeface mTf; - - public LineChartItem(ChartData cd, Context c) { - super(cd); - - mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf"); - } - - @Override - public int getItemType() { - return TYPE_LINECHART; - } - - @SuppressLint("InflateParams") - @Override - public View getView(int position, View convertView, Context c) { - - ViewHolder holder; - - if (convertView == null) { - - holder = new ViewHolder(); - - convertView = LayoutInflater.from(c).inflate( - R.layout.list_item_linechart, null); - holder.chart = convertView.findViewById(R.id.chart); - - convertView.setTag(holder); - - } else { - holder = (ViewHolder) convertView.getTag(); - } - - // apply styling - // holder.chart.setValueTypeface(mTf); - holder.chart.getDescription().setEnabled(false); - holder.chart.setDrawGridBackground(false); - - XAxis xAxis = holder.chart.getXAxis(); - xAxis.setPosition(XAxisPosition.BOTTOM); - xAxis.setTypeface(mTf); - xAxis.setDrawGridLines(false); - xAxis.setDrawAxisLine(true); - - YAxis leftAxis = holder.chart.getAxisLeft(); - leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(5, false); - leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) - - YAxis rightAxis = holder.chart.getAxisRight(); - rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(5, false); - rightAxis.setDrawGridLines(false); - rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) - - // set data - holder.chart.setData((LineData) mChartData); - - // do not forget to refresh the chart - // holder.chart.invalidate(); - holder.chart.animateX(750); - - return convertView; - } - - private static class ViewHolder { - LineChart chart; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.kt b/app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.kt new file mode 100644 index 0000000000..2ed37997e2 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/listviewitems/LineChartItem.kt @@ -0,0 +1,73 @@ +package info.appdev.chartexample.listviewitems + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Typeface +import android.view.LayoutInflater +import android.view.View +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.components.XAxis.XAxisPosition +import com.github.mikephil.charting.data.ChartData +import com.github.mikephil.charting.data.LineData +import info.appdev.chartexample.R + +class LineChartItem(cd: ChartData<*>, c: Context) : ChartItem(cd) { + private val typeface: Typeface? = Typeface.createFromAsset(c.assets, "OpenSans-Regular.ttf") + + override val itemType: Int + get() = TYPE_LINECHART + + @SuppressLint("InflateParams") + override fun getView(position: Int, convertView: View?, c: Context?): View { + var convertView = convertView + val holder: ViewHolder + + if (convertView == null) { + holder = ViewHolder() + + convertView = LayoutInflater.from(c).inflate( + R.layout.list_item_linechart, null + ) + holder.chart = convertView.findViewById(R.id.chart) + + convertView.tag = holder + } else { + holder = convertView.tag as ViewHolder + } + + // apply styling + // holder.chart.setValueTypeface(mTf); + holder.chart!!.description.isEnabled = false + holder.chart!!.setDrawGridBackground(false) + + val xAxis = holder.chart!!.xAxis + xAxis.position = XAxisPosition.BOTTOM + xAxis.typeface = typeface + xAxis.setDrawGridLines(false) + xAxis.setDrawAxisLine(true) + + val leftAxis = holder.chart!!.axisLeft + leftAxis.typeface = typeface + leftAxis.setLabelCount(5, false) + leftAxis.setAxisMinimum(0f) // this replaces setStartAtZero(true) + + val rightAxis = holder.chart!!.axisRight + rightAxis.typeface = typeface + rightAxis.setLabelCount(5, false) + rightAxis.setDrawGridLines(false) + rightAxis.setAxisMinimum(0f) // this replaces setStartAtZero(true) + + // set data + holder.chart!!.setData(chartData as LineData?) + + // do not forget to refresh the chart + // holder.chart.invalidate(); + holder.chart!!.animateX(750) + + return convertView + } + + private class ViewHolder { + var chart: LineChart? = null + } +} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.java b/app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.java deleted file mode 100644 index 8a8180c172..0000000000 --- a/app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.java +++ /dev/null @@ -1,106 +0,0 @@ - -package info.appdev.chartexample.listviewitems; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Color; -import android.graphics.Typeface; -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; -import android.text.style.RelativeSizeSpan; -import android.view.LayoutInflater; -import android.view.View; - -import com.github.mikephil.charting.charts.PieChart; -import com.github.mikephil.charting.components.Legend; -import com.github.mikephil.charting.data.ChartData; -import com.github.mikephil.charting.data.PieData; -import com.github.mikephil.charting.formatter.PercentFormatter; -import com.github.mikephil.charting.utils.ColorTemplate; - -import info.appdev.chartexample.R; - -public class PieChartItem extends ChartItem { - - private final Typeface mTf; - private final SpannableString mCenterText; - - public PieChartItem(ChartData cd, Context c) { - super(cd); - - mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf"); - mCenterText = generateCenterText(); - } - - @Override - public int getItemType() { - return TYPE_PIECHART; - } - - @SuppressLint("InflateParams") - @Override - public View getView(int position, View convertView, Context c) { - - ViewHolder holder; - - if (convertView == null) { - - holder = new ViewHolder(); - - convertView = LayoutInflater.from(c).inflate( - R.layout.list_item_piechart, null); - holder.chart = convertView.findViewById(R.id.chart); - - convertView.setTag(holder); - - } else { - holder = (ViewHolder) convertView.getTag(); - } - - // apply styling - holder.chart.getDescription().setEnabled(false); - holder.chart.setHoleRadius(52f); - holder.chart.setTransparentCircleRadius(57f); - holder.chart.setCenterText(mCenterText); - holder.chart.setCenterTextTypeface(mTf); - holder.chart.setCenterTextSize(9f); - holder.chart.setUsePercentValues(true); - holder.chart.setExtraOffsets(5, 10, 50, 10); - - mChartData.setValueFormatter(new PercentFormatter()); - mChartData.setValueTypeface(mTf); - mChartData.setValueTextSize(11f); - mChartData.setValueTextColor(Color.WHITE); - // set data - holder.chart.setData((PieData) mChartData); - - Legend l = holder.chart.getLegend(); - l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); - l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); - l.setOrientation(Legend.LegendOrientation.VERTICAL); - l.setDrawInside(false); - l.setYEntrySpace(0f); - l.setYOffset(0f); - - // do not forget to refresh the chart - // holder.chart.invalidate(); - holder.chart.animateY(900); - - return convertView; - } - - private SpannableString generateCenterText() { - SpannableString s = new SpannableString("MPAndroidChart\ncreated by\nPhilipp Jahoda"); - s.setSpan(new RelativeSizeSpan(1.6f), 0, 14, 0); - s.setSpan(new ForegroundColorSpan(ColorTemplate.VORDIPLOM_COLORS[0]), 0, 14, 0); - s.setSpan(new RelativeSizeSpan(.9f), 14, 25, 0); - s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, 25, 0); - s.setSpan(new RelativeSizeSpan(1.4f), 25, s.length(), 0); - s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), 25, s.length(), 0); - return s; - } - - private static class ViewHolder { - PieChart chart; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.kt b/app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.kt new file mode 100644 index 0000000000..767338c0a5 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/listviewitems/PieChartItem.kt @@ -0,0 +1,96 @@ +package info.appdev.chartexample.listviewitems + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Color +import android.graphics.Typeface +import android.text.SpannableString +import android.text.style.ForegroundColorSpan +import android.text.style.RelativeSizeSpan +import android.text.style.StyleSpan +import android.view.LayoutInflater +import android.view.View +import com.github.mikephil.charting.charts.PieChart +import com.github.mikephil.charting.components.Legend +import com.github.mikephil.charting.data.ChartData +import com.github.mikephil.charting.data.PieData +import com.github.mikephil.charting.formatter.PercentFormatter +import com.github.mikephil.charting.utils.ColorTemplate +import info.appdev.chartexample.R + +class PieChartItem(cd: ChartData<*>, c: Context) : ChartItem(cd) { + private val typeface: Typeface? = Typeface.createFromAsset(c.assets, "OpenSans-Regular.ttf") + private val centerText: SpannableString + + init { + centerText = generateCenterSpannableText() + } + + override val itemType: Int + get() = TYPE_PIECHART + + @SuppressLint("InflateParams") + override fun getView(position: Int, convertView: View?, c: Context?): View { + var convertView = convertView + val holder: ViewHolder + + if (convertView == null) { + holder = ViewHolder() + + convertView = LayoutInflater.from(c).inflate( + R.layout.list_item_piechart, null + ) + holder.chart = convertView.findViewById(R.id.chart) + + convertView.tag = holder + } else { + holder = convertView.tag as ViewHolder + } + + // apply styling + holder.chart!!.description.isEnabled = false + holder.chart!!.holeRadius = 52f + holder.chart!!.transparentCircleRadius = 57f + holder.chart!!.centerText = centerText + holder.chart!!.setCenterTextTypeface(typeface) + holder.chart!!.setCenterTextSize(9f) + holder.chart!!.setUsePercentValues(true) + holder.chart!!.setExtraOffsets(5f, 10f, 50f, 10f) + + chartData.setValueFormatter(PercentFormatter()) + chartData.setValueTypeface(typeface) + chartData.setValueTextSize(11f) + chartData.setValueTextColor(Color.WHITE) + // set data + holder.chart!!.setData(chartData as PieData?) + + val l = holder.chart!!.legend + l.verticalAlignment = Legend.LegendVerticalAlignment.TOP + l.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT + l.orientation = Legend.LegendOrientation.VERTICAL + l.setDrawInside(false) + l.yEntrySpace = 0f + l.yOffset = 0f + + // do not forget to refresh the chart + // holder.chart.invalidate(); + holder.chart!!.animateY(900) + + return convertView + } + + private fun generateCenterSpannableText(): SpannableString { + val s = SpannableString("AndroidChart\ndeveloped by AppDevNext") + s.setSpan(RelativeSizeSpan(1.7f), 0, 14, 0) + s.setSpan(StyleSpan(Typeface.NORMAL), 14, s.length - 15, 0) + s.setSpan(ForegroundColorSpan(Color.GRAY), 14, s.length - 15, 0) + s.setSpan(RelativeSizeSpan(.8f), 14, s.length - 15, 0) + s.setSpan(StyleSpan(Typeface.ITALIC), s.length - 14, s.length, 0) + s.setSpan(ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length - 14, s.length, 0) + return s + } + + private class ViewHolder { + var chart: PieChart? = null + } +} diff --git a/app/src/main/java/info/appdev/chartexample/notimportant/MenuAdapter.kt b/app/src/main/java/info/appdev/chartexample/notimportant/MenuAdapter.kt index 256da36206..929bd5496c 100644 --- a/app/src/main/java/info/appdev/chartexample/notimportant/MenuAdapter.kt +++ b/app/src/main/java/info/appdev/chartexample/notimportant/MenuAdapter.kt @@ -43,7 +43,7 @@ internal class MenuAdapter(context: Context, objects: List?>?) : return inflatedView } - private inner class ViewHolder { + private class ViewHolder { var tvName: TextView? = null var tvDesc: TextView? = null } From ddee945f1b75693e333983e0ecd48db30649bdce Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Tue, 2 Dec 2025 07:28:34 +0100 Subject: [PATCH 2/4] Kotlin fragments --- .../chartexample/fragments/BarChartFrag.java | 113 ---------- .../chartexample/fragments/BarChartFrag.kt | 97 +++++++++ .../fragments/ComplexityFragment.java | 56 ----- .../fragments/ComplexityFragment.kt | 48 +++++ .../chartexample/fragments/PieChartFrag.java | 65 ------ .../chartexample/fragments/PieChartFrag.kt | 60 ++++++ .../fragments/ScatterChartFrag.java | 70 ------- .../fragments/ScatterChartFrag.kt | 61 ++++++ .../fragments/SimpleFragment.java | 194 ------------------ .../chartexample/fragments/SimpleFragment.kt | 183 +++++++++++++++++ .../fragments/SineCosineFragment.java | 58 ------ .../fragments/SineCosineFragment.kt | 50 +++++ .../fragments/ViewPagerSimpleChartDemo.kt | 5 +- 13 files changed, 503 insertions(+), 557 deletions(-) delete mode 100644 app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.java create mode 100644 app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.java create mode 100644 app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.java create mode 100644 app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.java create mode 100644 app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.java create mode 100644 app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.kt delete mode 100644 app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.java create mode 100644 app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.kt diff --git a/app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.java b/app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.java deleted file mode 100644 index 053211a060..0000000000 --- a/app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.java +++ /dev/null @@ -1,113 +0,0 @@ -package info.appdev.chartexample.fragments; -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; - -import com.github.mikephil.charting.charts.BarChart; -import com.github.mikephil.charting.components.Legend; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.YAxis; -import com.github.mikephil.charting.listener.ChartTouchListener; -import com.github.mikephil.charting.listener.OnChartGestureListener; - -import info.appdev.chartexample.R; -import info.appdev.chartexample.custom.MyMarkerView; - - -public class BarChartFrag extends SimpleFragment implements OnChartGestureListener { - - @NonNull - public static Fragment newInstance() { - return new BarChartFrag(); - } - - private BarChart chart; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.frag_simple_bar, container, false); - - // create a new chart object - chart = new BarChart(getActivity()); - chart.getDescription().setEnabled(false); - chart.setOnChartGestureListener(this); - - MyMarkerView mv = new MyMarkerView(getActivity(), R.layout.custom_marker_view); - mv.setChartView(chart); // For bounds control - chart.setMarker(mv); - - chart.setDrawGridBackground(false); - chart.setDrawBarShadow(false); - - Typeface tf = Typeface.createFromAsset(requireContext().getAssets(), "OpenSans-Light.ttf"); - - chart.setData(generateBarData(1, 20000)); - - Legend l = chart.getLegend(); - l.setTypeface(tf); - - YAxis leftAxis = chart.getAxisLeft(); - leftAxis.setTypeface(tf); - leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) - - chart.getAxisRight().setEnabled(false); - - XAxis xAxis = chart.getXAxis(); - xAxis.setEnabled(false); - - // programmatically add the chart - FrameLayout parent = v.findViewById(R.id.parentLayout); - parent.addView(chart); - - return v; - } - - @Override - public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) { - Log.i("Gesture", "START"); - } - - @Override - public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) { - Log.i("Gesture", "END"); - chart.highlightValues(null); - } - - @Override - public void onChartLongPressed(MotionEvent me) { - Log.i("LongPress", "Chart long pressed."); - } - - @Override - public void onChartDoubleTapped(MotionEvent me) { - Log.i("DoubleTap", "Chart double-tapped."); - } - - @Override - public void onChartSingleTapped(MotionEvent me) { - Log.i("SingleTap", "Chart single-tapped."); - } - - @Override - public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) { - Log.i("Fling", "Chart fling. VelocityX: " + velocityX + ", VelocityY: " + velocityY); - } - - @Override - public void onChartScale(MotionEvent me, float scaleX, float scaleY) { - Log.i("Scale / Zoom", "ScaleX: " + scaleX + ", ScaleY: " + scaleY); - } - - @Override - public void onChartTranslate(MotionEvent me, float dX, float dY) { - Log.i("Translate / Move", "dX: " + dX + ", dY: " + dY); - } - -} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.kt b/app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.kt new file mode 100644 index 0000000000..3a3097baf9 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/fragments/BarChartFrag.kt @@ -0,0 +1,97 @@ +package info.appdev.chartexample.fragments + +import android.graphics.Typeface +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import androidx.fragment.app.Fragment +import com.github.mikephil.charting.charts.BarChart +import com.github.mikephil.charting.listener.ChartTouchListener.ChartGesture +import com.github.mikephil.charting.listener.OnChartGestureListener +import info.appdev.chartexample.R +import info.appdev.chartexample.custom.MyMarkerView + +class BarChartFrag : SimpleFragment(), OnChartGestureListener { + private var chart: BarChart? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + val v = inflater.inflate(R.layout.frag_simple_bar, container, false) + + // create a new chart object + chart = BarChart(requireActivity()) + chart!!.description.isEnabled = false + chart!!.onChartGestureListener = this + + val mv = MyMarkerView(activity, R.layout.custom_marker_view) + mv.chartView = chart // For bounds control + chart!!.setMarker(mv) + + chart!!.setDrawGridBackground(false) + chart!!.setDrawBarShadow(false) + + val tf = Typeface.createFromAsset(requireContext().assets, "OpenSans-Light.ttf") + + chart!!.setData(generateBarData(1, 20000f)) + + val l = chart!!.legend + l.typeface = tf + + val leftAxis = chart!!.axisLeft + leftAxis.typeface = tf + leftAxis.setAxisMinimum(0f) // this replaces setStartAtZero(true) + + chart!!.axisRight.isEnabled = false + + val xAxis = chart!!.xAxis + xAxis.isEnabled = false + + // programmatically add the chart + val parent = v.findViewById(R.id.parentLayout) + parent.addView(chart) + + return v + } + + override fun onChartGestureStart(me: MotionEvent?, lastPerformedGesture: ChartGesture?) { + Log.i("Gesture", "START") + } + + override fun onChartGestureEnd(me: MotionEvent?, lastPerformedGesture: ChartGesture?) { + Log.i("Gesture", "END") + chart!!.highlightValues(null) + } + + override fun onChartLongPressed(me: MotionEvent?) { + Log.i("LongPress", "Chart long pressed.") + } + + override fun onChartDoubleTapped(me: MotionEvent?) { + Log.i("DoubleTap", "Chart double-tapped.") + } + + override fun onChartSingleTapped(me: MotionEvent?) { + Log.i("SingleTap", "Chart single-tapped.") + } + + override fun onChartFling(me1: MotionEvent?, me2: MotionEvent?, velocityX: Float, velocityY: Float) { + Log.i("Fling", "Chart fling. VelocityX: $velocityX, VelocityY: $velocityY") + } + + override fun onChartScale(me: MotionEvent?, scaleX: Float, scaleY: Float) { + Log.i("Scale / Zoom", "ScaleX: $scaleX, ScaleY: $scaleY") + } + + override fun onChartTranslate(me: MotionEvent?, dX: Float, dY: Float) { + Log.i("Translate / Move", "dX: $dX, dY: $dY") + } + + companion object { + fun newInstance(): Fragment { + return BarChartFrag() + } + } +} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.java b/app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.java deleted file mode 100644 index fd6aeb4cc0..0000000000 --- a/app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.java +++ /dev/null @@ -1,56 +0,0 @@ -package info.appdev.chartexample.fragments; -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import info.appdev.chartexample.R; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.github.mikephil.charting.charts.LineChart; -import com.github.mikephil.charting.components.Legend; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.YAxis; - - -public class ComplexityFragment extends SimpleFragment { - - @NonNull - public static Fragment newInstance() { - return new ComplexityFragment(); - } - - @SuppressWarnings("FieldCanBeLocal") - private LineChart chart; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.frag_simple_line, container, false); - - chart = v.findViewById(R.id.lineChart1); - - chart.getDescription().setEnabled(false); - - chart.setDrawGridBackground(false); - - chart.setData(getComplexity()); - chart.animateX(3000); - - Typeface tf = Typeface.createFromAsset(requireContext().getAssets(), "OpenSans-Light.ttf"); - - Legend l = chart.getLegend(); - l.setTypeface(tf); - - YAxis leftAxis = chart.getAxisLeft(); - leftAxis.setTypeface(tf); - - chart.getAxisRight().setEnabled(false); - - XAxis xAxis = chart.getXAxis(); - xAxis.setEnabled(false); - - return v; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.kt b/app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.kt new file mode 100644 index 0000000000..cc48c31277 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/fragments/ComplexityFragment.kt @@ -0,0 +1,48 @@ +package info.appdev.chartexample.fragments + +import android.graphics.Typeface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.github.mikephil.charting.charts.LineChart +import info.appdev.chartexample.R + +class ComplexityFragment : SimpleFragment() { + private var chart: LineChart? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + val v = inflater.inflate(R.layout.frag_simple_line, container, false) + + chart = v.findViewById(R.id.lineChart1) + + chart!!.description.isEnabled = false + + chart!!.setDrawGridBackground(false) + + chart!!.setData(complexity) + chart!!.animateX(3000) + + val tf = Typeface.createFromAsset(requireContext().assets, "OpenSans-Light.ttf") + + val l = chart!!.legend + l.typeface = tf + + val leftAxis = chart!!.axisLeft + leftAxis.typeface = tf + + chart!!.axisRight.isEnabled = false + + val xAxis = chart!!.xAxis + xAxis.isEnabled = false + + return v + } + + companion object { + fun newInstance(): Fragment { + return ComplexityFragment() + } + } +} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.java b/app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.java deleted file mode 100644 index bd698348c0..0000000000 --- a/app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.java +++ /dev/null @@ -1,65 +0,0 @@ -package info.appdev.chartexample.fragments; -import android.graphics.Color; -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import info.appdev.chartexample.R; - -import android.text.SpannableString; -import android.text.style.ForegroundColorSpan; -import android.text.style.RelativeSizeSpan; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.github.mikephil.charting.charts.PieChart; -import com.github.mikephil.charting.components.Legend; - - -public class PieChartFrag extends SimpleFragment { - - @NonNull - public static Fragment newInstance() { - return new PieChartFrag(); - } - - @SuppressWarnings("FieldCanBeLocal") - private PieChart chart; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.frag_simple_pie, container, false); - - chart = v.findViewById(R.id.pieChart1); - chart.getDescription().setEnabled(false); - - Typeface tf = Typeface.createFromAsset(requireContext().getAssets(), "OpenSans-Light.ttf"); - - chart.setCenterTextTypeface(tf); - chart.setCenterText(generateCenterText()); - chart.setCenterTextSize(10f); - chart.setCenterTextTypeface(tf); - - // radius of the center hole in percent of maximum radius - chart.setHoleRadius(45f); - chart.setTransparentCircleRadius(50f); - - Legend l = chart.getLegend(); - l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); - l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); - l.setOrientation(Legend.LegendOrientation.VERTICAL); - l.setDrawInside(false); - - chart.setData(generatePieData()); - - return v; - } - - private SpannableString generateCenterText() { - SpannableString s = new SpannableString("Revenues\nQuarters 2015"); - s.setSpan(new RelativeSizeSpan(2f), 0, 8, 0); - s.setSpan(new ForegroundColorSpan(Color.GRAY), 8, s.length(), 0); - return s; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.kt b/app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.kt new file mode 100644 index 0000000000..8b86a1b59b --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/fragments/PieChartFrag.kt @@ -0,0 +1,60 @@ +package info.appdev.chartexample.fragments + +import android.graphics.Color +import android.graphics.Typeface +import android.os.Bundle +import android.text.SpannableString +import android.text.style.ForegroundColorSpan +import android.text.style.RelativeSizeSpan +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.github.mikephil.charting.charts.PieChart +import com.github.mikephil.charting.components.Legend +import info.appdev.chartexample.R + +class PieChartFrag : SimpleFragment() { + private var chart: PieChart? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + val v = inflater.inflate(R.layout.frag_simple_pie, container, false) + + chart = v.findViewById(R.id.pieChart1) + chart!!.description.isEnabled = false + + val tf = Typeface.createFromAsset(requireContext().assets, "OpenSans-Light.ttf") + + chart!!.setCenterTextTypeface(tf) + chart!!.centerText = generateCenterText() + chart!!.setCenterTextSize(10f) + chart!!.setCenterTextTypeface(tf) + + // radius of the center hole in percent of maximum radius + chart!!.holeRadius = 45f + chart!!.transparentCircleRadius = 50f + + val l = chart!!.legend + l.verticalAlignment = Legend.LegendVerticalAlignment.TOP + l.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT + l.orientation = Legend.LegendOrientation.VERTICAL + l.setDrawInside(false) + + chart!!.setData(generatePieData()) + + return v + } + + private fun generateCenterText(): SpannableString { + val s = SpannableString("Revenues\nQuarters 2015") + s.setSpan(RelativeSizeSpan(2f), 0, 8, 0) + s.setSpan(ForegroundColorSpan(Color.GRAY), 8, s.length, 0) + return s + } + + companion object { + fun newInstance(): Fragment { + return PieChartFrag() + } + } +} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.java b/app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.java deleted file mode 100644 index f7c7c3d1f3..0000000000 --- a/app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.java +++ /dev/null @@ -1,70 +0,0 @@ -package info.appdev.chartexample.fragments; - -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.github.mikephil.charting.charts.ScatterChart; -import com.github.mikephil.charting.components.Legend; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.XAxis.XAxisPosition; -import com.github.mikephil.charting.components.YAxis; - -import info.appdev.chartexample.R; -import info.appdev.chartexample.custom.MyMarkerView; - - -public class ScatterChartFrag extends SimpleFragment { - - @NonNull - public static Fragment newInstance() { - return new ScatterChartFrag(); - } - - @SuppressWarnings("FieldCanBeLocal") - private ScatterChart chart; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.frag_simple_scatter, container, false); - - chart = v.findViewById(R.id.scatterChart1); - chart.getDescription().setEnabled(false); - - Typeface tf = Typeface.createFromAsset(requireContext().getAssets(), "OpenSans-Light.ttf"); - - MyMarkerView mv = new MyMarkerView(getActivity(), R.layout.custom_marker_view); - mv.setChartView(chart); // For bounds control - chart.setMarker(mv); - - chart.setDrawGridBackground(false); - chart.setData(generateScatterData(6, 10000)); - - XAxis xAxis = chart.getXAxis(); - xAxis.setEnabled(true); - xAxis.setPosition(XAxisPosition.BOTTOM); - - YAxis leftAxis = chart.getAxisLeft(); - leftAxis.setTypeface(tf); - - YAxis rightAxis = chart.getAxisRight(); - rightAxis.setTypeface(tf); - rightAxis.setDrawGridLines(false); - - Legend l = chart.getLegend(); - l.setWordWrapEnabled(true); - l.setTypeface(tf); - l.setFormSize(14f); - l.setTextSize(9f); - - // increase the space between legend & bottom and legend & content - l.setYOffset(13f); - chart.setExtraBottomOffset(16f); - - return v; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.kt b/app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.kt new file mode 100644 index 0000000000..04c384b089 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/fragments/ScatterChartFrag.kt @@ -0,0 +1,61 @@ +package info.appdev.chartexample.fragments + +import android.graphics.Typeface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.github.mikephil.charting.charts.ScatterChart +import com.github.mikephil.charting.components.XAxis.XAxisPosition +import info.appdev.chartexample.R +import info.appdev.chartexample.custom.MyMarkerView + +class ScatterChartFrag : SimpleFragment() { + private var chart: ScatterChart? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + val v = inflater.inflate(R.layout.frag_simple_scatter, container, false) + + chart = v.findViewById(R.id.scatterChart1) + chart!!.description.isEnabled = false + + val tf = Typeface.createFromAsset(requireContext().assets, "OpenSans-Light.ttf") + + val mv = MyMarkerView(activity, R.layout.custom_marker_view) + mv.chartView = chart // For bounds control + chart!!.setMarker(mv) + + chart!!.setDrawGridBackground(false) + chart!!.setData(generateScatterData(6, 10000f)) + + val xAxis = chart!!.xAxis + xAxis.isEnabled = true + xAxis.position = XAxisPosition.BOTTOM + + val leftAxis = chart!!.axisLeft + leftAxis.typeface = tf + + val rightAxis = chart!!.axisRight + rightAxis.typeface = tf + rightAxis.setDrawGridLines(false) + + val l = chart!!.legend + l.isWordWrapEnabled = true + l.typeface = tf + l.formSize = 14f + l.textSize = 9f + + // increase the space between legend & bottom and legend & content + l.yOffset = 13f + chart!!.extraBottomOffset = 16f + + return v + } + + companion object { + fun newInstance(): Fragment { + return ScatterChartFrag() + } + } +} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.java b/app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.java deleted file mode 100644 index 249c4f5ba2..0000000000 --- a/app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.java +++ /dev/null @@ -1,194 +0,0 @@ -package info.appdev.chartexample.fragments; - -import android.graphics.Color; -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.github.mikephil.charting.charts.ScatterChart; -import com.github.mikephil.charting.data.BarData; -import com.github.mikephil.charting.data.BarDataSet; -import com.github.mikephil.charting.data.BarEntry; -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.data.LineData; -import com.github.mikephil.charting.data.LineDataSet; -import com.github.mikephil.charting.data.PieData; -import com.github.mikephil.charting.data.PieDataSet; -import com.github.mikephil.charting.data.PieEntry; -import com.github.mikephil.charting.data.ScatterData; -import com.github.mikephil.charting.data.ScatterDataSet; -import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; -import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; -import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; -import com.github.mikephil.charting.utils.ColorTemplate; -import com.github.mikephil.charting.utils.FileUtils; -import info.appdev.chartexample.DataTools; - -import java.util.ArrayList; - -@SuppressWarnings({"SameParameterValue", "WeakerAccess"}) -public abstract class SimpleFragment extends Fragment { - - private Typeface tf; - - public SimpleFragment() { - - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - tf = Typeface.createFromAsset(requireContext().getAssets(), "OpenSans-Regular.ttf"); - return super.onCreateView(inflater, container, savedInstanceState); - } - - protected BarData generateBarData(int dataSets, float range) { - int count = 12; - Double[] values = DataTools.Companion.getValues(count); - ArrayList sets = new ArrayList<>(); - - for(int i = 0; i < dataSets; i++) { - - ArrayList entries = new ArrayList<>(); - - for(int j = 0; j < count; j++) { - entries.add(new BarEntry(j, (float) (values[j].floatValue() * range) + range / 4)); - } - - BarDataSet ds = new BarDataSet(entries, getLabel(i)); - ds.setColors(ColorTemplate.VORDIPLOM_COLORS); - sets.add(ds); - } - - BarData d = new BarData(sets); - d.setValueTypeface(tf); - return d; - } - - protected ScatterData generateScatterData(int dataSets, float range) { - int count = 100; - Double[] values = DataTools.Companion.getValues(count); - ArrayList sets = new ArrayList<>(); - - ScatterChart.ScatterShape[] shapes = ScatterChart.ScatterShape.getAllDefaultShapes(); - - for(int i = 0; i < dataSets; i++) { - - ArrayList entries = new ArrayList<>(); - - for(int j = 0; j < count; j++) { - entries.add(new Entry(j, (float) (values[j].floatValue() * range) + range / 4)); - } - - ScatterDataSet ds = new ScatterDataSet(entries, getLabel(i)); - ds.setScatterShapeSize(12f); - ds.setScatterShape(shapes[i % shapes.length]); - ds.setColors(ColorTemplate.COLORFUL_COLORS); - ds.setScatterShapeSize(9f); - sets.add(ds); - } - - ScatterData d = new ScatterData(sets); - d.setValueTypeface(tf); - return d; - } - - /** - * generates less data (1 DataSet, 4 values) - * @return PieData - */ - protected PieData generatePieData() { - - int count = 4; - Double[] values = DataTools.Companion.getValues(count); - ArrayList entries1 = new ArrayList<>(); - - for(int i = 0; i < count; i++) { - entries1.add(new PieEntry((float) ((values[i].floatValue() * 60) + 40), "Quarter " + (i+1))); - } - - PieDataSet ds1 = new PieDataSet(entries1, "Quarterly Revenues 2015"); - ds1.setColors(ColorTemplate.VORDIPLOM_COLORS); - ds1.setSliceSpace(2f); - ds1.setValueTextColor(Color.WHITE); - ds1.setValueTextSize(12f); - - PieData d = new PieData(ds1); - d.setValueTypeface(tf); - - return d; - } - - protected LineData generateLineData() { - - ArrayList sets = new ArrayList<>(); - LineDataSet ds1 = new LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().getAssets(), "sine.txt"), "Sine function"); - LineDataSet ds2 = new LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().getAssets(), "cosine.txt"), "Cosine function"); - - ds1.setLineWidth(2f); - ds2.setLineWidth(2f); - - ds1.setDrawCircles(false); - ds2.setDrawCircles(false); - - ds1.setColor(ColorTemplate.VORDIPLOM_COLORS[0]); - ds2.setColor(ColorTemplate.VORDIPLOM_COLORS[1]); - - // load DataSets from files in assets folder - sets.add(ds1); - sets.add(ds2); - - LineData d = new LineData(sets); - d.setValueTypeface(tf); - return d; - } - - protected LineData getComplexity() { - - ArrayList sets = new ArrayList<>(); - - LineDataSet ds1 = new LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().getAssets(), "n.txt"), "O(n)"); - LineDataSet ds2 = new LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().getAssets(), "nlogn.txt"), "O(nlogn)"); - LineDataSet ds3 = new LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().getAssets(), "square.txt"), "O(n\u00B2)"); - LineDataSet ds4 = new LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().getAssets(), "three.txt"), "O(n\u00B3)"); - - ds1.setColor(ColorTemplate.VORDIPLOM_COLORS[0]); - ds2.setColor(ColorTemplate.VORDIPLOM_COLORS[1]); - ds3.setColor(ColorTemplate.VORDIPLOM_COLORS[2]); - ds4.setColor(ColorTemplate.VORDIPLOM_COLORS[3]); - - ds1.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[0]); - ds2.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[1]); - ds3.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[2]); - ds4.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[3]); - - ds1.setLineWidth(2.5f); - ds1.setCircleRadius(3f); - ds2.setLineWidth(2.5f); - ds2.setCircleRadius(3f); - ds3.setLineWidth(2.5f); - ds3.setCircleRadius(3f); - ds4.setLineWidth(2.5f); - ds4.setCircleRadius(3f); - - - // load DataSets from files in assets folder - sets.add(ds1); - sets.add(ds2); - sets.add(ds3); - sets.add(ds4); - - LineData d = new LineData(sets); - d.setValueTypeface(tf); - return d; - } - - private final String[] mLabels = new String[] { "Company A", "Company B", "Company C", "Company D", "Company E", "Company F" }; - - private String getLabel(int i) { - return mLabels[i]; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.kt b/app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.kt new file mode 100644 index 0000000000..87d5728b6b --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/fragments/SimpleFragment.kt @@ -0,0 +1,183 @@ +package info.appdev.chartexample.fragments + +import android.graphics.Color +import android.graphics.Typeface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.github.mikephil.charting.charts.ScatterChart.ScatterShape +import com.github.mikephil.charting.data.BarData +import com.github.mikephil.charting.data.BarDataSet +import com.github.mikephil.charting.data.BarEntry +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.data.PieData +import com.github.mikephil.charting.data.PieDataSet +import com.github.mikephil.charting.data.PieEntry +import com.github.mikephil.charting.data.ScatterData +import com.github.mikephil.charting.data.ScatterDataSet +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet +import com.github.mikephil.charting.utils.ColorTemplate +import com.github.mikephil.charting.utils.FileUtils +import info.appdev.chartexample.DataTools.Companion.getValues + +abstract class SimpleFragment : Fragment() { + private var tf: Typeface? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + tf = Typeface.createFromAsset(requireContext().assets, "OpenSans-Regular.ttf") + return super.onCreateView(inflater, container, savedInstanceState) + } + + protected fun generateBarData(dataSets: Int, range: Float): BarData { + val count = 12 + val values = getValues(count) + val sets = ArrayList() + + for (i in 0..() + + for (j in 0..() + + val shapes = ScatterShape.getAllDefaultShapes() + + for (i in 0..() + + for (j in 0..() + + for (i in 0..() + val ds1 = LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().assets, "sine.txt"), "Sine function") + val ds2 = LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().assets, "cosine.txt"), "Cosine function") + + ds1.setLineWidth(2f) + ds2.setLineWidth(2f) + + ds1.setDrawCircles(false) + ds2.setDrawCircles(false) + + ds1.setColor(ColorTemplate.VORDIPLOM_COLORS[0]) + ds2.setColor(ColorTemplate.VORDIPLOM_COLORS[1]) + + // load DataSets from files in assets folder + sets.add(ds1) + sets.add(ds2) + + val d = LineData(sets) + d.setValueTypeface(tf) + return d + } + + protected val complexity: LineData + get() { + val sets = ArrayList() + + val ds1 = + LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().assets, "n.txt"), "O(n)") + val ds2 = + LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().assets, "nlogn.txt"), "O(nlogn)") + val ds3 = + LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().assets, "square.txt"), "O(n\u00B2)") + val ds4 = + LineDataSet(FileUtils.loadEntriesFromAssets(requireContext().assets, "three.txt"), "O(n\u00B3)") + + ds1.setColor(ColorTemplate.VORDIPLOM_COLORS[0]) + ds2.setColor(ColorTemplate.VORDIPLOM_COLORS[1]) + ds3.setColor(ColorTemplate.VORDIPLOM_COLORS[2]) + ds4.setColor(ColorTemplate.VORDIPLOM_COLORS[3]) + + ds1.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[0]) + ds2.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[1]) + ds3.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[2]) + ds4.setCircleColor(ColorTemplate.VORDIPLOM_COLORS[3]) + + ds1.setLineWidth(2.5f) + ds1.circleRadius = 3f + ds2.setLineWidth(2.5f) + ds2.circleRadius = 3f + ds3.setLineWidth(2.5f) + ds3.circleRadius = 3f + ds4.setLineWidth(2.5f) + ds4.circleRadius = 3f + + + // load DataSets from files in assets folder + sets.add(ds1) + sets.add(ds2) + sets.add(ds3) + sets.add(ds4) + + val d = LineData(sets) + d.setValueTypeface(tf) + return d + } + + private val labels: Array = arrayOf("Company A", "Company B", "Company C", "Company D", "Company E", "Company F") + + private fun getLabel(i: Int): String { + return labels[i] + } +} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.java b/app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.java deleted file mode 100644 index 68858b64cb..0000000000 --- a/app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.java +++ /dev/null @@ -1,58 +0,0 @@ -package info.appdev.chartexample.fragments; -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import info.appdev.chartexample.R; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.github.mikephil.charting.charts.LineChart; -import com.github.mikephil.charting.components.Legend; -import com.github.mikephil.charting.components.XAxis; -import com.github.mikephil.charting.components.YAxis; - - -public class SineCosineFragment extends SimpleFragment { - - @NonNull - public static Fragment newInstance() { - return new SineCosineFragment(); - } - - @SuppressWarnings("FieldCanBeLocal") - private LineChart chart; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.frag_simple_line, container, false); - - chart = v.findViewById(R.id.lineChart1); - - chart.getDescription().setEnabled(false); - - chart.setDrawGridBackground(false); - - chart.setData(generateLineData()); - chart.animateX(3000); - - Typeface tf = Typeface.createFromAsset(requireContext().getAssets(), "OpenSans-Light.ttf"); - - Legend l = chart.getLegend(); - l.setTypeface(tf); - - YAxis leftAxis = chart.getAxisLeft(); - leftAxis.setTypeface(tf); - leftAxis.setAxisMaximum(1.2f); - leftAxis.setAxisMinimum(-1.2f); - - chart.getAxisRight().setEnabled(false); - - XAxis xAxis = chart.getXAxis(); - xAxis.setEnabled(false); - - return v; - } -} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.kt b/app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.kt new file mode 100644 index 0000000000..98064fa25f --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/fragments/SineCosineFragment.kt @@ -0,0 +1,50 @@ +package info.appdev.chartexample.fragments + +import android.graphics.Typeface +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.github.mikephil.charting.charts.LineChart +import info.appdev.chartexample.R + +class SineCosineFragment : SimpleFragment() { + private var chart: LineChart? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + val v = inflater.inflate(R.layout.frag_simple_line, container, false) + + chart = v.findViewById(R.id.lineChart1) + + chart!!.description.isEnabled = false + + chart!!.setDrawGridBackground(false) + + chart!!.setData(generateLineData()) + chart!!.animateX(3000) + + val tf = Typeface.createFromAsset(requireContext().assets, "OpenSans-Light.ttf") + + val l = chart!!.legend + l.typeface = tf + + val leftAxis = chart!!.axisLeft + leftAxis.typeface = tf + leftAxis.setAxisMaximum(1.2f) + leftAxis.setAxisMinimum(-1.2f) + + chart!!.axisRight.isEnabled = false + + val xAxis = chart!!.xAxis + xAxis.isEnabled = false + + return v + } + + companion object { + fun newInstance(): Fragment { + return SineCosineFragment() + } + } +} diff --git a/app/src/main/java/info/appdev/chartexample/fragments/ViewPagerSimpleChartDemo.kt b/app/src/main/java/info/appdev/chartexample/fragments/ViewPagerSimpleChartDemo.kt index 00eeba977c..396736ca77 100644 --- a/app/src/main/java/info/appdev/chartexample/fragments/ViewPagerSimpleChartDemo.kt +++ b/app/src/main/java/info/appdev/chartexample/fragments/ViewPagerSimpleChartDemo.kt @@ -25,7 +25,10 @@ import info.appdev.chartexample.notimportant.DemoBase class ViewPagerSimpleChartDemo : DemoBase() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) + window.setFlags( + WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN + ) setContentView(R.layout.activity_awesomedesign) val pager = findViewById(R.id.pager) pager.offscreenPageLimit = 3 From b5fdc01985ca914c2273ade0afa1a2c257ec1a4b Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Tue, 2 Dec 2025 07:31:12 +0100 Subject: [PATCH 3/4] Kotlin formatter --- .../appdev/chartexample/BarChartActivity.kt | 4 +-- .../chartexample/ListViewBarChartActivity.kt | 2 -- .../appdev/chartexample/StackedBarActivity.kt | 4 +-- .../custom/CustomScatterShapeRenderer.java | 31 ------------------- .../custom/CustomScatterShapeRenderer.kt | 28 +++++++++++++++++ .../DayAxisValueFormatter.kt | 2 +- .../MyAxisValueFormatter.kt | 2 +- .../{custom => formatter}/MyFillFormatter.kt | 4 +-- .../{custom => formatter}/MyValueFormatter.kt | 2 +- .../YearXAxisFormatter.kt | 2 +- 10 files changed, 38 insertions(+), 43 deletions(-) delete mode 100644 app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.java create mode 100644 app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.kt rename app/src/main/java/info/appdev/chartexample/{custom => formatter}/DayAxisValueFormatter.kt (98%) rename app/src/main/java/info/appdev/chartexample/{custom => formatter}/MyAxisValueFormatter.kt (90%) rename app/src/main/java/info/appdev/chartexample/{custom => formatter}/MyFillFormatter.kt (91%) rename app/src/main/java/info/appdev/chartexample/{custom => formatter}/MyValueFormatter.kt (92%) rename app/src/main/java/info/appdev/chartexample/{custom => formatter}/YearXAxisFormatter.kt (92%) diff --git a/app/src/main/java/info/appdev/chartexample/BarChartActivity.kt b/app/src/main/java/info/appdev/chartexample/BarChartActivity.kt index b2dc828522..68dfaa2cae 100644 --- a/app/src/main/java/info/appdev/chartexample/BarChartActivity.kt +++ b/app/src/main/java/info/appdev/chartexample/BarChartActivity.kt @@ -31,8 +31,8 @@ import com.github.mikephil.charting.listener.OnChartValueSelectedListener import com.github.mikephil.charting.utils.Fill import com.github.mikephil.charting.utils.MPPointF import info.appdev.chartexample.DataTools.Companion.getValues -import info.appdev.chartexample.custom.DayAxisValueFormatter -import info.appdev.chartexample.custom.MyAxisValueFormatter +import info.appdev.chartexample.formatter.DayAxisValueFormatter +import info.appdev.chartexample.formatter.MyAxisValueFormatter import info.appdev.chartexample.custom.XYMarkerView import info.appdev.chartexample.notimportant.DemoBase diff --git a/app/src/main/java/info/appdev/chartexample/ListViewBarChartActivity.kt b/app/src/main/java/info/appdev/chartexample/ListViewBarChartActivity.kt index 300b6106a1..a358dfebeb 100644 --- a/app/src/main/java/info/appdev/chartexample/ListViewBarChartActivity.kt +++ b/app/src/main/java/info/appdev/chartexample/ListViewBarChartActivity.kt @@ -27,8 +27,6 @@ import androidx.core.net.toUri /** * Demonstrates the use of charts inside a ListView. IMPORTANT: provide a * specific height attribute for the chart inside your ListView item - * - * @author Philipp Jahoda */ class ListViewBarChartActivity : DemoBase() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/info/appdev/chartexample/StackedBarActivity.kt b/app/src/main/java/info/appdev/chartexample/StackedBarActivity.kt index e19a6d1da8..352dfdaaf2 100644 --- a/app/src/main/java/info/appdev/chartexample/StackedBarActivity.kt +++ b/app/src/main/java/info/appdev/chartexample/StackedBarActivity.kt @@ -26,8 +26,8 @@ import com.github.mikephil.charting.interfaces.datasets.IBarDataSet import com.github.mikephil.charting.listener.OnChartValueSelectedListener import com.github.mikephil.charting.utils.ColorTemplate import info.appdev.chartexample.DataTools.Companion.getValues -import info.appdev.chartexample.custom.MyAxisValueFormatter -import info.appdev.chartexample.custom.MyValueFormatter +import info.appdev.chartexample.formatter.MyAxisValueFormatter +import info.appdev.chartexample.formatter.MyValueFormatter import info.appdev.chartexample.notimportant.DemoBase class StackedBarActivity : DemoBase(), OnSeekBarChangeListener, OnChartValueSelectedListener { diff --git a/app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.java b/app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.java deleted file mode 100644 index 873f438632..0000000000 --- a/app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.java +++ /dev/null @@ -1,31 +0,0 @@ -package info.appdev.chartexample.custom; - -import android.graphics.Canvas; -import android.graphics.Paint; - -import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet; -import com.github.mikephil.charting.renderer.scatter.IShapeRenderer; -import com.github.mikephil.charting.utils.Utils; -import com.github.mikephil.charting.utils.ViewPortHandler; - -/** - * Custom shape renderer that draws a single line. - * Created by philipp on 26/06/16. - */ -public class CustomScatterShapeRenderer implements IShapeRenderer -{ - - @Override - public void renderShape(Canvas c, IScatterDataSet dataSet, ViewPortHandler viewPortHandler, - float posX, float posY, Paint renderPaint) { - - final float shapeHalf = Utils.convertDpToPixel(dataSet.getScatterShapeSize()) / 2f; - - c.drawLine( - posX - shapeHalf, - posY - shapeHalf, - posX + shapeHalf, - posY + shapeHalf, - renderPaint); - } -} diff --git a/app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.kt b/app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.kt new file mode 100644 index 0000000000..8d3ddfab20 --- /dev/null +++ b/app/src/main/java/info/appdev/chartexample/custom/CustomScatterShapeRenderer.kt @@ -0,0 +1,28 @@ +package info.appdev.chartexample.custom + +import android.graphics.Canvas +import android.graphics.Paint +import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet +import com.github.mikephil.charting.renderer.scatter.IShapeRenderer +import com.github.mikephil.charting.utils.Utils +import com.github.mikephil.charting.utils.ViewPortHandler + +/** + * Custom shape renderer that draws a single line. + */ +class CustomScatterShapeRenderer : IShapeRenderer { + override fun renderShape( + canvas: Canvas, dataSet: IScatterDataSet, viewPortHandler: ViewPortHandler?, + posX: Float, posY: Float, renderPaint: Paint + ) { + val shapeHalf = Utils.convertDpToPixel(dataSet.getScatterShapeSize()) / 2f + + canvas.drawLine( + posX - shapeHalf, + posY - shapeHalf, + posX + shapeHalf, + posY + shapeHalf, + renderPaint + ) + } +} diff --git a/app/src/main/java/info/appdev/chartexample/custom/DayAxisValueFormatter.kt b/app/src/main/java/info/appdev/chartexample/formatter/DayAxisValueFormatter.kt similarity index 98% rename from app/src/main/java/info/appdev/chartexample/custom/DayAxisValueFormatter.kt rename to app/src/main/java/info/appdev/chartexample/formatter/DayAxisValueFormatter.kt index 3dd38d72ee..a3c0012ab8 100644 --- a/app/src/main/java/info/appdev/chartexample/custom/DayAxisValueFormatter.kt +++ b/app/src/main/java/info/appdev/chartexample/formatter/DayAxisValueFormatter.kt @@ -1,4 +1,4 @@ -package info.appdev.chartexample.custom +package info.appdev.chartexample.formatter import com.github.mikephil.charting.charts.BarLineChartBase import com.github.mikephil.charting.components.AxisBase diff --git a/app/src/main/java/info/appdev/chartexample/custom/MyAxisValueFormatter.kt b/app/src/main/java/info/appdev/chartexample/formatter/MyAxisValueFormatter.kt similarity index 90% rename from app/src/main/java/info/appdev/chartexample/custom/MyAxisValueFormatter.kt rename to app/src/main/java/info/appdev/chartexample/formatter/MyAxisValueFormatter.kt index 78ae2a1008..f0a4f70e67 100644 --- a/app/src/main/java/info/appdev/chartexample/custom/MyAxisValueFormatter.kt +++ b/app/src/main/java/info/appdev/chartexample/formatter/MyAxisValueFormatter.kt @@ -1,4 +1,4 @@ -package info.appdev.chartexample.custom +package info.appdev.chartexample.formatter import com.github.mikephil.charting.components.AxisBase import com.github.mikephil.charting.formatter.IAxisValueFormatter diff --git a/app/src/main/java/info/appdev/chartexample/custom/MyFillFormatter.kt b/app/src/main/java/info/appdev/chartexample/formatter/MyFillFormatter.kt similarity index 91% rename from app/src/main/java/info/appdev/chartexample/custom/MyFillFormatter.kt rename to app/src/main/java/info/appdev/chartexample/formatter/MyFillFormatter.kt index a63f824cb5..7abb0f7699 100644 --- a/app/src/main/java/info/appdev/chartexample/custom/MyFillFormatter.kt +++ b/app/src/main/java/info/appdev/chartexample/formatter/MyFillFormatter.kt @@ -1,4 +1,4 @@ -package info.appdev.chartexample.custom +package info.appdev.chartexample.formatter import com.github.mikephil.charting.formatter.IFillFormatter import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider @@ -10,4 +10,4 @@ class MyFillFormatter(private val fillPos: Float) : IFillFormatter { // your logic could be here return fillPos } -} +} \ No newline at end of file diff --git a/app/src/main/java/info/appdev/chartexample/custom/MyValueFormatter.kt b/app/src/main/java/info/appdev/chartexample/formatter/MyValueFormatter.kt similarity index 92% rename from app/src/main/java/info/appdev/chartexample/custom/MyValueFormatter.kt rename to app/src/main/java/info/appdev/chartexample/formatter/MyValueFormatter.kt index 701229650a..1fc517afbe 100644 --- a/app/src/main/java/info/appdev/chartexample/custom/MyValueFormatter.kt +++ b/app/src/main/java/info/appdev/chartexample/formatter/MyValueFormatter.kt @@ -1,4 +1,4 @@ -package info.appdev.chartexample.custom +package info.appdev.chartexample.formatter import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.formatter.IValueFormatter diff --git a/app/src/main/java/info/appdev/chartexample/custom/YearXAxisFormatter.kt b/app/src/main/java/info/appdev/chartexample/formatter/YearXAxisFormatter.kt similarity index 92% rename from app/src/main/java/info/appdev/chartexample/custom/YearXAxisFormatter.kt rename to app/src/main/java/info/appdev/chartexample/formatter/YearXAxisFormatter.kt index 036b172e5a..822d0007a3 100644 --- a/app/src/main/java/info/appdev/chartexample/custom/YearXAxisFormatter.kt +++ b/app/src/main/java/info/appdev/chartexample/formatter/YearXAxisFormatter.kt @@ -1,4 +1,4 @@ -package info.appdev.chartexample.custom +package info.appdev.chartexample.formatter import com.github.mikephil.charting.components.AxisBase import com.github.mikephil.charting.formatter.IAxisValueFormatter From dd6e340ef95015694309560f1ba8ff4ef2e43a4a Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Tue, 2 Dec 2025 08:03:17 +0100 Subject: [PATCH 4/4] Adopt reference screenshots --- ...ltiChartActivity-Multiple-1SampleClick.png | Bin 43297 -> 43351 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/screenshotsToCompare9/StartTest_smokeTestStart-31-ListViewMultiChartActivity-Multiple-1SampleClick.png b/screenshotsToCompare9/StartTest_smokeTestStart-31-ListViewMultiChartActivity-Multiple-1SampleClick.png index 9f382b4c80373692ee0bf82256bcbfacf3a42fef..c0dfe4641cf342029d41caaca8ff5c83dd8d2171 100644 GIT binary patch delta 6270 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 mG+H_p;RK{`X3I{O)${*4c}?r}COMJ-0000