I have a MPChart and I am setting the values like this
lineChart.legend.isEnabled = false
lineChart.description.isEnabled = false
val entryList = arrayListOf<Entry>()
val sortedList = stockGraphResponse?.prices?.sortedWith(compareBy {
it?.date
})
for (i in 0 until sortedList?.size!!) {
val item = Utils.replaceCommaInNumber(sortedList[i]?.price!!).toFloat()
entryList.add(Entry(sortedList[i]?.date?.toFloat()!!, item))
}
val lineDataSet = LineDataSet(entryList,"")
lineDataSet.setDrawCircles(false)
lineDataSet.setDrawFilled(true)
val lineData = LineData(lineDataSet)
lineChart.data = lineData
lineChart.setDrawBorders(true)
val xAxis = lineChart.xAxis
xAxis.position = XAxis.XAxisPosition.BOTTOM
xAxis.setValueFormatter(CustomFormatter())
xAxis.setLabelCount(5,true)
val yAxis = lineChart.axisLeft
val yRight = lineChart.axisRight
yRight.isEnabled = false
lineChart.isAutoScaleMinMaxEnabled = true
lineChart.invalidate()
And the result is this graph
I am setting 5 for label count in xAxis and I am getting 5 labels but then the values are being plotted like that and so they are overlapping. I tried using granularity but still the same. How can I streamline this? Any help would be appreciated. Thanks
Related
Trying to implement mpandroidchart, but the graph is ending up useless because it is plotting the chart incorrectly.
Below is the snippet of how i try to implement.
fun setGraph(cdata : ArrayList<Entry>){
val lineChart: LineChart = bind.lineChartViewPage
lineChart.setExtraOffsets(0f, 40f, 0f, 40f)
lineChart.setDrawBorders(false)
lineChart.setDrawGridBackground(false)
lineChart.legend.isEnabled = false
lineChart.description.isEnabled = false
lineChart.setTouchEnabled(false)
lineChart.isDragEnabled = false
lineChart.setScaleEnabled(false)
lineChart.setPinchZoom(false)
lineChart.isAutoScaleMinMaxEnabled = false
val lds = LineDataSet(cdata, "my data")
lds.mode = LineDataSet.Mode.LINEAR
lds.setDrawCircleHole(false)
lds.setDrawCircles(false)
lds.color = Color.parseColor("#ffffff")
lds.lineWidth = 1.5f
lds.isHighlightEnabled = false
val lineDataSets: ArrayList<ILineDataSet> = ArrayList<ILineDataSet>()
lineDataSets.add(lds)
lds.setDrawValues(false)
val lineData = LineData(lineDataSets)
val ll1 = LimitLine(2.5F)
ll1.lineWidth = 2f
ll1.lineColor = Color.parseColor("#99ce7aff")
val yAxisRight: YAxis = lineChart.axisRight
yAxisRight.textColor = Color.WHITE
yAxisRight.setDrawZeroLine(false)
yAxisRight.setDrawAxisLine(false)
yAxisRight.setCenterAxisLabels(true)
yAxisRight.setDrawTopYLabelEntry(true)
yAxisRight.setDrawGridLines(false)
yAxisRight.setGranularity(1.0f)
yAxisRight.isGranularityEnabled = true
yAxisRight.setLabelCount(6, true)
yAxisRight.removeAllLimitLines()
yAxisRight.addLimitLine(ll1)
yAxisRight.axisMaximum = 3.0f
yAxisRight.axisMinimum = 0.0f
val xAxis: XAxis = lineChart.xAxis
xAxis.isEnabled = false
xAxis.valueFormatter = null
xAxis.setDrawLabels(false)
xAxis.setDrawGridLines(false)
val yAxisLeft: YAxis = lineChart.axisLeft
yAxisLeft.isEnabled = false
yAxisLeft.setDrawLabels(false)
yAxisLeft.setDrawGridLines(false)
// hide legend
val legend: Legend = lineChart.legend
legend.isEnabled = false
lineChart.data = lineData
lineChart.data.notifyDataChanged()
lineChart.notifyDataSetChanged()
lineChart.invalidate()
}
I tried out some combinations and found a different behavior if i comment out below lines :
yAxisRight.axisMaximum = 3.0f
yAxisRight.axisMinimum = 0.0f
Before commenting lines (incorrect plotting with limit line)
After commenting lines (correct plotting and limit line vanished)
Below is the dataset on which the graph is being plotted. here the max value is 0.8f and min value is 0.1f.
private fun fakeData():ArrayList<Entry>{
val al: ArrayList<Entry> = ArrayList()
al.add(Entry(1F, 0.2F))
al.add(Entry(2F, 0.4F))
al.add(Entry(3F, 0.5F))
al.add(Entry(4F, 0.6F))
al.add(Entry(5F, 0.3F))
al.add(Entry(6F, 0.4F))
al.add(Entry(7F, 0.6F))
al.add(Entry(8F, 0.7F))
al.add(Entry(9F, 0.4F))
al.add(Entry(10F, 0.1F))
al.add(Entry(11F, 0.3F))
al.add(Entry(12F, 0.3F))
al.add(Entry(13F, 0.5F))
al.add(Entry(14F, 0.6F))
al.add(Entry(15F, 0.47F))
al.add(Entry(16F, 0.55F))
al.add(Entry(17F, 0.66F))
al.add(Entry(18F, 0.45F))
al.add(Entry(19F, 0.46F))
al.add(Entry(20F, 0.33F))
al.add(Entry(21F, 0.4F))
al.add(Entry(22F, 0.36F))
al.add(Entry(23F, 0.37F))
al.add(Entry(24F, 0.46F))
al.add(Entry(25F, 0.74F))
al.add(Entry(26F, 0.76F))
al.add(Entry(27F, 0.79F))
al.add(Entry(28F, 0.8F))
return al
}
If i dont set min and max values as below; then the limit line won't show up.
yAxisRight.axisMaximum = 3.0f
yAxisRight.axisMinimum = 0.0f
chart version : com.github.PhilJay:MPAndroidChart:v3.1.0
Please let me know if there is something wrong with this implementation or possible ways to correct this.
UPDATE :
Tried multiple dataset and found that defining custom yaxis min and max value is causing the chart to be drawn incorrectly. I cant understand why?
Had the same issue and the fix is pretty easy, but not straightforward, though, you should set the same max and min values for both y-axises:
axisLeft.apply {
axisMinimum = 0.0f
axisMaximum = 3.0f
}
axisRight.apply {
axisMinimum = 0.0f
axisMaximum = 3.0f
}
I try to display some charts in my android app. I use MPAndroidChart library. But somehow my chart is always compress on the x-axis. The value seems to have all the x value 0.
In the data set this is not the case. I can not figure out what I am doing wrong.
val chart = binding.statsGraph
chart.description.isEnabled = false
chart.setDrawGridBackground(false)
chart.setDrawBarShadow(false)
chart.isHighlightFullBarEnabled = false
chart.setBackgroundColor(Color.WHITE)
chart.setDrawGridBackground(false)
chart.setDrawBarShadow(false)
chart.setHighlightFullBarEnabled(false)
// draw bars behind lines
chart.setDrawOrder(
arrayOf(
CombinedChart.DrawOrder.BAR,
CombinedChart.DrawOrder.BUBBLE,
CombinedChart.DrawOrder.CANDLE,
CombinedChart.DrawOrder.LINE,
CombinedChart.DrawOrder.SCATTER
)
)
val legend = chart.getLegend()
legend.isWordWrapEnabled = true
legend.verticalAlignment = Legend.LegendVerticalAlignment.BOTTOM
legend.horizontalAlignment = Legend.LegendHorizontalAlignment.CENTER
legend.orientation = Legend.LegendOrientation.HORIZONTAL
legend.setDrawInside(false)
val rightAxis = chart.getAxisRight()
rightAxis.setDrawGridLines(false)
rightAxis.axisMinimum = 0f // this replaces setStartAtZero(true)
val leftAxis = chart.getAxisLeft()
leftAxis.setDrawGridLines(false)
leftAxis.axisMinimum = 0f // this replaces setStartAtZero(true)
val xAxis = chart.getXAxis()
xAxis.position = XAxis.XAxisPosition.BOTH_SIDED
xAxis.axisMinimum = 0f
xAxis.granularity = 1f
class MyValueFormatter : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return value.toInt().toString()
}
}
xAxis.valueFormatter = MyValueFormatter()
val data = CombinedData()
data.setData(test())
xAxis.axisMaximum = data.xMax + 0.25f
chart.setData(data)
chart.invalidate()
You have to make sure that your layout and its parent layout has a "match_parent" width.
I'm implementing a feature for displaying Target & Actual for properties .
So, I have to display Target labels according to filter selected for example if 3 Month filter selected then need to display March , Feb & Jan but what currently labels are not displaying on XAxis.
Here is my code , please rectify any issue:
fun showOrderChart(){
try {
orderChart.description.isEnabled=false
orderChart.setMaxVisibleValueCount(60)
// scaling can now only be done on x- and y-axis separately
// scaling can now only be done on x- and y-axis separately
orderChart.setPinchZoom(true)
orderChart.setDrawBarShadow(false)
orderChart.setDrawGridBackground(false)
/* val xAxis: XAxis = orderChart.xAxis
xAxis.position = XAxisPosition.BOTTOM
xAxis.setDrawGridLines(false)*/
orderChart.axisLeft.setDrawGridLines(false)
// add a nice and smooth animation
// add a nice and smooth animation
orderChart.animateY(1500)
orderChart.legend.isEnabled = false
val xVals = ArrayList<String>()
xVals.add("Jan")
xVals.add("Feb")
xVals.add("Mar")
xVals.add("Apr")
xVals.add("May")
xVals.add("Jun")
val yVals1 = ArrayList<BarEntry>()
val yVals2 = ArrayList<BarEntry>()
yVals1.add(BarEntry(1f, 1.toFloat()))
yVals2.add(BarEntry(1f, 2.toFloat()))
yVals1.add(BarEntry(2f, 3.toFloat()))
yVals2.add(BarEntry(2f, 4.toFloat()))
yVals1.add(BarEntry(3f, 5.toFloat()))
yVals2.add(BarEntry(3f, 6.toFloat()))
yVals1.add(BarEntry(4f, 7.toFloat()))
yVals2.add(BarEntry(4f, 5.toFloat()))
yVals1.add(BarEntry(5f, 9.toFloat()))
yVals2.add(BarEntry(5f, 12.toFloat()))
yVals1.add(BarEntry(6f, 11.toFloat()))
yVals2.add(BarEntry(6f, 8.toFloat()))
val set1:BarDataSet
val set2:BarDataSet
set1 = BarDataSet(yVals1, "Target")
set1.color = Color.RED
set2 = BarDataSet(yVals2, "Actual")
set2.color = Color.BLUE
val data = BarData(set1, set2)
data.setValueFormatter(LargeValueFormatter())
orderChart.data = data
orderChart.getBarData().setBarWidth(0.3f)
orderChart.xAxis.setAxisMinimum(0f)
orderChart.getXAxis().setAxisMaximum(0 + orderChart.getBarData().getGroupWidth(0.4f, 0f) * 6)
orderChart.groupBars(0f, 0.4f, 0f)
orderChart.getData().setHighlightEnabled(false)
orderChart.invalidate()
val l = orderChart.getLegend()
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP)
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT)
l.setOrientation(Legend.LegendOrientation.VERTICAL)
l.setDrawInside(true)
l.setYOffset(20f)
l.setXOffset(0f)
l.setYEntrySpace(0f)
l.setTextSize(8f)
val xAxis = orderChart.getXAxis()
xAxis.granularity = 1f
xAxis.setGranularityEnabled(true)
xAxis.setCenterAxisLabels(true)
xAxis.setDrawGridLines(false)
xAxis.setAxisMaximum(6f)
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM)
xAxis.setValueFormatter(IndexAxisValueFormatter(xVals))
orderChart.getAxisRight().setEnabled(false)
val leftAxis = orderChart.getAxisLeft()
leftAxis.setValueFormatter(LargeValueFormatter())
leftAxis.setDrawGridLines(true)
leftAxis.setSpaceTop(35f)
leftAxis.setAxisMinimum(0f)
}catch (e: Exception){
e.printStackTrace()
}
}
you need code for label. like this.
YAxis yAxisRight = lineChart.getAxisRight(); //set right of Y
yAxisRight.setDrawLabels(true);
My MPAndroidChart displays a stronger line to represent the middle of the graph. How do I avoid that please?
Here is what I have at the moment:
private fun addChart(totals: Totals) {
chart1.apply {
isDragEnabled = true
isScaleXEnabled = false
isScaleYEnabled = true
axisRight.isEnabled = false
axisLeft.setDrawAxisLine(false)
xAxis.isEnabled = false
legend.isEnabled = false
description.text = ""
setTouchEnabled(false)
}
val y: YAxis = chart1.axisLeft
y.axisMaximum = 800f
y.axisMinimum = 0f
y.labelCount = 5
val yValues = ArrayList<Entry>()
for ((index, i) in totals.features!!.withIndex()) {
yValues.add(Entry(index.toFloat(), i.attributes?.confirmedCovidCases!!.toFloat()))
}
val set1 = LineDataSet(yValues, "Data set 1")
set1.color = resources.getColor(R.color.orange)
set1.setDrawCircles(false)
val dataSets = ArrayList<ILineDataSet>()
dataSets.add(set1)
val data = LineData(dataSets)
chart1.data = data
}
Thank you very much.
I try to recreate your chart but did not have the problem
Try to run it on device, because it might your PC/simulator pixel bleeding
I'm using MPAndroidChart in my android application but the x-axis is wrong formatted and label are duplicated. Here my code
private fun lineChart(exams: List<Exam>) {
val formatter: DateFormat = SimpleDateFormat("dd/MM/yyyy")
val lineChart: LineChart = linechart
lineChart.animateY(1000)
val d = Description()
d.text = "TEST"
lineChart.description = d
val yValues: ArrayList<Entry> = ArrayList()
var count = 0
for (exam in exams.sortedByDescending { exam -> exam.date }) {
if (getString(R.string.scores_array_admitted) != exam.score)
yValues.add(Entry(count++.toFloat(), exam.score.toFloat()))
}
val lineDataSet = LineDataSet(yValues, getString(R.string.linechart_score_label))
val dataSet: ArrayList<ILineDataSet> = ArrayList()
dataSet.add(lineDataSet)
val lineData = LineData(dataSet)
val xAxis: XAxis = lineChart.xAxis
val values = ArrayList<String>()
for (exam in exams.sortedByDescending { exam -> exam.date }) {
if (getString(R.string.scores_array_admitted) != exam.score)
values.add(formatter.format(exam.date))
}
val array = arrayOfNulls<String>(values.size)
values.toArray(array)
var aa = array!!
xAxis.valueFormatter = MyAxisValueFormatter(aa)
lineChart.data = lineData
}
In debug I see that the value in the arrays are correct, 2 exams and in values array the label are the two date of the exam and they are exactly two, but when I run my application the result is this
In x axis I would have only two date