I want to show the Min and Max value on the line chart i am using the library MPChart Android library.
I want to show min max as like this.
My Code for the Line chart
val lineDataSet = LineDataSet(values, "")
lineDataSet.lineWidth = 2f
lineDataSet.setDrawValues(true)
lineDataSet.setDrawFilled(true)
// lineDataSet.fillAlpha = 85
lineDataSet.setDrawCircles(false)
// lineDataSet.setCircleColor(Color.BLACK)
lineDataSet.color = resources.getColor(R.color.green)
// lineDataSet.fillColor = resources.getColor(R.color.colorPrimary)
lineDataSet.highLightColor = resources.getColor(R.color.coral);
val elevationMarker = ChartMarkerView2(activity)
binding!!.chart.markerView = elevationMarker
lineDataSet.setDrawHighlightIndicators(true)
lineDataSet.setDrawHorizontalHighlightIndicator(false)
lineDataSet.setDrawCircleHole(true)
lineDataSet.circleHoleRadius = 5f
lineDataSet.setCircleColor(
resources.getColor(R.color.green)
)
val drawable = ContextCompat.getDrawable(requireContext(), R.drawable.fade_graph_bg)
lineDataSet.fillDrawable = drawable
lineDataSet.axisDependency = YAxis.AxisDependency.LEFT
// lineDataSet.cubicIntensity = 0f
// lineDataSet.mode = LineDataSet.Mode.HORIZONTAL_BEZIER;
val dataSets = ArrayList<ILineDataSet>()
dataSets.add(lineDataSet) // add the datasets
// create a data object with the datasets
val data = LineData(dataSets)
// data.setDrawValues(false)
// set data
binding!!.chart.data = data
// binding!!.chart.animateX(100)
binding!!.chart.invalidate()
you can get Max- Min your Dataset and in ValueFormatter Modify your value like this :
val numArr1 = intArrayOf(10000, 10100, 12200,12700, 9036, 11200, 10200)
val max = numArr1.maxOrNull() ?: 0
val min = numArr1.minOrNull() ?: 0
valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
if (value == min.toFloat() || value == max.toFloat())
{
return "$value $"
}
return ""
}
}
Here is the code snippet to set minimum and maximum value in Linechart using MPAndroidChart library.
val chartEntities: ArrayList<Entry> = ArrayList()
val values = Array(5) {0f}
values[0] = 5f
values[1] = 2.2f
values[2] = 7.2f
values[3] = 9.5f
values[4] = 4.5f
values[5] = 6.4f
var i = 0
for (entry in values) {
var value = values[i]
chartEntities.add(Entry(i.toFloat(), value))
i++
}
val lineDataSet = LineDataSet(chartEntities, "")
val max = values.maxOrNull() ?: 0
val min = values.minOrNull() ?: 0
val valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
if (value == min.toFloat() || value == max.toFloat())
{
return "$value"
}
return ""
}
}
lineDataSet.valueFormatter = valueFormatter
lineDataSet.setDrawValues(true)
With this sample snippet you can set minimum and maximum values in linechart using MPAndroidChart.
Create float array of items to display in the line chart
find out minimum and maximum values from the arraylist.
create ValueFormatter and set values there.
set valueFormatter property to lineDataSet
set setDrawValues(true) in lineDataSet
Hope this helps. Happy coding.
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:
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()
}
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);}
I have a code to display a data in a line graph and I need to change the xAxis to date but the log have a error
java.lang.NumberFormatException: For input string: "2019-04-19 00:00:00"
Below is my code snippet for line graph
mLineChart = findViewById(R.id.chart)
importData()
val dataSet = LineDataSet(entries, "Water")
val lineData = LineData(dataSet)
mLineChart.axisRight.isEnabled = false
mLineChart.data = lineData
dataSet.color = Color.RED
dataSet.setDrawCircles(false)
dataSet.setDrawValues(false)
dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER
mLineChart.description.text = ""
mLineChart.legend.isEnabled = false
mLineChart.invalidate()
val leftAxis = mLineChart.axisLeft
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART)
leftAxis.axisMinimum = 0f
leftAxis.axisMaximum = 30f
val rightAxis = mLineChart.axisRight
rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART)
rightAxis.axisMinimum = 0f
rightAxis.axisMaximum = 30f
var xAxis = mLineChart.xAxis
xAxis.position = XAxis.XAxisPosition.BOTTOM
xAxis.setDrawGridLines(false)
xAxis.axisMinimum = 0f
xAxis.labelCount = 5
xAxis.axisMaximum = 400f
xAxis.granularity = 1f
xAxis.isGranularityEnabled = true
xAxis.valueFormatter = DateAxisValueFormatter(null)
Below is my code snippet for inserting data
private fun importData() {
for (data in dataList) {
val date = java.lang.Float.parseFloat(data.date)
val water = java.lang.Float.parseFloat(data.water)
entries.add(Entry(date, water))
}
Below is my code snippet for value formatter
internal inner class DateAxisValueFormatter(private val mValues: Array<String>?) : ValueFormatter(),
IAxisValueFormatter {
var sdf = SimpleDateFormat("hh:mm", Locale.ENGLISH)
override fun getFormattedValue(value: Float, axis: AxisBase?): String {
return sdf.format(Date(value.toLong()))
}
}
Your exception is clear, you're trying to convert a string into Float, but this string is not a Number.
If you want to display a date, you have to format your date in milliseconds before.
Try something like that:
private fun importData() {
val dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)
for (data in dataList) {
val date = dateFormatter.parse(data.date)
val water = java.lang.Float.parseFloat(data.water)
//Here you get your date as a Long and you convert it in Float
entries.add(Entry(date.time.toFloat(), water))
}
EDIT:
In your xAxis set your own valueFormatter this way to convert your float back in date:
val x = chart.xAxis
x.setValueFormatter { value, _ ->
SimpleDateFormat("HH:mm:ss", Locale.ENGLISH).format(value.toLong())
}