Refactor StatsFragment with TableReportFragment & StatisticsFragment

feature/top10
Aurelien Hubert 7 years ago
parent 770a75468b
commit ad46897936
  1. 19
      app/src/main/java/net/pokeranalytics/android/ui/adapter/ComparisonChartPagerAdapter.kt
  2. 4
      app/src/main/java/net/pokeranalytics/android/ui/adapter/HomePagerAdapter.kt
  3. 10
      app/src/main/java/net/pokeranalytics/android/ui/adapter/ReportPagerAdapter.kt
  4. 148
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  5. 131
      app/src/main/java/net/pokeranalytics/android/ui/fragment/TableReportFragment.kt
  6. 15
      app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/StatRow.kt

@ -6,7 +6,9 @@ import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.fragment.*
import net.pokeranalytics.android.ui.fragment.CalendarFragment
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.fragment.HistoryFragment
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import java.lang.ref.WeakReference
@ -51,20 +53,7 @@ class ComparisonChartPagerAdapter(val context: Context, fragmentManager: Fragmen
}
override fun getItemPosition(obj: Any): Int {
return when (obj) {
//CLEAN
/*
HistoryFragment::class.java -> 0
StatsFragment::class.java -> 1
SettingsFragment::class.java -> 2
*/
HistoryFragment::class.java -> 0
StatsFragment::class.java -> 1
CalendarFragment::class.java -> 2
ReportsFragment::class.java -> 3
MoreFragment::class.java -> 4
else -> -1
}
return POSITION_UNCHANGED
}
/**

@ -18,7 +18,7 @@ class HomePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAda
override fun getItem(position: Int): PokerAnalyticsFragment {
return when (position) {
0 -> HistoryFragment.newInstance()
1 -> StatsFragment.newInstance()
1 -> StatisticsFragment.newInstance()
2 -> CalendarFragment.newInstance()
3 -> ReportsFragment.newInstance()
4 -> MoreFragment.newInstance()
@ -44,7 +44,7 @@ class HomePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAda
override fun getItemPosition(obj: Any): Int {
return when (obj) {
HistoryFragment::class.java -> 0
StatsFragment::class.java -> 1
StatisticsFragment::class.java -> 1
CalendarFragment::class.java -> 2
ReportsFragment::class.java -> 3
MoreFragment::class.java -> 4

@ -9,6 +9,7 @@ import androidx.viewpager.widget.PagerAdapter
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.ui.fragment.GraphFragment
import net.pokeranalytics.android.ui.fragment.TableReportFragment
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import java.lang.ref.WeakReference
@ -26,14 +27,13 @@ class ReportPagerAdapter(val context: Context, val fragmentManager: FragmentMana
GraphFragment.newInstance(dataSetList)
}
1 -> {
val dataSetList = listOf(report.lineEntries(context = context))
GraphFragment.newInstance(dataSetList)
val dataSetList = report.multiLineEntries(context = context)
//TODO: Uncomment GraphFragment when multiLineEntries will return List<DataSet<*>>
//GraphFragment.newInstance(dataSetList)
PokerAnalyticsFragment()
}
2 -> {
//val dataSetList = listOf(report.barEntries())
//GraphFragment.newInstance(dataSetList)
PokerAnalyticsFragment()
TableReportFragment.newInstance(report)
}
else -> PokerAnalyticsFragment()
}

@ -0,0 +1,148 @@
package net.pokeranalytics.android.ui.fragment
import android.os.Bundle
import android.view.View
import io.realm.Realm
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.Report
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.StatRow
import timber.log.Timber
import java.util.*
import kotlin.coroutines.CoroutineContext
class StatisticsFragment : TableReportFragment() {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
private lateinit var statsAdapter: RowRepresentableAdapter
private var stringAll = ""
private var stringCashGame = ""
private var stringTournament = ""
companion object {
/**
* Create new instance
*/
fun newInstance(report: Report? = null): StatisticsFragment {
val fragment = StatisticsFragment()
report?.let {
fragment.report = it
}
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
}
// Life Cycle
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
launchStatComputation()
}
override fun sessionsChanged() {
this.launchStatComputation()
this.statsAdapter.notifyDataSetChanged()
}
override fun initData() {
super.initData()
this.stringAll = getString(R.string.all)
this.stringCashGame = getString(R.string.cash_game)
this.stringTournament = getString(R.string.tournament)
}
override fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
val rows: ArrayList<RowRepresentable> = ArrayList()
report.results.forEach { result ->
rows.add(CustomizableRowRepresentable(title = result.group.name))
result.group.stats?.forEach { stat ->
rows.add(StatRow(stat, result.computedStat(stat), result.group.name))
}
}
return rows
}
// Business
/**
* Launch stat computation
*/
private fun launchStatComputation() {
GlobalScope.launch(coroutineContext) {
val test = GlobalScope.async {
val s = Date()
Timber.d(">>> start...")
val realm = Realm.getDefaultInstance()
report = createSessionGroupsAndStartCompute(realm)
realm.close()
val e = Date()
val duration = (e.time - s.time) / 1000.0
Timber.d(">>> ended in $duration seconds")
}
test.await()
if (!isDetached) {
showResults()
}
}
}
/**
* Create session groups and start computations
*/
private fun createSessionGroupsAndStartCompute(realm: Realm): Report {
val allStats: List<Stat> = listOf(
Stat.NET_RESULT,
Stat.HOURLY_RATE,
Stat.AVERAGE,
Stat.NUMBER_OF_SETS,
Stat.AVERAGE_DURATION,
Stat.DURATION
)
val allSessionGroup = ComputableGroup(stringAll, listOf(), allStats)
val cgStats: List<Stat> = listOf(
Stat.NET_RESULT,
Stat.HOURLY_RATE,
Stat.NET_BB_PER_100_HANDS,
Stat.HOURLY_RATE_BB,
Stat.AVERAGE,
Stat.STANDARD_DEVIATION_HOURLY,
Stat.WIN_RATIO,
Stat.NUMBER_OF_GAMES,
Stat.AVERAGE_BUYIN
)
val cgSessionGroup = ComputableGroup(stringCashGame, listOf(QueryCondition.CASH), cgStats)
val tStats: List<Stat> =
listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.ROI, Stat.WIN_RATIO, Stat.NUMBER_OF_GAMES, Stat.AVERAGE_BUYIN)
val tSessionGroup = ComputableGroup(stringTournament, listOf(QueryCondition.TOURNAMENT), tStats)
Timber.d(">>>>> Start computations...")
return Calculator.computeGroups(realm, listOf(allSessionGroup, cgSessionGroup, tSessionGroup), Calculator.Options())
}
}

