最近使用MPAndroidChart中的直方图来展示数据,记录下大致的实现过程,点击这里可跳转至官方文档
1 引入MPAndroidChart
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
2 添加到布局中
直方图是BarChart这个类
<com.github.mikephil.charting.charts.BarChart
android:id="@+id/bc"
android:layout_width="match_parent"
android:layout_height="182dp" />
3 表格设置
3.1 表格基本设置
//背景颜色
binding.bc.setBackgroundColor(Color.WHITE)
//不显示图表网格
binding.bc.setDrawGridBackground(false)
//背景阴影
binding.bc.setDrawBarShadow(false)
binding.bc.isHighlightFullBarEnabled = false
//不显示边框
binding.bc.setDrawBorders(false)
//设置动画
binding.bc.animateY(1000,Easing.Linear)
binding.bc.animateX(1000,Easing.Linear)
//禁止所有事件
binding.bc.setTouchEnabled(false)
3.2 设置x轴
private fun setXAxis(labels: List<DataForTrend>){
//x轴,显示在底部
val xAxis = binding.bc.xAxis
xAxis.position = XAxis.XAxisPosition.BOTTOM
xAxis.granularity = 0f
//不显示x轴
xAxis.setDrawAxisLine(false)
xAxis.setDrawGridLines(false)
//x轴下的label顺时针旋转45度
xAxis.labelRotationAngle = -45f
//x轴间距
xAxis.granularity = 1f
//自定义标签
val formatter = MyXAxisValueFormatter(labels)
binding.bc.xAxis.valueFormatter = formatter
//横坐标标签数量
xAxis.labelCount = labels.size
}
//自定义x轴显示值
class MyXAxisValueFormatter(private val labels: List<DataForTrend>,private val isYear: Boolean): IndexAxisValueFormatter(){
override fun getFormattedValue(value: Float): String {
var index = value.toInt()
if (index < 0) index = 0
var time = ""
if (index < labels.size){
time = labels[index].statisticTime
}
return time
}
}
3.3 设置y轴
private fun setYAxis(labels: List<DataForTrend>){
//左边的y轴
val yAxis = binding.bc.axisLeft
//右边的y轴
val yRAxis = binding.bc.axisRight
//y轴从0开始
yAxis.axisMinimum = 0f
yRAxis.isEnabled =false
//不显示y轴
yAxis.setDrawAxisLine(false)
yRAxis.setDrawAxisLine(false)
yRAxis.setDrawGridLines(false)
//y轴上水平横线,这里设置成虚线
yAxis.enableGridDashedLine(10f,10f,0f)
}
3.4 标签设置
private fun setLabel(labels: List<DataForTrend>){
val legend = binding.bc.legend
legend.form = Legend.LegendForm.EMPTY
legend.textSize = 12f
//显示位置
legend.verticalAlignment = Legend.LegendVerticalAlignment.BOTTOM
legend.horizontalAlignment = Legend.LegendHorizontalAlignment.LEFT
legend.orientation = Legend.LegendOrientation.HORIZONTAL
//是否绘制在图表里
legend.setDrawInside(false)
//不显示右下角描述内容
val description = Description()
description.isEnabled = false
binding.bc.description = description
}
4 添加数据
4.1 将我们自己的数据转为BarEntry
4.2 将BarEntry集合转为BarDataSet
4.3 设置直方图的颜色,线宽等
4.4 将BarDataSet转为BarData
4.5 将BarData设置给BarChart
val labels = arrayListOf<DataForTrend>()
labels.add(DataForTrend("07-10",49))
labels.add(DataForTrend("07-11",72))
labels.add(DataForTrend("07-12",0))
labels.add(DataForTrend("07-13",0))
labels.add(DataForTrend("07-14",0))
labels.add(DataForTrend("07-15",0))
labels.add(DataForTrend("07-16",0))
val barentrys = arrayListOf<BarEntry>()
labels.forEachIndexed { index, ele ->
val barEntry = BarEntry(index.toFloat(),ele.orderAmount.toFloat())
barentrys.add(barEntry)
}
val barDataSet = BarDataSet(barentrys,"")
initBarDataSet(barDataSet,Color.parseColor("#FF44B549"))
val barData = BarData(barDataSet)
//设置成1f,直方图会埃在一起,这样会隔开
barData.barWidth = 0.5f
binding.bc.data = barData
private fun initBarDataSet(set: BarDataSet,color: Int){
set.color = color
//线宽
set.formLineWidth = 1f
set.formSize = 14f
//不显示柱状图顶部值
set.setDrawValues(false)
}
效果如下
5 现在这样是有多少数据都一起显示,数据多的时候直方图每条的宽度会变得很小,x轴下标签也会密密麻麻的
接下来改造下,同时最多显示7条数据,可以左右滑动查看其他数据
5.1 添加数据,多加几条数据
val labels = arrayListOf<DataForTrend>()
labels.add(DataForTrend("07-01",0))
labels.add(DataForTrend("07-02",0))
labels.add(DataForTrend("07-03",0))
labels.add(DataForTrend("07-04",20))
labels.add(DataForTrend("07-05",0))
labels.add(DataForTrend("07-07",210))
labels.add(DataForTrend("07-08",0))
labels.add(DataForTrend("07-09",0))
5.2 重新设置BarChart
//重置所有缩放和拖动,并使图表完全适合其边界
binding.bc.fitScreen()
//禁止所有事件
binding.bc.setTouchEnabled(false)
//禁止缩放
binding.bc.setScaleEnabled(false)
//设置最多显示多少数据
binding.bc.setMaxVisibleValueCount(types.size)
//设置x轴放大倍数,y轴不放大
binding.bc.zoom(labels.size/7f,1f,0f,0f)
setXAxis(labels)
setYAxis(labels)
setLabel(labels)
//允许接收触摸事件
binding.bc.setTouchEnabled(true)
//可以拖动
binding.bc.isDragEnabled = true
效果如下
注意:上刷新数据的需要设置这个,比如,可以选择月份展示不同月份的数据,不加这个直方图的宽度会越来越大
//重置所有缩放和拖动,并使图表完全适合其边界
binding.bc.fitScreen()