diff --git a/app/src/main/java/de/tum/in/tumcampusapp/component/tumui/grades/GradesFragment.kt b/app/src/main/java/de/tum/in/tumcampusapp/component/tumui/grades/GradesFragment.kt index d0482896c3..a654f1736c 100644 --- a/app/src/main/java/de/tum/in/tumcampusapp/component/tumui/grades/GradesFragment.kt +++ b/app/src/main/java/de/tum/in/tumcampusapp/component/tumui/grades/GradesFragment.kt @@ -15,10 +15,12 @@ import android.widget.EditText import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat.getColor +import com.github.mikephil.charting.components.Description import com.github.mikephil.charting.components.Legend import com.github.mikephil.charting.components.LegendEntry +import com.github.mikephil.charting.components.XAxis import com.github.mikephil.charting.data.* -import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.formatter.IndexAxisValueFormatter import com.google.gson.* import com.google.gson.reflect.TypeToken import com.zhuinden.fragmentviewbindingdelegatekt.viewBinding @@ -36,7 +38,7 @@ import org.joda.time.format.DateTimeFormat import org.joda.time.format.DateTimeFormatter import java.lang.reflect.Type import java.text.NumberFormat -import java.util.Locale +import java.util.* import javax.inject.Inject class GradesFragment : FragmentForAccessingTumOnline( @@ -242,7 +244,7 @@ class GradesFragment : FragmentForAccessingTumOnline( * * @param gradeDistribution An [ArrayMap] mapping grades to number of occurrences */ - private fun displayPieChart(gradeDistribution: ArrayMap) { + private fun displayPieChart(gradeDistribution: ArrayMap) { val entries = grades.map { grade -> val count = gradeDistribution[grade] ?: 0 PieEntry(count.toFloat(), grade) @@ -283,47 +285,41 @@ class GradesFragment : FragmentForAccessingTumOnline( * * @param gradeDistribution An [ArrayMap] mapping grades to number of occurrence */ - private fun displayBarChart(gradeDistribution: ArrayMap) { - val entries = grades.mapIndexed { index, grade -> - val value = gradeDistribution[grade] ?: 0 - BarEntry(index.toFloat(), value.toFloat()) + private fun displayBarChart(gradeDistribution: ArrayMap) { + val sum = gradeDistribution.values.sum() + val entries: List + if (adaptDiagramToWeights) { + entries = grades.mapIndexed { index, grade -> + val value: Double = gradeDistribution[grade] ?: 0.0 + BarEntry(index.toFloat(), ((value*100) / sum).toFloat()) + } + } else { + entries = grades.mapIndexed { index, grade -> + val value = gradeDistribution[grade] ?: 0 + BarEntry(index.toFloat(), value.toFloat()) + } } - var annotation = "" - if (!adaptDiagramToWeights) { - annotation = getString(R.string.grades_without_weight) - } - val set = BarDataSet(entries, annotation).apply { + val set = BarDataSet(entries, "").apply { setColors(GRADE_COLORS, requireContext()) valueTextColor = resources.getColor(R.color.text_primary) } + set.setDrawValues(false) with(binding) { barChartView.apply { + data = BarData(set) setFitBars(true) - // only label grades that are associated with at least one grade - data.setValueFormatter(object : ValueFormatter() { - override fun getFormattedValue(value: Float): String { - if (value > 0.0) - return value.toString() - return "" - } - }) - - description = null - setTouchEnabled(false) - - axisLeft.granularity = 1f - axisRight.granularity = 1f + xAxis.granularity = 1f + legend.isEnabled = true - description = null setTouchEnabled(false) legend.setCustom( arrayOf( LegendEntry( - getString(R.string.grades_without_weight), + context.getString(R.string.grade_passed_annotation), Legend.LegendForm.SQUARE, 10f, 0f, @@ -335,9 +331,30 @@ class GradesFragment : FragmentForAccessingTumOnline( legend.textColor = getColor(resources, R.color.text_primary, null) xAxis.textColor = getColor(resources, R.color.text_primary, null) - axisLeft.textColor = getColor(resources, R.color.text_primary, null) - axisRight.textColor = getColor(resources, R.color.text_primary, null) + axisLeft.isEnabled = true + + if (adaptDiagramToWeights) { + description.isEnabled = true + val desc = Description() + desc.text = context.getString(R.string.grade_percentages) + + desc.setTextSize(11f) + desc.setPosition(540F, 50F) + description = desc + axisRight.disableGridDashedLine() + axisLeft.disableGridDashedLine() + } else { + description.isEnabled = false + axisLeft.granularity = 1f + axisRight.granularity = 1f + } + val labels = (10..51).map { i -> "" + (i / 10.0) }.toList() + + xAxis.valueFormatter = IndexAxisValueFormatter(labels) + xAxis.position = XAxis.XAxisPosition.BOTTOM + xAxis.disableGridDashedLine() + xAxis.disableAxisLineDashedLine() invalidate() } } @@ -373,8 +390,8 @@ class GradesFragment : FragmentForAccessingTumOnline( * @param exams List of [Exam] objects * @return An [ArrayMap] mapping grades to number of occurrence */ - private fun calculateGradeDistribution(exams: List): ArrayMap { - val gradeDistribution = ArrayMap() + private fun calculateGradeDistribution(exams: List): ArrayMap { + val gradeDistribution = ArrayMap() exams.forEach { exam -> // The grade distribution now takes grades with more than one decimal place into account as well if (exam.gradeUsedInAverage) { @@ -382,15 +399,17 @@ class GradesFragment : FragmentForAccessingTumOnline( if (cleanGrade.contains(longGradeRe)) { cleanGrade = cleanGrade.subSequence(0, 3) as String } - val count = gradeDistribution[cleanGrade] ?: 0 + val count = gradeDistribution[cleanGrade] ?: 0.0 if (adaptDiagramToWeights) { - gradeDistribution[cleanGrade] = count + (exam.credits_new * exam.weight).toInt() + gradeDistribution[cleanGrade] = + count + (exam.credits_new * exam.weight).toInt() } else { - gradeDistribution[cleanGrade] = count + 1 + gradeDistribution[cleanGrade] = count + 1.0 } } } + return gradeDistribution } @@ -672,6 +691,8 @@ class GradesFragment : FragmentForAccessingTumOnline( binding.floatingButtonAddExamGrade.visibility = View.VISIBLE binding.chartsContainer.visibility = View.GONE binding.checkboxUseDiagrams.visibility = View.VISIBLE + barMenuItem?.isVisible = false + pieMenuItem?.isVisible = false param.setMargins(0, ((32 * density + 0.5f).toInt()), 0, 0) binding.gradesListView.setPadding(0, 0, 0, 0) } else { @@ -679,6 +700,8 @@ class GradesFragment : FragmentForAccessingTumOnline( binding.frameLayoutAverageGrade?.visibility = View.VISIBLE binding.floatingButtonAddExamGrade.visibility = View.GONE binding.chartsContainer.visibility = View.VISIBLE + pieMenuItem?.isVisible = binding.barChartView.visibility != View.GONE + barMenuItem?.isVisible = binding.barChartView.visibility == View.GONE binding.checkboxUseDiagrams.visibility = View.GONE param.setMargins(0, 0, 0, 0) binding.gradesListView.setPadding(0, ((256 * density + 0.5f).toInt()), 0, 0) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 6f4f50ea93..b4104a64ab 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -100,7 +100,8 @@ Ungültige Anzahl an ECTS. Die ECTS-Zahl muss größer als 0 sein. Eine neue Prüfung hinzufügen Die Noten werden normalerweise automatisch hinzugefügt. Falls spezielle Noten hinzugefügt werden sollen, kann dies hier geschehen. Manuell hinzugefügte Prüfungen können später wieder gelöscht werden. - + Ohne Note Bestanden. + Prozentsatz der Noten. TUM Kennung diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d5b8849bb1..9c94c2fbb8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - + @@ -128,7 +128,8 @@ Invalid amount of credits. Must be greater than 0. Add a New Exam Grades are normally added automatically. In case special grades should be added, this can be done here. Manually added Exams can be deleted later on. - + Exam passed without a grade + Percentage of each grade TUM Identification @@ -846,5 +847,4 @@ Signature: %5$s Feature not implemented yet Interactive map is not yet implemented. You can access it on NavigaTum website. Redirect -