Add information about student in grade statistics pie chart (#1749)

Co-authored-by: Mikołaj Pich <m.pich@outlook.com>
This commit is contained in:
Michael
2022-02-15 13:08:44 +01:00
committed by GitHub
parent d3bf5c3e0a
commit aff0fb3a60
12 changed files with 153 additions and 59 deletions

View File

@ -24,5 +24,8 @@ data class GradeSemesterStatistics(
var id: Long = 0
@Transient
var average: String = ""
var classAverage: String = ""
@Transient
var studentAverage: String = ""
}

View File

@ -63,20 +63,16 @@ class GradeStatisticsRepository @Inject constructor(
mapResult = { items ->
when (subjectName) {
"Wszystkie" -> {
val numerator = items.map {
it.classAverage.replace(",", ".").toDoubleOrNull() ?: .0
}.filterNot { it == .0 }
(items.reversed() + GradePartialStatistics(
val summaryItem = GradePartialStatistics(
studentId = semester.studentId,
semesterId = semester.semesterId,
subject = subjectName,
classAverage = if (numerator.isEmpty()) "" else numerator.average().let {
"%.2f".format(Locale.FRANCE, it)
},
studentAverage = "",
classAverage = items.map { it.classAverage }.getSummaryAverage(),
studentAverage = items.map { it.studentAverage }.getSummaryAverage(),
classAmounts = items.map { it.classAmounts }.sumGradeAmounts(),
studentAmounts = items.map { it.studentAmounts }.sumGradeAmounts()
)).reversed()
)
listOf(summaryItem) + items
}
else -> items.filter { it.subject == subjectName }
}.mapPartialToStatisticItems()
@ -112,29 +108,29 @@ class GradeStatisticsRepository @Inject constructor(
val itemsWithAverage = items.map { item ->
item.copy().apply {
val denominator = item.amounts.sum()
average = if (denominator == 0) "" else {
classAverage = if (denominator == 0) "" else {
(item.amounts.mapIndexed { gradeValue, amount ->
(gradeValue + 1) * amount
}.sum().toDouble() / denominator).let {
"%.2f".format(Locale.FRANCE, it)
}
}.sum().toDouble() / denominator).asAverageString()
}
}
}
when (subjectName) {
"Wszystkie" -> (itemsWithAverage.reversed() + GradeSemesterStatistics(
studentId = semester.studentId,
semesterId = semester.semesterId,
subject = subjectName,
amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(),
studentGrade = 0
).apply {
average = itemsWithAverage.mapNotNull {
it.average.replace(",", ".").toDoubleOrNull()
}.average().let {
"%.2f".format(Locale.FRANCE, it)
"Wszystkie" -> {
val summaryItem = GradeSemesterStatistics(
studentId = semester.studentId,
semesterId = semester.semesterId,
subject = subjectName,
amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(),
studentGrade = 0,
).apply {
classAverage = itemsWithAverage.map { it.classAverage }.getSummaryAverage()
studentAverage = items
.mapNotNull { summary -> summary.studentGrade.takeIf { it != 0 } }
.average().asAverageString()
}
}).reversed()
listOf(summaryItem) + itemsWithAverage
}
else -> itemsWithAverage.filter { it.subject == subjectName }
}.mapSemesterToStatisticItems()
}
@ -171,6 +167,19 @@ class GradeStatisticsRepository @Inject constructor(
}
)
private fun List<String>.getSummaryAverage(): String {
val averages = mapNotNull {
it.replace(",", ".").toDoubleOrNull()
}
return averages.average()
.asAverageString()
.takeIf { averages.isNotEmpty() }
.orEmpty()
}
private fun Double.asAverageString(): String = "%.2f".format(Locale.FRANCE, this)
private fun List<List<Int>>.sumGradeAmounts(): List<Int> {
val result = mutableListOf(0, 0, 0, 0, 0, 0)
forEach {

View File

@ -9,12 +9,7 @@ import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.LegendEntry
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.PieData
import com.github.mikephil.charting.data.PieDataSet
import com.github.mikephil.charting.data.PieEntry
import com.github.mikephil.charting.data.*
import com.github.mikephil.charting.formatter.ValueFormatter
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
@ -136,20 +131,50 @@ class GradeStatisticsAdapter @Inject constructor() :
binding: ItemGradeStatisticsPieBinding,
partials: GradePartialStatistics
) {
bindPieChart(binding, partials.subject, partials.classAverage, partials.classAmounts)
val studentAverage = partials.studentAverage.takeIf { it.isNotEmpty() }?.let {
binding.root.context.getString(R.string.grade_statistics_student_average, it)
}
bindPieChart(
binding = binding,
subject = partials.subject,
average = partials.classAverage,
studentValue = studentAverage,
amounts = partials.classAmounts
)
}
private fun bindSemesterChart(
binding: ItemGradeStatisticsPieBinding,
semester: GradeSemesterStatistics
) {
bindPieChart(binding, semester.subject, semester.average, semester.amounts)
val studentAverage = semester.studentAverage.takeIf { it.isNotBlank() }
val studentGrade = semester.studentGrade.takeIf { it != 0 }
val studentValue = when {
studentAverage != null -> binding.root.context.getString(
R.string.grade_statistics_student_average,
studentAverage
)
studentGrade != null -> binding.root.context.getString(
R.string.grade_statistics_student_grade,
studentGrade.toString()
)
else -> null
}
bindPieChart(
binding = binding,
subject = semester.subject,
average = semester.classAverage,
studentValue = studentValue,
amounts = semester.amounts
)
}
private fun bindPieChart(
binding: ItemGradeStatisticsPieBinding,
subject: String,
average: String,
studentValue: String?,
amounts: List<Int>
) {
with(binding.gradeStatisticsPieTitle) {
@ -208,13 +233,13 @@ class GradeStatisticsAdapter @Inject constructor() :
val numberOfGradesString = amounts.fold(0) { acc, it -> acc + it }
.let { resources.getQuantityString(R.plurals.grade_number_item, it, it) }
val averageString =
binding.root.context.getString(R.string.grade_statistics_average, average)
binding.root.context.getString(R.string.grade_statistics_class_average, average)
minAngleForSlices = 25f
description.isEnabled = false
centerText =
numberOfGradesString + ("\n\n" + averageString).takeIf { average.isNotBlank() }
.orEmpty()
.orEmpty() + studentValue?.let { "\n$it" }.orEmpty()
setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground))
setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary))