I am using MP chart in my project. I am using multiple dataset bar chart. I ma facing following issues:
I want to provide some space between legend and x-axis. Right now it is sticked with the axis. I check the documentation but didn't found any method for setting margin between axis and legend. (Attached screenshot - Highlighted as Issue 1)
The chart is showing an empty group in the beginning, which I want to remove.(Attached screenshot - Highlighted as Issue 2)
Below is my code:
tco_chart?.description?.isEnabled = false
tco_chart?.setPinchZoom(false)
tco_chart?.setDrawBarShadow(false)
val leftYAxis = tco_chart?.axisLeft
leftYAxis?.setDrawGridLines(false)
leftYAxis?.axisMinimum = 0f
tco_chart?.setDrawGridBackground(false)
val mv = MyMarkerView(this, R.layout.custom_marker_view)
mv.setChartView(tco_chart) // For bounds control
tco_chart.setMarker(mv)
val legend = tco_chart?.legend
legend?.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM)
legend?.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT)
legend?.setOrientation(Legend.LegendOrientation.HORIZONTAL)
legend?.setYOffset(0f)
legend?.setXOffset(10f)
legend?.setYEntrySpace(0f)
legend?.setTextSize(5f)
val axisLabels = ArrayList<String>()
axisLabels.add("Year 1")
axisLabels.add("Year 2")
axisLabels.add("Year 3")
axisLabels.add("Year 4")
axisLabels.add("Year 5")
val xAxis = tco_chart?.xAxis
xAxis?.granularity = 1f
xAxis?.position = XAxis.XAxisPosition.BOTTOM
xAxis?.setCenterAxisLabels(true)
xAxis?.setDrawLabels(true)
xAxis?.valueFormatter = IndexAxisValueFormatter(axisLabels)
val insuranceCostEntry = ArrayList<BarEntry>()
val insuranceCostDataModel = tcoResultModel.insurance_cost
if (insuranceCostDataModel != null) {
insuranceCostEntry.add(BarEntry(0f, insuranceCostDataModel.first_year.toFloat()))
insuranceCostEntry.add(BarEntry(1f, insuranceCostDataModel.second_year.toFloat()))
insuranceCostEntry.add(BarEntry(2f, insuranceCostDataModel.third_year.toFloat()))
insuranceCostEntry.add(BarEntry(3f, insuranceCostDataModel.fourth_year.toFloat()))
insuranceCostEntry.add(BarEntry(4f, insuranceCostDataModel.fifth_year.toFloat()))
}
val fuelCostEntry = ArrayList<BarEntry>()
val fuelCostDataModel = tcoResultModel.fuel_cost
if (fuelCostDataModel != null) {
fuelCostEntry.add(BarEntry(0f, fuelCostDataModel.first_year.toFloat()))
fuelCostEntry.add(BarEntry(1f, fuelCostDataModel.second_year.toFloat()))
fuelCostEntry.add(BarEntry(2f, fuelCostDataModel.third_year.toFloat()))
fuelCostEntry.add(BarEntry(3f, fuelCostDataModel.fourth_year.toFloat()))
fuelCostEntry.add(BarEntry(4f, fuelCostDataModel.fifth_year.toFloat()))
}
val serviceCostEntry = ArrayList<BarEntry>()
val serviceCostDataModel = tcoResultModel.service_cost
if (serviceCostDataModel != null) {
serviceCostEntry.add(BarEntry(0f, serviceCostDataModel.first_year.toFloat()))
serviceCostEntry.add(BarEntry(1f, serviceCostDataModel.second_year.toFloat()))
serviceCostEntry.add(BarEntry(2f, serviceCostDataModel.third_year.toFloat()))
serviceCostEntry.add(BarEntry(3f, serviceCostDataModel.fourth_year.toFloat()))
serviceCostEntry.add(BarEntry(4f, serviceCostDataModel.fifth_year.toFloat()))
}
val tyreChangeCostEntry = ArrayList<BarEntry>()
val tyreChangeCostDataModel = tcoResultModel.tyre_change_cost
if (tyreChangeCostDataModel != null) {
tyreChangeCostEntry.add(BarEntry(0f, tyreChangeCostDataModel.first_year.toFloat()))
tyreChangeCostEntry.add(BarEntry(1f, tyreChangeCostDataModel.second_year.toFloat()))
tyreChangeCostEntry.add(BarEntry(2f, tyreChangeCostDataModel.third_year.toFloat()))
tyreChangeCostEntry.add(BarEntry(3f, tyreChangeCostDataModel.fourth_year.toFloat()))
tyreChangeCostEntry.add(BarEntry(4f, tyreChangeCostDataModel.fifth_year.toFloat()))
}
val depreciationCostEntry = ArrayList<BarEntry>()
val depriciationCostDataModel = tcoResultModel.depreciation_cost
if (depriciationCostDataModel != null) {
depreciationCostEntry.add(BarEntry(0f, depriciationCostDataModel.first_year.toFloat()))
depreciationCostEntry.add(BarEntry(1f, depriciationCostDataModel.second_year.toFloat()))
depreciationCostEntry.add(BarEntry(2f, depriciationCostDataModel.third_year.toFloat()))
depreciationCostEntry.add(BarEntry(3f, depriciationCostDataModel.fourth_year.toFloat()))
depreciationCostEntry.add(BarEntry(4f, depriciationCostDataModel.fifth_year.toFloat()))
}
val year1Set: BarDataSet
val year2Set: BarDataSet
val year3Set: BarDataSet
val year4Set: BarDataSet
val year5Set: BarDataSet
var data = tco_chart?.data
if (data != null) {
if (data.dataSetCount > 0) {
year1Set = data.getDataSetByIndex(0) as BarDataSet
year1Set.values = insuranceCostEntry
year2Set = data.getDataSetByIndex(1) as BarDataSet
year2Set.values = fuelCostEntry
year3Set = data.getDataSetByIndex(2) as BarDataSet
year3Set.values = tyreChangeCostEntry
year4Set = data.getDataSetByIndex(3) as BarDataSet
year4Set.values = serviceCostEntry
year5Set = data.getDataSetByIndex(4) as BarDataSet
year5Set.values = depreciationCostEntry
data.notifyDataChanged()
tco_chart?.notifyDataSetChanged()
}
} else {
year1Set = BarDataSet(insuranceCostEntry, "Insurance Cost")
year1Set.color = Color.rgb(232, 128, 44)
year2Set = BarDataSet(fuelCostEntry, "Fuel Cost")
year2Set.color = Color.rgb(232, 199, 44)
year3Set = BarDataSet(tyreChangeCostEntry, "Tyre Change Cost")
year3Set.color = Color.rgb(10, 149, 221)
year4Set = BarDataSet(serviceCostEntry, "Service Cost")
year4Set.color = Color.rgb(47, 194, 144)
year5Set = BarDataSet(depreciationCostEntry, "Depriciation Cost")
year5Set.color = Color.rgb(105, 123, 192)
data = BarData(year1Set, year2Set, year3Set, year4Set, year5Set)
data.setValueFormatter(IndexAxisValueFormatter())
tco_chart?.data = data
}
val rightYAxis = tco_chart?.axisRight
rightYAxis?.isEnabled = false
tco_chart?.getBarData()?.setBarWidth(0.1f)
tco_chart?.xAxis?.axisMaximum = (0 + data.getGroupWidth(0.4f, 0.02f) * 5)
tco_chart?.groupBars(0f, 0.4f, 0.02f)
tco_chart?.invalidate()
I had the same issue, you can fix it with use some additional padding for chart.
Use this:
chart.setExtraOffsets(5f,5f,5f,15f)
Hope it helps.
You Give Offset to Legend Like ..
val legend = chart.legend
legend.xOffset = 10f
Related
what I want to achieve
what I have
I want to show icons on the xAxis above time but line chart takes icon and places them on the value where temperature is shown. I have searched a lot but could not find the answer. Any help would be appreciated. I have tried a lot of things but all in vein.
private fun setTempChart(hour: ArrayList<Hour>, id: String) {
val entries: MutableList<Entry> = ArrayList()
for (i in hour.indices) {
val code = hour[i].condition.code
val icon =
if (hour[i].is_day == 1) requireActivity().setIconDay(code) else requireActivity().setIconNight(
code
)
entries.add(Entry(i.toFloat(), sharedPreference.temp?.let {
hour[i].temp_c.setCurrentTemperature(
it
).toFloat()
}!!))
}
val dataSet = LineDataSet(entries, "")
dataSet.apply {
lineWidth = 0f
setDrawCircles(false)
setDrawCircleHole(false)
isHighlightEnabled = false
valueTextColor = Color.WHITE
setColors(Color.WHITE)
valueTextSize = 12f
mode = LineDataSet.Mode.CUBIC_BEZIER
setDrawFilled(true)
fillColor = Color.WHITE
valueTypeface = typeface
isDrawIconsEnabled
setDrawIcons(true)
valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return String.format(Locale.getDefault(), "%.0f", value)
}
}
}
val lineData = LineData(dataSet)
chart.apply {
description.isEnabled = false
axisLeft.setDrawLabels(false)
axisRight.setDrawLabels(false)
legend.isEnabled = false
axisLeft.setDrawGridLines(false)
axisRight.setDrawGridLines(false)
axisLeft.setDrawAxisLine(false)
axisRight.setDrawAxisLine(false)
setScaleEnabled(false)
data = lineData
setVisibleXRange(8f, 8f)
animateY(1000)
xAxis.apply {
setDrawAxisLine(false)
textColor = Color.WHITE
setDrawGridLines(false)
setDrawLabels(true)
position = XAxis.XAxisPosition.BOTTOM
textSize = 12f
valueFormatter = MyAxisFormatter(hour, id)
isGranularityEnabled = true
granularity = 1f
labelCount = entries.size
}
}
}
I am using MPAndroidChart library
There isn't a nice built-in way to draw icons like that, but you can do it by making a custom extension of the LineChartRenderer and overriding drawExtras. Then you can get your icons from R.drawable.X and draw them on the canvas wherever you want. There is some work to figure out where to put them to line up with the data points, but you can copy the logic from drawCircles to find that.
Example Custom Renderer
inner class MyRenderer(private val context: Context,
private val iconY: Float,
private val iconSizeDp: Float,
chart: LineDataProvider,
animator: ChartAnimator,
viewPortHandler: ViewPortHandler)
: LineChartRenderer(chart, animator, viewPortHandler) {
private var buffer: FloatArray = listOf(0f,0f).toFloatArray()
override fun drawExtras(c: Canvas) {
super.drawExtras(c)
val iconSizePx = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
iconSizeDp,
resources.displayMetrics
)
// get the icons you want to draw
val cloudy = ContextCompat.getDrawable(context, R.drawable.cloudy)
val sunny = ContextCompat.getDrawable(context, R.drawable.sunny)
if( cloudy == null || sunny == null ) {
throw RuntimeException("Missing drawables")
}
// Determine icon width in pixels
val w = iconSizePx
val h = iconSizePx
val dataSets = mChart.lineData.dataSets
val phaseY = mAnimator.phaseY
for(dataSet in dataSets) {
mXBounds.set(mChart, dataSet)
val boundsRange = mXBounds.range + mXBounds.min
val transformer = mChart.getTransformer(dataSet.axisDependency)
for(j in mXBounds.min .. boundsRange) {
val e = dataSet.getEntryForIndex(j) ?: break
buffer[0] = e.x
buffer[1] = iconY * phaseY
transformer.pointValuesToPixel(buffer)
if( !mViewPortHandler.isInBoundsRight(buffer[0])) {
break
}
if( !mViewPortHandler.isInBoundsLeft(buffer[0]) ||
!mViewPortHandler.isInBoundsY(buffer[1])) {
continue
}
// Draw the icon centered under the data point, but at a fixed
// vertical position. Here the icon "sits on top" of the
// specified iconY value
val left = (buffer[0]-w/2).roundToInt()
val right = (buffer[0]+w/2).roundToInt()
val top = (buffer[1]-h).roundToInt()
val bottom = (buffer[1]).roundToInt()
// Alternately, use this to center the icon at the
// "iconY" value
//val top = (buffer[1]-h/2).roundToInt()
//val bottom = (buffer[1]+h/2).roundToInt()
// Use whatever logic you want to select which icon
// to use at each position
val icon = if( e.y > 68f ) {
sunny
}
else {
cloudy
}
icon.setBounds(left, top, right, bottom)
icon.draw(c)
}
}
}
}
Using the Custom Renderer
val iconY = 41f
val iconSizeDp = 40f
chart.renderer = MyRenderer(this, iconY, iconSizeDp,
chart, chart.animator, chart.viewPortHandler)
(other formatting)
val chart = findViewById<LineChart>(R.id.chart)
chart.axisRight.isEnabled = false
val yAx = chart.axisLeft
yAx.setDrawLabels(false)
yAx.setDrawGridLines(false)
yAx.setDrawAxisLine(false)
yAx.axisMinimum = 40f
yAx.axisMaximum = 80f
val xAx = chart.xAxis
xAx.setDrawLabels(false)
xAx.position = XAxis.XAxisPosition.BOTTOM
xAx.setDrawGridLines(false)
xAx.setDrawAxisLine(false)
xAx.axisMinimum = 0.5f
xAx.axisMaximum = 5.5f
xAx.granularity = 0.5f
val x = listOf(0,1,2,3,4,5,6)
val y = listOf(60,65,66,70,65,50,55)
val e = x.zip(y).map { Entry(it.first.toFloat(), it.second.toFloat())}
val line = LineDataSet(e, "temp")
line.setDrawValues(true)
line.setDrawCircles(false)
line.circleRadius = 20f // makes the text offset up
line.valueTextSize = 20f
line.color = Color.BLACK
line.lineWidth = 2f
line.setDrawFilled(true)
line.fillColor = Color.BLACK
line.fillAlpha = 50
line.mode = LineDataSet.Mode.CUBIC_BEZIER
line.valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return "%.0f F".format(value)
}
}
chart.data = LineData(line)
chart.description.isEnabled = false
chart.legend.isEnabled = false
Gives the desired effect
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 having a problem with aligning xAxis labels with actual bars.
I'm using MPChart for Android.
Here's an image of how it looks like:
As you can see, xAxis label is out of place. There should be one value under each group of bars.
I tried to fix it with
My code in Kotlin:
fun populateGraphData() {
var barChartView = findViewById<BarChart>(R.id.chartConsumptionGraph)
val barWidth: Float
val barSpace: Float
val groupSpace: Float
barWidth = 0.45f
barSpace = 0.1f
groupSpace = 0.56f
var titleobject = AvsF_response_year()
var xAxisValues = ArrayList<String>()
var yValueGroup1 = ArrayList<BarEntry>()
var yValueGroup2 = ArrayList<BarEntry>()
var barDataSet1: BarDataSet
var barDataSet2: BarDataSet
var i=1
for(value in avsfDateResponseList){
xAxisValues.add(value.dateTimeUTC)
yValueGroup1.add(BarEntry(i.toFloat(),value.dayAheadTotalLoadForecastValue.toFloat()))
yValueGroup2.add(BarEntry(i.toFloat(),value.actualTotalLoadValue.toFloat()))
i=i+1
}
barDataSet1 = BarDataSet(yValueGroup1, "")
barDataSet1.setColors(Color.CYAN, Color.CYAN)
barDataSet1.label = "DAY AHEAD TOTAL LOAD FORECAST"
barDataSet1.setDrawIcons(false)
barDataSet1.setDrawValues(false)
barDataSet2 = BarDataSet(yValueGroup2, "")
barDataSet2.label = "ACTUAL TOTAL LOAD"
barDataSet2.setColors(Color.BLUE, Color.BLUE)
barDataSet2.setDrawIcons(false)
barDataSet2.setDrawValues(false)
var barData = BarData(barDataSet1, barDataSet2)
barChartView.description.text = "entso-e"
barChartView.description.isEnabled = true
barChartView.description.textSize = 3f
barData.setValueFormatter(LargeValueFormatter())
barChartView.setData(barData)
barChartView.getBarData().setBarWidth(barWidth)
barChartView.getXAxis().setAxisMinimum(0f)
val size = avsfDateResponseList.size.toFloat() +avsfDateResponseList.size.toFloat()
barChartView.getXAxis().setAxisMaximum(size)
barChartView.groupBars(0f, groupSpace, barSpace)
barChartView.setFitBars(true)
barChartView.getData().setHighlightEnabled(true)
var legend = barChartView.legend
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM)
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT)
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL)
legend.setDrawInside(false)
var legenedEntries = arrayListOf<LegendEntry>()
legenedEntries.add(LegendEntry("DAY AHEAD TOTAL LOAD FORECAST", Legend.LegendForm.SQUARE, 8f, 8f, null, Color.CYAN))
legenedEntries.add(LegendEntry("ACTUAL TOTAL LOAD", Legend.LegendForm.SQUARE, 8f, 8f, null, Color.BLUE))
legend.setCustom(legenedEntries)
legend.setYOffset(2f)
legend.setXOffset(2f)
legend.setYEntrySpace(0f)
legend.setTextSize(9f)
val xAxis = barChartView.getXAxis()
xAxis.setGranularity(1f)
xAxis.setGranularityEnabled(true)
xAxis.setCenterAxisLabels(true)
xAxis.setDrawGridLines(false)
xAxis.labelRotationAngle = 60F
xAxis.textSize = 10f
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM)
xAxis.setValueFormatter(IndexAxisValueFormatter(xAxisValues))
xAxis.setCenterAxisLabels(true)
xAxis.setLabelCount(avsfDateResponseList.size.toInt())
xAxis.setCenterAxisLabels(true)
xAxis.setAvoidFirstLastClipping(true)
barChartView.setDragEnabled(true)
barChartView.getAxisRight().setEnabled(false)
barChartView.setScaleEnabled(true)
val leftAxis = barChartView.getAxisLeft()
leftAxis.setValueFormatter(LargeValueFormatter())
leftAxis.setDrawGridLines(false)
leftAxis.setSpaceTop(1f)
leftAxis.setAxisMinimum(0f)
barChartView.data = barData
barChartView.setVisibleXRange(1f, 18f)
}
I've tried deleting and adding each one of these lines and nothing seems to be working right.
Can someone help me?
I want to set the negative values of the bars to the left of the bars but at present some of the bars are overlapping these values.
How can i remove this overlapping of the negative values and if i set horizonatal_chart.setDrawValueAboveBar(true) then the positive bar will overlap the positive values.
Here's the code:
private fun filterHorizontalBarData(myList: List<Response>?) {
try {
val brand = ArrayList<String>()
var index = 0f
var color_index = 0
val data = BarData()
val values_adapter = ArrayList<String>()
for (item in myList!!) {
if (item.kPI.equals("Value % Growth") || item.kPI.equals("Volume % Growth")) {
val kpiValue = ArrayList<BarEntry>()
kpiValue.add(BarEntry(index,item.kPIvalue.toFloat()))
brand.add(item.brand)
values_adapter.add(item.kPIvalue.toString())
val barDataSet = BarDataSet(kpiValue, item.brand)
if(color_index<7)
barDataSet.setColor(getColor(horizonatal_chart.context, getColorID(color_index)))
else
barDataSet.setColor(getColorID(color_index))
barDataSet.valueTextSize = 8f
// barDataSet.setDrawValues(false)
data.addDataSet(barDataSet)
index++
color_index++
}
}
// values_adapter.sortDescending()
// first_bar_values.adapter = AdapterValuesHorizontalBar(values_adapter)
setHorizontalChart(data, brand)
}catch (e: Exception){
e.printStackTrace()
}
}
private fun setHorizontalChart(data : BarData, brand: ArrayList<String>){
horizonatal_chart.setDrawBarShadow(false)
val description = Description()
description.text = ""
horizonatal_chart.description = description
horizonatal_chart.legend.setEnabled(false)
horizonatal_chart.setPinchZoom(false)
horizonatal_chart.setScaleEnabled(false)
horizonatal_chart.setDrawValueAboveBar(true)
//Display the axis on the left (contains the labels 1*, 2* and so on)
val xAxis = horizonatal_chart.getXAxis()
xAxis.setDrawGridLines(false)
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM)
xAxis.setEnabled(true)
xAxis.setDrawAxisLine(false)
xAxis.textColor = Color.parseColor("#a1a1a1")
xAxis.xOffset = 5f
val yLeft = horizonatal_chart.axisLeft
//Set the minimum and maximum bar lengths as per the values that they represent
yLeft.axisMaximum = 100f
yLeft.axisMinimum = 0f
yLeft.isEnabled = false
yLeft.setDrawZeroLine(true)
yLeft.granularity = 1f
//Now add the labels to be added on the vertical axis
xAxis.valueFormatter = IAxisValueFormatter { value, axis ->
if (value.toInt() < brand.size) {
brand.get(value.toInt())
} else {
"0"
}
}
val yRight = horizonatal_chart.axisRight
yRight.setDrawAxisLine(true)
yRight.setDrawGridLines(false)
yRight.isEnabled = false
//Set bar entries and add necessary formatting
horizonatal_chart.axisLeft.setAxisMinimum(data.yMin)
data.barWidth = 0.9f
// val myCustomChartRender = MyCustomChartRender(horizonatal_chart, horizonatal_chart.animator, horizonatal_chart.viewPortHandler)
// //Add animation to the graph
// horizonatal_chart.renderer = myCustomChartRender
horizonatal_chart.animateY(2000)
horizonatal_chart.data = data
horizonatal_chart.setTouchEnabled(false)
horizonatal_chart.invalidate()
}
Please help me !
The problem seems that you've not provided minimum and maximum cap for rightAxis.
horizonatal_chart.axisRight.setAxisMinimum(-100)
horizonatal_chart.axisRight.setAxisMaximum(100)
Reference : The same issue is mentioned at issue and was solved by providing axis minimum and maximum
Line Graph
I have 5 dynamic data which is giving +1 or -1 as result, if the result is +1 then graph direction is towards up and if the result is -1 then graph direction is towards downward.
Image in your question is not available to view but i can put a sample for how to draw a line chart in your android app easily.
First -as mentioned in comment- you can use MPAndroidChart. You can add it to your project like following:
implementation "com.github.PhilJay:MPAndroidChart:v3.0.3"
Here's a sample default line chart implementation which i use in my personal projects.
open class DefaultLineChart #JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
: LineChart(context, attrs, defStyle) {
init {
setupChart()
}
private fun setupChart() {
// Init Description
val description = Description().apply {
isEnabled = false
}
setDescription(description)
// Init GridBackground
setGridBackgroundColor(android.R.color.white)
setDrawGridBackground(true)
// Init Borders
setDrawBorders(true)
setBorderColor(android.R.color.black)
setBorderWidth(1f)
// Init Other Properties
setPinchZoom(false)
isDoubleTapToZoomEnabled = false
isDragEnabled = true
setNoDataText(context.getString(R.string.info_text_no_content))
setScaleEnabled(true)
// Init Legend
val legend = legend.apply {
isEnabled = false
}
// Init xAxis
val xAxis = xAxis.apply {
isEnabled = true
setCenterAxisLabels(false)
gridColor = android.R.color.white
setAvoidFirstLastClipping(false)
setDrawLimitLinesBehindData(true)
position = XAxis.XAxisPosition.BOTTOM
}
// Init leftAxis
val leftAxis = axisLeft.apply {
axisMinimum = 0f
setDrawAxisLine(false)
setDrawZeroLine(true)
setDrawGridLines(true)
gridColor = android.R.color.black
axisLineColor = android.R.color.black
}
val rightAxis = axisRight.apply {
isEnabled = false
}
}
fun setChartTitle(title: String) {
val description = Description().apply {
text = title
isEnabled = true
}
setDescription(description)
}
}
You can add it to your xml layout like below:
<path_to_your_class.DefaultLineChart
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_marginTop="16dp"/>
Finally you can draw your chart like following code:
fun bindDefaultLineChart(chartView: LineChart,
marketValues: List<MarketVal>?,
label: String?) {
if (marketValues == null) {
return
}
val yValues = ArrayList<Entry>()
var maxCount: Long = 0
for (marketValue in marketValues) {
val entry = Entry(marketValue.dateTime.toFloat(),
marketValue.transactionNumber.toFloat())
yValues.add(entry)
if (marketValue.transactionNumber > maxCount) {
maxCount = marketValue.transactionNumber.toLong()
}
}
val xAxis = chartView.xAxis
val xAxisFormatter = ChartValueDateFormatter(Constants.DEFAULT_DATE_FORMAT)
xAxis.valueFormatter = xAxisFormatter
chartView.axisLeft.apply {
axisMaximum = (maxCount + MAX_CHAR_Y_AXIS_ADDITION).toFloat()
valueFormatter = NonFloatValueFormatter()
}
val dataSet = LineDataSet(yValues, label).apply {
axisDependency = YAxis.AxisDependency.LEFT
color = ContextCompat.getColor(chartView.context, R.color.colorAccent)
formLineWidth = 2f
setDrawIcons(true)
setDrawValues(false)
}
val lineData = LineData(dataSet)
chartView.data = lineData
}
}
You can find example implementation from here.