Add some labels to BarGraphView

This commit is contained in:
johan12345
2022-09-20 21:12:52 +02:00
committed by Johan von Forstner
parent b0371c1b20
commit f6afb2a8cb
4 changed files with 108 additions and 11 deletions

View File

@@ -2,19 +2,28 @@ package net.vonforst.evmap.ui
import android.content.Context
import android.graphics.Canvas
import android.graphics.DashPathEffect
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import net.vonforst.evmap.R
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import kotlin.math.roundToInt
class BarGraphView(context: Context, attrs: AttributeSet) : View(context, attrs) {
var zeroHeight = 4 * context.resources.displayMetrics.density
var barWidth = 16 * context.resources.displayMetrics.density
var barMargin = 2 * context.resources.displayMetrics.density
var barWidth = (16 * context.resources.displayMetrics.density).roundToInt()
var barMargin = (2 * context.resources.displayMetrics.density).roundToInt()
var legendWidth = 12 * context.resources.displayMetrics.density
var legendLineLength = 4 * context.resources.displayMetrics.density
var legendLineWidth = 1 * context.resources.displayMetrics.density
var dashLength = 4 * context.resources.displayMetrics.density
var barDrawableUnavailable =
AppCompatResources.getDrawable(context, R.drawable.bar_graph_unavailable)!!
@@ -26,35 +35,107 @@ class BarGraphView(context: Context, attrs: AttributeSet) : View(context, attrs)
field = value
invalidate()
}
var maxValue: Int? = null
set(value) {
field = value
invalidate()
}
var activeAlpha = 0.87f
var inactiveAlpha = 0.60f
private val legendPaint = Paint().apply {
val ta = context.theme.obtainStyledAttributes(intArrayOf(R.attr.colorControlNormal))
color = ta.getColor(0, 0)
strokeWidth = legendLineWidth
textSize = legendWidth - legendLineLength
}
private val legendDashedPaint = Paint().apply {
set(legendPaint)
alpha = (inactiveAlpha * 255).roundToInt()
style = Paint.Style.STROKE
pathEffect = DashPathEffect(floatArrayOf(dashLength, dashLength), 0f)
}
private lateinit var graphBounds: Rect
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
graphBounds = Rect(paddingLeft, paddingTop, w - paddingRight, h - paddingBottom)
val bottom = (paddingBottom + legendWidth).roundToInt()
val left = (paddingLeft + legendWidth).roundToInt()
val right = (paddingRight + legendWidth).roundToInt()
val top = (paddingTop + (legendWidth - legendLineLength) / 3 * 2).roundToInt()
graphBounds = Rect(left, top, w - right, h - bottom)
}
private val timeFormat = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
override fun onDraw(canvas: Canvas) {
val data = data ?: return
val maxValue = data.maxOf { it.value }
val data = data?.toSortedMap() ?: return
val maxValue = maxValue ?: data.maxOf { it.value }
canvas.apply {
data.toSortedMap().entries.forEachIndexed { i, (t, v) ->
drawLine(
graphBounds.left.toFloat(),
graphBounds.top.toFloat(),
graphBounds.right.toFloat(),
graphBounds.top.toFloat(),
legendDashedPaint
)
legendPaint.textAlign = Paint.Align.CENTER
data.entries.forEachIndexed { i, (t, v) ->
val drawable = if (v > 0) barDrawableAvailable else barDrawableUnavailable
val height =
zeroHeight + (graphBounds.height() - zeroHeight) * v.toFloat() / maxValue
val left = graphBounds.left + (barWidth + barMargin) * i
if (left + barWidth > graphBounds.right) return@forEachIndexed
drawable.setBounds(
graphBounds.left + ((barWidth + barMargin) * i).roundToInt(),
left,
graphBounds.bottom - height.roundToInt(),
graphBounds.left + ((barWidth + barMargin) * i + barWidth).roundToInt(),
left + barWidth,
graphBounds.bottom
)
drawable.alpha = (inactiveAlpha * 255).roundToInt()
drawable.draw(canvas)
if (t.minute == 0) {
val center = left.toFloat() + barWidth / 2
drawLine(
center, graphBounds.bottom.toFloat(),
center, graphBounds.bottom + legendLineLength, legendPaint
)
drawText(
t.withZoneSameInstant(ZoneId.systemDefault()).format(timeFormat),
center, graphBounds.bottom + legendWidth, legendPaint
)
}
}
drawLine(
graphBounds.left.toFloat(),
graphBounds.bottom.toFloat(),
graphBounds.right.toFloat(),
graphBounds.bottom.toFloat(),
legendPaint
)
drawLine(
graphBounds.left.toFloat(),
graphBounds.bottom.toFloat(),
graphBounds.right.toFloat(),
graphBounds.bottom.toFloat(),
legendPaint
)
legendPaint.textAlign = Paint.Align.LEFT
drawText(
maxValue.toString(),
graphBounds.right.toFloat() + legendLineLength,
graphBounds.top + (legendWidth - legendLineLength) / 3,
legendPaint
)
}
}
}

View File

@@ -335,16 +335,30 @@
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/prediction" />
<TextView
android:id="@+id/textView8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/availability_prediction"
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
android:textColor="?colorPrimary"
app:goneUnlessAnimated="@{predictionGraph != null}"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/textView13" />
<net.vonforst.evmap.ui.BarGraphView
android:id="@+id/prediction"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginTop="16dp"
app:goneUnless="@{predictionGraph != null}"
android:layout_marginTop="8dp"
app:goneUnlessAnimated="@{predictionGraph != null}"
app:data="@{predictionGraph}"
app:maxValue="@{charger.data.totalChargepoints}"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/textView13"
app:layout_constraintTop_toBottomOf="@+id/textView8"
tools:itemCount="3"
tools:layoutManager="LinearLayoutManager"
tools:listitem="@layout/item_connector"

View File

@@ -270,4 +270,5 @@
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>
<string name="about_contributors">Mitwirkende</string>
<string name="about_contributors_text">Dank an alle Mitwirkenden für ihre Beiträge von Code und Übersetzungen für EVMap:</string>
<string name="availability_prediction">Verfügbarkeitsprognose</string>
</resources>

View File

@@ -269,4 +269,5 @@
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>
<string name="about_contributors">Contributors</string>
<string name="about_contributors_text">Thanks to all contributors for their coding and translation contributions to EVMap:</string>
<string name="availability_prediction">Availability prediction</string>
</resources>