2

I have a LineChart in my app. The x value of the data points I use are milliseconds that I display as a date using ValueFormatter. This works fine, except I only want the date to be displayed once. I tried the following code, and it almost works, however it only works for the first date displayed. Any help appreciated!

Here is an example of my problem:

gif

This is my most successful code, I use kotlin:

val xAxis = chart.xAxis
xAxis.position = XAxis.XAxisPosition.BOTTOM

val dateFormatter = SimpleDateFormat("dd/MM")
var lastDate = ""
val formatter = object :  ValueFormatter() {
    override fun getFormattedValue(value: Float): String {
        val date = dateFormatter.format(Date(value.toLong()))
        if (date==lastDate){
            return ""
        }
        lastDate = date
        return date
    }
}
xAxis.valueFormatter = formatter

The following is the whole function, the json is temporary and is only there for testing purposes, the app will receive similar jsons.

private fun chart(){

        val json = JSONObject("""{"payload":{"serie":{"data":
            [[1564129484189,3287],[1564129933626,3287],[1564130385185,3287],[1564130834622,3280],[1564131284854,3280],[1564131736401,3280],
            [1564132184652,3280],[1564132634092,3280],[1564133083925,3280],[1564133534963,3287],[1564133984117,3287],[1564134434677,3287],
            [1564134883854,3280],[1564135333830,3280],[1564135785080,3280],[1564136234991,3280],[1564136685793,3280],[1564137134667,3280],
            [1564137584570,3280],[1564138034367,3280],[1564138484236,3280],[1564138934104,3273],[1564139384690,3273],[1564139834549,3273],
            [1564140284417,3280],[1564140734298,3280],[1564141183544,3280],[1564141634006,3273],[1564142083871,3273],[1564142533644,3273],
            [1564142984818,3273],[1564143433797,3273],[1564143883681,3273],[1564144334485,3273],[1564144785207,3273],[1564145234378,3273],
            [1564145685180,3280],[1564146134070,3280],[1564146584966,3280],[1564147034886,3280],[1564147484703,3280],[1564147934612,3280],
            [1564148384456,3280],[1564148834343,3280],[1564149283943,3280],[1564149734825,3280],[1564150184715,3280],[1564150634494,3280],
            [1564151084377,3287],[1564151534299,3287],[1564151984188,3287],[1564215691264,3287],[1564216142234,3287],[1564216591762,3287],
            [1564217041687,3287],[1564217491103,3287],[1564217941061,3287],[1564218391529,3287],[1564218841469,3287],[1564219291586,3287],
            [1564219741426,3287],[1564220192557,3287],[1564220641356,3287],[1564221091465,3280],[1564221541440,3280],[1564221991829,3280],
            [1564222441313,3287],[1564222893010,3287],[1564223344202,3287],[1564223792494,3280],[1564224696695,3280],[1564225144701,3280],
            [1564225591575,3280],[1564226047071,3280],[1564226492027,3280],[1564226951626,3280],[1564227392573,3280],[1564227841277,3280],
            [1564228292385,3287],[1564228741844,3287],[1564229192885,3287],[1564229642831,3287],[1564230092311,3287],[1564230550690,3287],
            [1564230993205,3287],[1564231443101,3287],[1564231892541,3287],[1564232344078,3280],[1564232793143,3280],[1564233255081,3280]]}}}""")

        val payload = json.get("payload") as JSONObject
        val serie = payload.get("serie") as JSONObject
        val dataPoints = serie.get("data") as JSONArray


        val values = arrayListOf<Entry>()
        for (i in 0 until dataPoints.length()) {
            val innerData = dataPoints[i] as JSONArray
            values.add (Entry(
                innerData[0].toString().toFloat() ,
                innerData[1].toString().toFloat()
            ))
        }


        val chart = findViewById<LineChart>(R.id.graph2)
        chart.setTouchEnabled(true)
        chart.setPinchZoom(true)
        chart.isScaleYEnabled = false


        val dataSet = LineDataSet(values, "Service")
        dataSet.color = ContextCompat.getColor(this, R.color.colorAccent)
        dataSet.setCircleColor(ContextCompat.getColor(this, R.color.colorPrimaryDark))
        dataSet.setDrawValues(false)
        dataSet.lineWidth = 2f

        val xAxis = chart.xAxis
        xAxis.position = XAxis.XAxisPosition.BOTTOM

        val dateFormatter = SimpleDateFormat("dd/MM")
        var lastDate = ""
        val formatter = object :  ValueFormatter() {
            override fun getFormattedValue(value: Float): String {
                val date = dateFormatter.format(Date(value.toLong()))
                if (date==lastDate){
                    return ""
                }
                lastDate = date
                return date
            }
        }
        xAxis.valueFormatter = formatter

        val yAxisRight = chart.axisRight
        yAxisRight.isEnabled = false
        val yAxisLeft = chart.axisLeft
        yAxisLeft.granularity = 1f

        val desc = Description()
        desc.text = "custom description"
        chart.description = desc

        val data = LineData(dataSet)
        chart.data = data
        chart.animateX(1000)
        chart.invalidate()
    }
msrd0
  • 7,816
  • 9
  • 47
  • 82
Beryl
  • 21
  • 5

1 Answers1

0

I don't know in kotlin but in java or for some idea you can refer to my answer in the given link- DateTime axis in MPAndroidChart

I'm attaching the code in which I've used IndexAxisValueFormatter. Also declare dev String array in your class final String dev[] = new String[100]; and use it as in below code.

for (int i = 0; i < jsonArray1.length(); i++) {
    JSONObject object1 = jsonArray1.getJSONObject(i);

    dev[i] = object1.getString("block_time");  //for xaxis needed
    XAxis bottomAxis = lineChart.getXAxis();         
    bottomAxis.setValueFormatter(new IndexAxisValueFormatter(dev));/*for x axis values*/
    bottomAxis.setLabelCount(lineEntries.size());
    bottomAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    bottomAxis.setDrawLabels(true);    //to hide all xaxis values
    bottomAxis.setDrawGridLines(false);
    bottomAxis.setDrawAxisLine(true);}
Twinkle
  • 37
  • 11