diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index f1c3a91..f1c320d 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -3,7 +3,7 @@ android:id="@+id/rootView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/mainBackColor" + android:background="@color/white" android:orientation="vertical"> , entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index f1c3a91..f1c320d 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -3,7 +3,7 @@ android:id="@+id/rootView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/mainBackColor" + android:background="@color/white" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index f1c3a91..f1c320d 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -3,7 +3,7 @@ android:id="@+id/rootView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/mainBackColor" + android:background="@color/white" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/marker_gaode.xml b/app/src/main/res/layout/marker_gaode.xml deleted file mode 100644 index 0778857..0000000 --- a/app/src/main/res/layout/marker_gaode.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index f1c3a91..f1c320d 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -3,7 +3,7 @@ android:id="@+id/rootView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/mainBackColor" + android:background="@color/white" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/marker_gaode.xml b/app/src/main/res/layout/marker_gaode.xml deleted file mode 100644 index 0778857..0000000 --- a/app/src/main/res/layout/marker_gaode.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/popu_line_chart_marker.xml b/app/src/main/res/layout/popu_line_chart_marker.xml index 7096bfd..e4f2cd6 100644 --- a/app/src/main/res/layout/popu_line_chart_marker.xml +++ b/app/src/main/res/layout/popu_line_chart_marker.xml @@ -3,40 +3,27 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:background="@drawable/bg_stroke_layout_blue" - android:gravity="center|left" + android:background="@drawable/bg_solid_layout_blue_3" + android:gravity="center" android:orientation="vertical"> + android:textSize="11sp" /> - - + android:gravity="center_vertical" + android:padding="@dimen/dp_3" + android:text="@string/app_name" + android:textColor="@color/white" + android:textSize="11sp" /> \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index f1c3a91..f1c320d 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -3,7 +3,7 @@ android:id="@+id/rootView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/mainBackColor" + android:background="@color/white" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/marker_gaode.xml b/app/src/main/res/layout/marker_gaode.xml deleted file mode 100644 index 0778857..0000000 --- a/app/src/main/res/layout/marker_gaode.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/popu_line_chart_marker.xml b/app/src/main/res/layout/popu_line_chart_marker.xml index 7096bfd..e4f2cd6 100644 --- a/app/src/main/res/layout/popu_line_chart_marker.xml +++ b/app/src/main/res/layout/popu_line_chart_marker.xml @@ -3,40 +3,27 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:background="@drawable/bg_stroke_layout_blue" - android:gravity="center|left" + android:background="@drawable/bg_solid_layout_blue_3" + android:gravity="center" android:orientation="vertical"> + android:textSize="11sp" /> - - + android:gravity="center_vertical" + android:padding="@dimen/dp_3" + android:text="@string/app_name" + android:textColor="@color/white" + android:textSize="11sp" /> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9297ceb..ca7da7e 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -5,20 +5,8 @@ #626262 #F7F7FA #CCCCCC - #DDDDDD #FF0000 #FF6600 #37D4AE #99000000 - - - #96e9b5 - #ff8078 - #80bbff - #916bff - #ffe1ab - #6666FF - #CCFF66 - #37D4AE - #feb5a2 \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt index f94274d..acf5ad9 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/LineChart.kt @@ -6,16 +6,23 @@ import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.components.YAxis -import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.dp2px -fun LineChart.init(labelCount: Int) { +fun LineChart.initConfig() { this.setNoDataText("无数据,无法渲染...") this.setNoDataTextColor(R.color.orangeTextColor) - this.getPaint(Chart.PAINT_INFO).textSize = 14f.dp2px(this.context) + this.getPaint(Chart.PAINT_INFO).textSize = 12f.dp2px(this.context) this.setDrawGridBackground(false) this.setDrawBorders(false) + this.isScaleXEnabled = true //X轴可缩放 + this.isScaleYEnabled = false //Y轴不可缩放 + this.isDragEnabled = true + this.description.isEnabled = false + this.extraBottomOffset = 5f //底部边距 + //去掉图例 + this.legend.isEnabled = false this.animateY(1200, Easing.EaseInOutQuad) + //设置样式 val rightAxis: YAxis = this.axisRight //设置图表右边的y轴禁用 @@ -23,22 +30,14 @@ val leftAxis: YAxis = this.axisLeft leftAxis.axisMinimum = 0f leftAxis.axisMaximum = 100f - this.isScaleXEnabled = true //X轴可缩放 - this.isScaleYEnabled = false //Y轴不可缩放 + //设置x轴 val xAxis: XAxis = this.xAxis - xAxis.textColor = R.color.mainTextColor.convertColor(this.context) xAxis.textSize = 10f - xAxis.labelCount = labelCount //x轴标签数量 xAxis.setDrawLabels(true) //绘制标签 指x轴上的对应数值 xAxis.setDrawAxisLine(true) //是否绘制轴线 - xAxis.setDrawGridLines(true) //设置x轴上每个点对应的线 + xAxis.setDrawGridLines(false) //设置x轴上每个点对应的线 xAxis.granularity = 1f //禁止放大后x轴标签重绘 xAxis.position = XAxis.XAxisPosition.BOTTOM xAxis.labelRotationAngle = -45f - this.extraBottomOffset = 5f //解决X轴显示不完全问题 - //去掉描述 - this.description.isEnabled = false - //去掉图例 - this.legend.isEnabled = false } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt index a4db48e..d7f1843 100644 --- a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -1,7 +1,7 @@ package com.casic.smarttube.utils import com.casic.smarttube.R -import com.casic.smarttube.extensions.init +import com.casic.smarttube.extensions.initConfig import com.casic.smarttube.widgets.LineChartMarkerView import com.github.mikephil.charting.charts.LineChart import com.github.mikephil.charting.data.Entry @@ -22,11 +22,9 @@ /** * 折线图 * */ - fun setLineChartData( - chart: LineChart, xAxisDate: MutableList, entries: List - ) { + fun setLineChartData(chart: LineChart, xAxisDate: ArrayList, entries: List) { //每次加载数据都初始化折线图 - chart.init(xAxisDate.size) + chart.initConfig() if (entries.isEmpty()) { return } @@ -34,14 +32,11 @@ val lineDataSets: MutableList = ArrayList() //设置数据 val dataSet = LineDataSet(entries, entries[0].data.toString()) - dataSet.setDrawCircles(true) - //圆点颜色 - dataSet.setCircleColor(R.color.redTextColor.convertColor(chart.context)) + dataSet.setDrawCircles(false) //线条颜色 dataSet.color = R.color.redTextColor.convertColor(chart.context) dataSet.setDrawFilled(false) -// dataSet.fillColor = R.color.redTextColor.convertColor(chart.context) - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + dataSet.mode = LineDataSet.Mode.LINEAR lineDataSets.add(dataSet) val lineData = LineData(lineDataSets) diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt index a0025db..e58c030 100644 --- a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -36,7 +36,7 @@ } override fun setupTopBarLayout() { - binding.rootView.initImmersionBar(this, true, R.color.mainThemeColor) + binding.rootView.initImmersionBar(this, true, R.color.white) binding.leftBackView.setOnClickListener { finish() } } @@ -143,9 +143,9 @@ } deviceViewModel.historyDataModel.observe(this) { if (it.code == 200) { - val xAxisLabels: MutableList = ArrayList() + val xAxisLabels = ArrayList() //每个entries都是一条折线 - val strengthEntries: ArrayList = ArrayList() + val strengthEntries = ArrayList() it.data.reverse() it.data.forEachIndexed { i, rowsBean -> // x 轴坐标 diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt index 51535bc..794a09c 100644 --- a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -1,43 +1,156 @@ package com.casic.smarttube.widgets import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Path import android.widget.TextView +import androidx.core.graphics.drawable.toBitmap import com.casic.smarttube.R import com.github.mikephil.charting.components.MarkerView import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.utils.MPPointF -import java.util.* +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.convertDrawable +import com.pengxh.kt.lite.extensions.dp2px -class LineChartMarkerView(context: Context?) : - MarkerView(context, R.layout.popu_line_chart_marker) { +class LineChartMarkerView(context: Context) : MarkerView(context, R.layout.popu_line_chart_marker) { - private val kTag = "LineChartMarkerView" - private val dayView: TextView = findViewById(R.id.dayView) - private val lelValueView: TextView = findViewById(R.id.lelValueView) - private val volValueView: TextView = findViewById(R.id.volValueView) - private var xAxisDate: MutableList = ArrayList() + private val timeView: TextView = findViewById(R.id.timeView) + private val valueView: TextView = findViewById(R.id.valueView) + private var xAxisDate = ArrayList() + private val dotBitmap = R.drawable.ic_chart_dot.convertDrawable(context)!!.toBitmap() + private var arrowPaint = Paint() + private val arrowHeight = 10.dp2px(context) // 箭头的高度 + private val arrowWidth = 15.dp2px(context) // 箭头的宽度 + private val arrowOffset = 2f.dp2px(context) //箭头偏移量 - fun setXAxisDate(date: MutableList) { + init { + arrowPaint.style = Paint.Style.FILL + arrowPaint.isAntiAlias = true + arrowPaint.color = R.color.mainThemeColor.convertColor(context) + } + + fun setXAxisDate(date: ArrayList) { this.xAxisDate = date } - //每次重绘,会调用此方法刷新数据 override fun refreshContent(e: Entry, highlight: Highlight) { super.refreshContent(e, highlight) - val data = e.data as String try { - val value = e.y.toDouble().toInt() - lelValueView.text = "浓度(LEL):${value}%" - volValueView.text = "浓度(VOL):${value * 500}ppm" - dayView.text = xAxisDate[(e.x).toInt()] - } catch (e: Exception) { - e.printStackTrace() + timeView.text = xAxisDate[(e.x).toInt()] + valueView.text = "${"%.2f".format(e.y)}%LEL" + } catch (ex: Exception) { + ex.printStackTrace() } super.refreshContent(e, highlight) } override fun getOffset(): MPPointF { - return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + return MPPointF((-(width shr 1)).toFloat(), -height.toFloat()) + } + + /** + * 绘制自适应界面的Marker + * */ + override fun draw(canvas: Canvas, posX: Float, posY: Float) { + if (chartView == null) { + super.draw(canvas, posX, posY) + return + } + + val saveId = canvas.save() + canvas.translate(posX, posY) + + canvas.drawBitmap(dotBitmap, -dotBitmap.width / 2f, -dotBitmap.height / 2f, null) + + drawArrow(canvas, posX, posY) + + draw(canvas) + canvas.restoreToCount(saveId) + } + + private fun drawArrow(canvas: Canvas, posX: Float, posY: Float) { + val path = Path() + if (posY < height + arrowHeight + dotBitmap.height / 2f) { + //处理超过上边界 + canvas.translate(0f, height + arrowHeight + dotBitmap.height / 2f) + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } else { + if (posX > width / 2f) { + //在图表中间 + path.moveTo(0f, -(height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.lineTo(0f, -(height + arrowHeight).toFloat()) + } else { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + path.lineTo(arrowWidth / 2f, -height.toFloat()) + path.lineTo(-arrowWidth / 2f, -height.toFloat()) + path.moveTo( + -(width / 2f - posX) - arrowOffset, + -(height + arrowHeight + arrowOffset) + ) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, -height.toFloat()) + } else { + canvas.translate(0f, -height - arrowHeight - dotBitmap.height / 2f) + if (posX < width / 2f) { + //超过左边界 + canvas.translate(width / 2f - posX, 0f) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + -(width / 2f - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + if (posX > chartView.width - (width / 2f)) { + //超过右边界 + canvas.translate(-(width / 2 - (chartView.width - posX)), 0f) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo( + width / 2 - (chartView.width - posX) + arrowOffset, + height + arrowHeight + arrowOffset + ) + } else { + path.moveTo(0f, (height + arrowHeight).toFloat()) + path.lineTo(arrowWidth / 2f, height.toFloat()) + path.lineTo(-arrowWidth / 2f, height.toFloat()) + path.moveTo(0f, (height + arrowHeight).toFloat()) + } + } + canvas.drawPath(path, arrowPaint) + canvas.translate(-width / 2f, 0f) + } } } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_blue_3.xml b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml new file mode 100644 index 0000000..3b277e8 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_layout_blue_3.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml deleted file mode 100644 index 900343f..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_10.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml b/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml deleted file mode 100644 index e329b7d..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_main_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml deleted file mode 100644 index 9570167..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_10.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml b/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml deleted file mode 100644 index 0c2abfe..0000000 --- a/app/src/main/res/drawable/bg_solid_layout_white_radius_top_20.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml deleted file mode 100644 index cc1e657..0000000 --- a/app/src/main/res/drawable/bg_solid_text_gray_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml b/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml deleted file mode 100644 index 3d70d93..0000000 --- a/app/src/main/res/drawable/bg_solid_text_green_radius_5.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_short_line.xml b/app/src/main/res/drawable/bottom_short_line.xml deleted file mode 100644 index 10c9062..0000000 --- a/app/src/main/res/drawable/bottom_short_line.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_main_selector.xml b/app/src/main/res/drawable/button_main_selector.xml deleted file mode 100644 index 5875998..0000000 --- a/app/src/main/res/drawable/button_main_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_white_selector.xml b/app/src/main/res/drawable/button_white_selector.xml deleted file mode 100644 index 4dd3c0b..0000000 --- a/app/src/main/res/drawable/button_white_selector.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/home_selector.xml b/app/src/main/res/drawable/home_selector.xml deleted file mode 100644 index 7c8ec4f..0000000 --- a/app/src/main/res/drawable/home_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml deleted file mode 100644 index 3d1695b..0000000 --- a/app/src/main/res/drawable/ic_add.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_chart_dot.xml b/app/src/main/res/drawable/ic_chart_dot.xml new file mode 100644 index 0000000..32dc2ed --- /dev/null +++ b/app/src/main/res/drawable/ic_chart_dot.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_home.xml b/app/src/main/res/drawable/ic_home.xml deleted file mode 100644 index 5c9aa7c..0000000 --- a/app/src/main/res/drawable/ic_home.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_home_selected.xml b/app/src/main/res/drawable/ic_home_selected.xml deleted file mode 100644 index aabb0ca..0000000 --- a/app/src/main/res/drawable/ic_home_selected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index f1c3a91..f1c320d 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -3,7 +3,7 @@ android:id="@+id/rootView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/mainBackColor" + android:background="@color/white" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/marker_gaode.xml b/app/src/main/res/layout/marker_gaode.xml deleted file mode 100644 index 0778857..0000000 --- a/app/src/main/res/layout/marker_gaode.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/popu_line_chart_marker.xml b/app/src/main/res/layout/popu_line_chart_marker.xml index 7096bfd..e4f2cd6 100644 --- a/app/src/main/res/layout/popu_line_chart_marker.xml +++ b/app/src/main/res/layout/popu_line_chart_marker.xml @@ -3,40 +3,27 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:background="@drawable/bg_stroke_layout_blue" - android:gravity="center|left" + android:background="@drawable/bg_solid_layout_blue_3" + android:gravity="center" android:orientation="vertical"> + android:textSize="11sp" /> - - + android:gravity="center_vertical" + android:padding="@dimen/dp_3" + android:text="@string/app_name" + android:textColor="@color/white" + android:textSize="11sp" /> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 9297ceb..ca7da7e 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -5,20 +5,8 @@ #626262 #F7F7FA #CCCCCC - #DDDDDD #FF0000 #FF6600 #37D4AE #99000000 - - - #96e9b5 - #ff8078 - #80bbff - #916bff - #ffe1ab - #6666FF - #CCFF66 - #37D4AE - #feb5a2 \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index f92b64a..a55db0b 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -70,15 +70,6 @@ @dimen/sp_16 - -