How to add a marker with some details for Bar Chart using MPAndroidChart in Kotlin?

Viewed 1010

I created a stacked BarChart using MPAndroidChart library and now when the user clicks on a bar, I want to display a marker with some details as in the image bellow: enter image description here

I found different topics on this subject but couldn't find a clear solution, so please help me if you can. Thanks!

EDIT

 for (item in dataTicketsList) {
        if (i <= 2) {

            val firstValue: String = transformDataForChart(item.values.first!!)
            hoursValuesArray.add(firstValue.toFloat())

            val secondValue: String = transformDataForChart(item.values.second!!)
            hoursValuesArray.add(secondValue.toFloat())

            val thirdValue: String = transformDataForChart(item.values.third!!)
            hoursValuesArray.add(thirdValue.toFloat())

            entriesVerticalBar.add(BarEntry(i, hoursValuesArray.toFloatArray()))
            i++
            hoursValuesArray.clear()

            if (item.label!!.contains("." + (Calendar.getInstance().get(Calendar.YEAR) - 1).toString())) {
                val date: String = item.label!!.replace("." + (Calendar.getInstance().get(Calendar.YEAR) - 1).toString(), "")
                barLabesArrayList.add(date)
            } else if (item.label!!.contains("." + (Calendar.getInstance().get(Calendar.YEAR)).toString())) {
                val date: String = item.label!!.replace("." + (Calendar.getInstance().get(Calendar.YEAR)).toString(), "")
                barLabesArrayList.add(date)
            }
        }
    }

    verticalBarChartColors.add(Color.rgb(89, 93, 223))
    verticalBarChartColors.add(Color.rgb(25, 227, 180))
    verticalBarChartColors.add(Color.rgb(85, 164, 206))
    val markerView = CustomMarkerView(requireContext(), R.layout.custom_marker_view_layout, hoursValuesArray )
    var barDataSet = BarDataSet(entriesVerticalBar, "")
    val barChart: BarChart = bar_chart_details
    barDataSet.colors = verticalBarChartColors
    barDataSet.valueTextSize = 8f
    barDataSet.stackLabels = arrayOf("00:00 - 06:00 h", "06:00 - 18:00 h", "18:00 - 24:00 h")
    barDataSet.valueTextColor = resources.getColor(R.color.white)
    val barData = BarData(barDataSet)
    barData.setValueFormatter(VerticalBarChart.DecimalRemover(DecimalFormat("###")))
    barChart.data = barData
    barChart.marker = markerView
1 Answers

You can define your custom marker view declaring a class which extends the MarkerView class.

  1. Define a custom layout for your marker view (custom_marker_view.xml).
    You could customize this layout with a layout or other views as you need.
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="6dp"
    android:layout_marginRight="6dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txtViewData"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"/>

</LinearLayout>
  1. Create the custom class (CustomMarkerView) extending MarkerView.
    This class must receive the array of data displayed in the chart and override the refreshContent method, were the data will be displayed.
    The getOffset method is optional and it serves to adjust the position of the marker on the screen.
class CustomMarkerView(
        context: Context,
        layout: Int,
        private val dataToDisplay: MutableList<Float>
) : MarkerView(context, layout) {

    private var txtViewData: TextView? = null

    init {
        txtViewData = findViewById(R.id.txtViewData)
    }

    override fun refreshContent(e: Entry?, highlight: Highlight?) {
        try {
            val xAxis = e?.x?.toInt() ?: 0
            txtViewData?.text = dataToDisplay[xAxis].toString()
        } catch (e: IndexOutOfBoundsException) { }

        super.refreshContent(e, highlight)
    }

    override fun getOffset(): MPPointF {
        return MPPointF(-(width / 2f), -height.toFloat())
    }
}
  1. You can then assign the marker to your chart with:
val marker = new CustomMarkerView(this, R.layout.custom_marker_view, <your-array-of-data>)
chart.marker = marker
Related