diff options
author | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2022-02-24 07:40:37 +0000 |
---|---|---|
committer | Guillaume Jacquart <guillaume.jacquart@hoodbrains.com> | 2022-02-24 07:40:37 +0000 |
commit | 6abf3b8bbcec463dcea8acbba63872d587ff2779 (patch) | |
tree | 3aea080c86ba2f51c6cb8ad4302765d1ddf5b3a6 /app/src/main/java/foundation/e/privacycentralapp/common | |
parent | ac0f57662d5c953f73c0561edc11e0ae8c9a0404 (diff) | |
parent | 8d669755396a58eb3894144b25631ff7577954be (diff) | |
download | advanced-privacy-6abf3b8bbcec463dcea8acbba63872d587ff2779.tar.gz |
Merge branch 'update_graphs' into 'main'
Update graph UI, #4582
See merge request e/privacy-central/privacycentralapp!16
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/common')
-rw-r--r-- | app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt | 194 | ||||
-rw-r--r-- | app/src/main/java/foundation/e/privacycentralapp/common/GraphStyle.kt | 62 |
2 files changed, 194 insertions, 62 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt b/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt new file mode 100644 index 0000000..db6bc7e --- /dev/null +++ b/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2021 E FOUNDATION + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package foundation.e.privacycentralapp.common + +import android.content.Context +import android.graphics.Canvas +import android.view.View +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.core.view.isVisible +import com.github.mikephil.charting.charts.BarChart +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.components.XAxis +import com.github.mikephil.charting.data.BarData +import com.github.mikephil.charting.data.BarDataSet +import com.github.mikephil.charting.data.BarEntry +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.listener.OnChartValueSelectedListener +import com.github.mikephil.charting.utils.MPPointF +import foundation.e.privacycentralapp.R + +class GraphHolder(val barChart: BarChart, val context: Context, val isMarkerAbove: Boolean = true) { + var data = emptyList<Int>() + set(value) { + field = value + refreshDataSet() + } + var labels = emptyList<String>() + + private var isHighlighted = false + + init { + barChart.apply { + description = null + setTouchEnabled(true) + setScaleEnabled(false) + + setDrawGridBackground(false) + setDrawBorders(false) + axisLeft.isEnabled = false + axisRight.isEnabled = false + + legend.isEnabled = false + + if (isMarkerAbove) { + extraTopOffset = 44f + } else { + extraBottomOffset = 44f + } + + offsetTopAndBottom(0) + xAxis.apply { + isEnabled = true + position = XAxis.XAxisPosition.BOTH_SIDED + setDrawGridLines(false) + setDrawLabels(false) + setDrawValueAboveBar(false) + } + + val periodMarker = PeriodMarkerView(context, isMarkerAbove) + periodMarker.chartView = this + marker = periodMarker + + setOnChartValueSelectedListener(object : OnChartValueSelectedListener { + override fun onValueSelected(e: Entry?, h: Highlight?) { + h?.let { periodMarker.setLabel(labels.getOrNull(it.x.toInt())) } + isHighlighted = true + refreshDataSet() + } + + override fun onNothingSelected() { + isHighlighted = false + refreshDataSet() + } + }) + } + } + + private fun refreshDataSet() { + val trackersDataSet = BarDataSet( + data.mapIndexed { index, value -> BarEntry(index.toFloat(), value.toFloat()) }, + "" + ).apply { + color = ContextCompat.getColor( + context, + if (isHighlighted) R.color.blue_unselected else R.color.accent + ) + setDrawValues(false) + highLightColor = ContextCompat.getColor( + context, R.color.accent + ) + highLightAlpha = 255 + } + + barChart.data = BarData(trackersDataSet) + barChart.invalidate() + } +} + +private fun Int.dpToPxF(context: Context): Float = this.toFloat() * context.resources.displayMetrics.density + +class PeriodMarkerView(context: Context, private val isMarkerAbove: Boolean = true) : MarkerView(context, R.layout.chart_tooltip) { + enum class ArrowPosition { LEFT, CENTER, RIGHT } + + private val arrowMargins = 10.dpToPxF(context) + private val mOffset2 = MPPointF(0f, 0f) + + private fun getArrowPosition(posX: Float): ArrowPosition { + val halfWidth = width / 2 + + return chartView?.let { chart -> + if (posX < halfWidth) { + ArrowPosition.LEFT + } else if (chart.width - posX < halfWidth) { + ArrowPosition.RIGHT + } else { + ArrowPosition.CENTER + } + } ?: ArrowPosition.CENTER + } + + private fun showArrow(position: ArrowPosition?) { + val ids = listOf( + R.id.arrow_top_left, R.id.arrow_top_center, R.id.arrow_top_right, + R.id.arrow_bottom_left, R.id.arrow_bottom_center, R.id.arrow_bottom_right + ) + + val toShow = if (isMarkerAbove) when (position) { + ArrowPosition.LEFT -> R.id.arrow_bottom_left + ArrowPosition.CENTER -> R.id.arrow_bottom_center + ArrowPosition.RIGHT -> R.id.arrow_bottom_right + else -> null + } else when (position) { + ArrowPosition.LEFT -> R.id.arrow_top_left + ArrowPosition.CENTER -> R.id.arrow_top_center + ArrowPosition.RIGHT -> R.id.arrow_top_right + else -> null + } + + ids.forEach { id -> + val showIt = id == toShow + findViewById<View>(id)?.let { + if (it.isVisible != showIt) { + it.isVisible = showIt + } + } + } + } + + fun setLabel(label: String?) { + findViewById<TextView>(R.id.label).text = label + } + + override fun refreshContent(e: Entry?, highlight: Highlight?) { + highlight?.let { + showArrow(getArrowPosition(highlight.xPx)) + } + super.refreshContent(e, highlight) + } + + override fun getOffsetForDrawingAtPoint(posX: Float, posY: Float): MPPointF { + val x = when (getArrowPosition(posX)) { + ArrowPosition.LEFT -> -arrowMargins + ArrowPosition.RIGHT -> -width + arrowMargins + ArrowPosition.CENTER -> -width.toFloat() / 2 + } + + mOffset2.x = x + mOffset2.y = if (isMarkerAbove) -posY + else -posY + (chartView?.height?.toFloat() ?: 0f) - height + + return mOffset2 + } + + override fun draw(canvas: Canvas?, posX: Float, posY: Float) { + super.draw(canvas, posX, posY) + } +} diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/GraphStyle.kt b/app/src/main/java/foundation/e/privacycentralapp/common/GraphStyle.kt deleted file mode 100644 index 63a0f3f..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/common/GraphStyle.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2021 E FOUNDATION - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.common - -import androidx.annotation.ColorInt -import com.github.mikephil.charting.charts.BarChart -import com.github.mikephil.charting.components.XAxis -import com.github.mikephil.charting.data.BarData -import com.github.mikephil.charting.data.BarDataSet -import com.github.mikephil.charting.data.BarEntry - -fun customizeBarChart(barChart: BarChart) { - barChart.apply { - description = null - setTouchEnabled(false) - setDrawGridBackground(false) - setDrawBorders(false) - axisLeft.isEnabled = false - axisRight.isEnabled = false - - legend.isEnabled = false - - xAxis.apply { - isEnabled = true - position = XAxis.XAxisPosition.BOTH_SIDED - setDrawGridLines(false) - yOffset = 32f - setDrawLabels(false) - // setDrawLimitLinesBehindData(true) - setDrawValueAboveBar(false) - } - } -} - -fun updateGraphData(values: List<Int>, graph: BarChart, @ColorInt graphColor: Int) { - - val trackersDataSet = BarDataSet( - values.mapIndexed { index, value -> BarEntry(index.toFloat(), value.toFloat()) }, - "" - ).apply { - color = graphColor - setDrawValues(false) - } - - graph.data = BarData(trackersDataSet) - graph.invalidate() -} |