@ -10,7 +10,6 @@ import kotlinx.android.synthetic.main.fragment_stats.*
import kotlinx.coroutines.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.*
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.ui.activity.StatisticDetailsActivity
import net.pokeranalytics.android.ui.adapter.DisplayDescriptor
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
@ -25,27 +24,27 @@ import timber.log.Timber
import java.util.*
import kotlin.coroutines.CoroutineContext
class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSource, CoroutineScope,
open class TableReportFragment : SessionObserverFragment(), StaticRowRepresentableDataSource, CoroutineScope,
RowRepresentableDelegate {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()
private var stringAll = ""
private var stringCashGame = ""
private var stringTournament = ""
private lateinit var statsAdapter: RowRepresentableAdapter
private var report : Report? = null
var report : Report? = null
companion object {
/**
* Create new instance
*/
fun newInstance(): StatsFragment {
val fragment = StatsFragment()
fun newInstance(report: Report? = null): TableReportFragment {
val fragment = TableReportFragment()
report?.let {
fragment.report = it
}
val bundle = Bundle()
fragment.arguments = bundle
return fragment
@ -62,7 +61,10 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
launchStatComputation()
report?.let {
showResults()
}
}
// Row Representable DS
@ -75,7 +77,7 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
val dc = DisplayDescriptor()
dc.textFormat = TextFormat(NULL_TEXT)
if (row is StatRow) {
context?.let { context ->
context?.let { _ ->
row.computedStat?.let {
dc.textFormat = it.format()
}
@ -86,7 +88,7 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
override fun statFormatForRow(row: RowRepresentable): TextFormat {
if (row is StatRow) {
context?.let { context ->
context?.let { _ ->
row.computedStat?.let { return it.format() }
}
}
@ -98,34 +100,20 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
statsAdapter.notifyDataSetChanged()
}
// Override
override fun sessionsChanged() {
this.launchStatComputation()
this.statsAdapter.notifyDataSetChanged()
}
// Business
/**
* Init data
*/
private fun initData() {
this.stringAll = getString(R.string.all)
this.stringCashGame = getString(R.string.cash_game)
this.stringTournament = getString(R.string.tournament)
open fun initData() {
this.statsAdapter = RowRepresentableAdapter(this, this)
}
/**
* Init UI
*/
private fun initUI() {
open fun initUI() {
val viewManager = LinearLayoutManager(requireContext())
recyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
@ -133,87 +121,26 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
}
}
private fun launchStatComputation() {
GlobalScope.launch(coroutineContext) {
val test = GlobalScope.async {
val s = Date()
Timber.d(">>> start...")
val realm = Realm.getDefaultInstance()
report = createSessionGroupsAndStartCompute(realm)
realm.close()
val e = Date()
val duration = (e.time - s.time) / 1000.0
Timber.d(">>> ended in $duration seconds")
}
test.await()
if (!isDetached) {
showResults()
}
}
}
private fun createSessionGroupsAndStartCompute(realm: Realm): Report {
val allStats: List<Stat> = listOf(
Stat.NET_RESULT,
Stat.HOURLY_RATE,
Stat.AVERAGE,
Stat.NUMBER_OF_SETS,
Stat.AVERAGE_DURATION,
Stat.DURATION
)
val allSessionGroup = ComputableGroup(stringAll, listOf(), allStats)
val cgStats: List<Stat> = listOf(
Stat.NET_RESULT,
Stat.HOURLY_RATE,
Stat.NET_BB_PER_100_HANDS,
Stat.HOURLY_RATE_BB,
Stat.AVERAGE,
Stat.STANDARD_DEVIATION_HOURLY,
Stat.WIN_RATIO,
Stat.NUMBER_OF_GAMES,
Stat.AVERAGE_BUYIN
)
val cgSessionGroup = ComputableGroup(stringCashGame, listOf(QueryCondition.CASH), cgStats)
val tStats: List<Stat> =
listOf(Stat.NET_RESULT, Stat.HOURLY_RATE, Stat.ROI, Stat.WIN_RATIO, Stat.NUMBER_OF_GAMES, Stat.AVERAGE_BUYIN)
val tSessionGroup = ComputableGroup(stringTournament, listOf(QueryCondition.TOURNAMENT), tStats)
Timber.d(">>>>> Start computations...")
return Calculator.computeGroups(
realm,
listOf(allSessionGroup, cgSessionGroup, tSessionGroup),
Calculator.Options()
)
}
private fun showResults() {
/**
* Show results
*/
fun showResults() {
report?.let {
this.rowRepresentables = this.convertReportIntoRepresentables(it)
statsAdapter.notifyDataSetChanged()
}
}
private fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
open fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
val rows: ArrayList<RowRepresentable> = ArrayList()
report.options.displayedStats.forEach {stat ->
rows.add(CustomizableRowRepresentable(title = stat.localizedTitle(requireContext())))
report.results.forEach {
val title = it.group.name
rows.add(StatRow(stat, it.computedStat(stat), it.group.name, title))
}
report.results.forEach { result ->
rows.add(CustomizableRowRepresentable(title = result.group.name))
result.group.stats?.forEach { stat ->
rows.add(StatRow(stat, result.computedStat(stat), result.group.name))
}
}
}
return rows
}
@ -237,6 +164,8 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
private fun launchStatComputationWithEvolution(stat: Stat, computableGroup: ComputableGroup) {
showLoader()
GlobalScope.launch(coroutineContext) {
var report: Report? = null
@ -259,12 +188,12 @@ class StatsFragment : SessionObserverFragment(), StaticRowRepresentableDataSourc
test.await()
if (!isDetached) {
hideLoader()
report?.let {
StatisticDetailsActivity.newInstance(requireContext(), stat, computableGroup, it)
}
}
}
}
}

@ -1,12 +1,13 @@
package net.pokeranalytics.android.ui.view.rowrepresentable
import android.content.Context
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
class StatRow(stat: Stat, computedStat: ComputedStat?, groupName: String = "") : RowRepresentable {
class StatRow(stat: Stat, computedStat: ComputedStat?, groupName: String = "", var title: String? = null) : RowRepresentable {
var stat: Stat = stat
var computedStat: ComputedStat? = computedStat
@ -18,4 +19,16 @@ class StatRow(stat: Stat, computedStat: ComputedStat?, groupName: String = "") :
override val resId: Int?
get() = this.stat.resId
override fun localizedTitle(context: Context): String {
this.title?.let {
return it
}
this.resId?.let {
return context.getString(it)
}
return "LOCALISATION NOT FOUND"
}
}

Loading…
Cancel
Save