From 93fa29829fcf7118d1f6941f763ed92589da4238 Mon Sep 17 00:00:00 2001
From: rebelonion <87634197+rebelonion@users.noreply.github.com>
Date: Sun, 3 Mar 2024 00:01:56 -0600
Subject: [PATCH] feat: length / year graph
---
.../ani/dantotsu/profile/StatsFragment.kt | 136 ++++++++++++++++--
1 file changed, 123 insertions(+), 13 deletions(-)
diff --git a/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt b/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt
index 5a8835b7..f3007300 100644
--- a/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt
+++ b/app/src/main/java/ani/dantotsu/profile/StatsFragment.kt
@@ -25,13 +25,13 @@ import com.github.aachartmodel.aainfographics.aachartcreator.aa_toAAOptions
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AADataLabels
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAItemStyle
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAMarker
+import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAPlotOptions
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAStyle
import com.github.aachartmodel.aainfographics.aatools.AAColor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Locale
-import kotlin.reflect.KClass
class StatsFragment(private val user: Query.UserProfile, private val activity: ProfileActivity) :
Fragment() {
@@ -39,6 +39,7 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
private var stats: Query.StatisticsResponse? = null
private var type: MediaType = MediaType.ANIME
private var statType: StatType = StatType.COUNT
+ private var primaryColor: Int = 0
override fun onCreateView(
inflater: LayoutInflater,
@@ -52,6 +53,14 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ val typedValue = TypedValue()
+ activity.theme.resolveAttribute(
+ com.google.android.material.R.attr.colorPrimary,
+ typedValue,
+ true
+ )
+ primaryColor = typedValue.data
+
binding.sourceType.setAdapter(
ArrayAdapter(
requireContext(),
@@ -127,6 +136,33 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
binding.scoreChartView.visibility = View.GONE
}
+ val lengthChartModel = getLengthChartModel(anime)
+ if (lengthChartModel != null) {
+ binding.lengthChartView.visibility = View.VISIBLE
+ val aaOptions = buildOptions(lengthChartModel)
+ binding.lengthChartView.aa_drawChartWithChartOptions(aaOptions)
+ } else {
+ binding.lengthChartView.visibility = View.GONE
+ }
+
+ val releaseYearChartModel = getReleaseYearChartModel(anime)
+ if (releaseYearChartModel != null) {
+ binding.releaseYearChartView.visibility = View.VISIBLE
+ val aaOptions = buildOptions(releaseYearChartModel, false, """
+ function () {
+ return 'Year: ' +
+ this.x +
+ '
' +
+ ' ${getTypeName()} ' +
+ this.y
+ }
+ """.trimIndent()
+ )
+ binding.releaseYearChartView.aa_drawChartWithChartOptions(aaOptions)
+ } else {
+ binding.releaseYearChartView.visibility = View.GONE
+ }
+
}
private fun buildOptions(
@@ -188,7 +224,7 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
}
if (names.isEmpty() || values.isEmpty())
return null
- val primaryColor = getBaseColor(activity)
+ val primaryColor = primaryColor
val palette = generateColorPalette(primaryColor, names.size)
return AAChartModel()
.chartType(AAChartType.Pie)
@@ -220,7 +256,6 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
}
if (names.isEmpty() || values.isEmpty())
return null
- val primaryColor = getBaseColor(activity)
val palette = generateColorPalette(primaryColor, names.size)
return AAChartModel()
.chartType(AAChartType.Pyramid)
@@ -252,7 +287,6 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
}
if (names.isEmpty() || values.isEmpty())
return null
- val primaryColor = getBaseColor(activity)
val palette = generateColorPalette(primaryColor, names.size)
return AAChartModel()
.chartType(AAChartType.Column)
@@ -266,6 +300,74 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
.series(getElements(names, values, palette))
}
+ private fun getLengthChartModel(anime: Boolean): AAChartModel? {
+ val names: List = if (anime) {
+ stats?.data?.user?.statistics?.anime?.lengths?.mapNotNull { it.length } ?: emptyList()
+ } else {
+ stats?.data?.user?.statistics?.manga?.lengths?.mapNotNull { it.length } ?: emptyList()
+ }
+ val values: List = if (anime) {
+ when (statType) {
+ StatType.COUNT -> stats?.data?.user?.statistics?.anime?.lengths?.map { it.count }
+ StatType.TIME -> stats?.data?.user?.statistics?.anime?.lengths?.map { it.minutesWatched / 60 }
+ StatType.MEAN_SCORE -> stats?.data?.user?.statistics?.anime?.lengths?.map { it.meanScore }
+ } ?: emptyList()
+ } else {
+ when (statType) {
+ StatType.COUNT -> stats?.data?.user?.statistics?.manga?.lengths?.map { it.count }
+ StatType.TIME -> stats?.data?.user?.statistics?.manga?.lengths?.map { it.chaptersRead }
+ StatType.MEAN_SCORE -> stats?.data?.user?.statistics?.manga?.lengths?.map { it.meanScore }
+ } ?: emptyList()
+ }
+ //clear nulls from names
+ if (names.isEmpty() || values.isEmpty())
+ return null
+ val palette = generateColorPalette(primaryColor, names.size)
+ return AAChartModel()
+ .chartType(AAChartType.Pie)
+ .title("Length")
+ .subtitle(getTypeName())
+ .zoomType(AAChartZoomType.XY)
+ .dataLabelsEnabled(true)
+ .series(getElements(names, values, palette))
+ }
+
+ private fun getReleaseYearChartModel(anime: Boolean): AAChartModel? {
+ val names: List = if (anime) {
+ stats?.data?.user?.statistics?.anime?.releaseYears?.map { it.releaseYear } ?: emptyList()
+ } else {
+ stats?.data?.user?.statistics?.manga?.releaseYears?.map { it.releaseYear } ?: emptyList()
+ }
+ val values: List = if (anime) {
+ when (statType) {
+ StatType.COUNT -> stats?.data?.user?.statistics?.anime?.releaseYears?.map { it.count }
+ StatType.TIME -> stats?.data?.user?.statistics?.anime?.releaseYears?.map { it.minutesWatched / 60 }
+ StatType.MEAN_SCORE -> stats?.data?.user?.statistics?.anime?.releaseYears?.map { it.meanScore }
+ } ?: emptyList()
+ } else {
+ when (statType) {
+ StatType.COUNT -> stats?.data?.user?.statistics?.manga?.releaseYears?.map { it.count }
+ StatType.TIME -> stats?.data?.user?.statistics?.manga?.releaseYears?.map { it.chaptersRead }
+ StatType.MEAN_SCORE -> stats?.data?.user?.statistics?.manga?.releaseYears?.map { it.meanScore }
+ } ?: emptyList()
+ }
+ //clear nulls from names
+ if (names.isEmpty() || values.isEmpty())
+ return null
+ val palette = generateColorPalette(primaryColor, names.size)
+ val hexColorsArray: Array = palette.map { String.format("#%06X", 0xFFFFFF and it) }.toTypedArray()
+ return AAChartModel()
+ .chartType(AAChartType.Bubble)
+ .title("Release Year")
+ .subtitle(getTypeName())
+ .zoomType(AAChartZoomType.XY)
+ .dataLabelsEnabled(false)
+ .yAxisTitle(getTypeName())
+ .stacking(AAChartStackingType.Normal)
+ .series(getElementsSimple(names, values))
+ .colorsTheme(hexColorsArray)
+ }
+
enum class StatType {
COUNT, TIME, MEAN_SCORE
}
@@ -312,19 +414,28 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
statDataElements.add(element)
}
return arrayOf(
- AASeriesElement().name("Score")
+ AASeriesElement().name("Score").color(primaryColor)
.data(statDataElements.toTypedArray())
)
}
- private fun getBaseColor(context: Context): Int {
- val typedValue = TypedValue()
- context.theme.resolveAttribute(
- com.google.android.material.R.attr.colorPrimary,
- typedValue,
- true
+ private fun getElementsSimple(
+ names: List,
+ statData: List
+ ): Array {
+ val statValues = mutableListOf>()
+ for (i in statData.indices) {
+ statValues.add(arrayOf(names[i], statData[i], statData[i]))
+ }
+ val sorted = statValues.sortedBy { it[0] as Int }
+ return arrayOf(
+ AASeriesElement().name("Score")
+ .data(sorted.toTypedArray())
+ .dataLabels(AADataLabels()
+ .enabled(false)
+ )
+ .colorByPoint(true)
)
- return typedValue.data
}
private fun setColors(aaOptions: AAOptions) {
@@ -352,7 +463,6 @@ class StatsFragment(private val user: Query.UserProfile, private val activity: P
0.9f
)
)
- val primaryColor = getBaseColor(activity)
aaOptions.chart?.backgroundColor(backgroundStyle.color)