forked from github/wulkanowy-mirror
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:
@ -24,5 +24,8 @@ data class GradeSemesterStatistics(
|
||||
var id: Long = 0
|
||||
|
||||
@Transient
|
||||
var average: String = ""
|
||||
var classAverage: String = ""
|
||||
|
||||
@Transient
|
||||
var studentAverage: String = ""
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
|
Reference in New Issue
Block a user