Start working on Bankroll fragment

dev
Aurelien Hubert 7 years ago
parent cdaeff4684
commit 62b08bc284
  1. 3
      app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt
  2. 13
      app/src/main/java/net/pokeranalytics/android/calculus/bankroll/BankrollReport.kt
  3. 68
      app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollFragment.kt
  4. 33
      app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt
  5. 83
      app/src/main/res/layout/row_legend_default.xml

@ -53,6 +53,7 @@ enum class Stat : RowRepresentable {
WINNING_SESSION_COUNT, WINNING_SESSION_COUNT,
BB_SESSION_COUNT, BB_SESSION_COUNT,
TOTAL_BUYIN, TOTAL_BUYIN,
RISK_OF_RUIN,
; ;
companion object { companion object {
@ -145,7 +146,7 @@ enum class Stat : RowRepresentable {
HOURLY_DURATION, AVERAGE_HOURLY_DURATION, MAXIMUM_DURATION -> { HOURLY_DURATION, AVERAGE_HOURLY_DURATION, MAXIMUM_DURATION -> {
return TextFormat(value.formattedHourlyDuration()) return TextFormat(value.formattedHourlyDuration())
} // red/green percentages } // red/green percentages
WIN_RATIO, ROI -> { WIN_RATIO, ROI, RISK_OF_RUIN -> {
val color = if (value * 100 >= this.threshold) R.color.green else R.color.red val color = if (value * 100 >= this.threshold) R.color.green else R.color.red
return TextFormat("${(value * 100).formatted()}%", color) return TextFormat("${(value * 100).formatted()}%", color)
} // white amountsr } // white amountsr

@ -9,6 +9,8 @@ import net.pokeranalytics.android.model.interfaces.DatedValue
import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.ui.graph.DataSetFactory import net.pokeranalytics.android.ui.graph.DataSetFactory
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import java.util.* import java.util.*
import kotlin.collections.HashMap import kotlin.collections.HashMap
@ -48,7 +50,7 @@ import kotlin.collections.HashMap
* This class holds the results from the BankrollCalculator computations * This class holds the results from the BankrollCalculator computations
* It has all the information required for the Bankroll various displays * It has all the information required for the Bankroll various displays
*/ */
class BankrollReport(var setup: BankrollReportSetup) { class BankrollReport(var setup: BankrollReportSetup) : RowRepresentable {
/** /**
* The value of the bankroll * The value of the bankroll
@ -138,6 +140,15 @@ class BankrollReport(var setup: BankrollReportSetup) {
var evolutionItems: MutableList<DatedValue> = mutableListOf() var evolutionItems: MutableList<DatedValue> = mutableListOf()
private set private set
override val viewType: Int
get() {
return if (setup.bankroll == null) {
RowViewType.LEGEND_DEFAULT.ordinal
} else {
RowViewType.TITLE_VALUE_ARROW.ordinal
}
}
/** /**
* Adds a list of dated items to the evolution items used to get the bankroll graph * Adds a list of dated items to the evolution items used to get the bankroll graph
*/ */

@ -5,13 +5,27 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_bankroll.* import kotlinx.android.synthetic.main.fragment_bankroll.*
import kotlinx.android.synthetic.main.fragment_stats.recyclerView import kotlinx.android.synthetic.main.fragment_stats.recyclerView
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.bankroll.BankrollCalculator
import net.pokeranalytics.android.calculus.bankroll.BankrollReportSetup
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.realm.Bankroll
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable
import timber.log.Timber
class BankrollFragment : PokerAnalyticsFragment() { class BankrollFragment : PokerAnalyticsFragment(), StaticRowRepresentableDataSource, RowRepresentableDelegate {
companion object { companion object {
@ -27,6 +41,9 @@ class BankrollFragment : PokerAnalyticsFragment() {
} }
private lateinit var parentActivity: PokerAnalyticsActivity private lateinit var parentActivity: PokerAnalyticsActivity
private lateinit var bankrollAdapter: RowRepresentableAdapter
private lateinit var bankrolls: RealmResults<Bankroll>
private var rows: ArrayList<RowRepresentable> = ArrayList()
// Life Cycle // Life Cycle
@ -36,11 +53,21 @@ class BankrollFragment : PokerAnalyticsFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initData()
initUI() initUI()
initData()
}
override fun adapterRows(): List<RowRepresentable>? {
Timber.d("adapterRows: ${rows.size}")
return rows
} }
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
}
// Business // Business
/** /**
@ -48,6 +75,39 @@ class BankrollFragment : PokerAnalyticsFragment() {
*/ */
private fun initData() { private fun initData() {
// Graph
//rows.add(GraphRow(report, Stat.NET_RESULT))
// Global
val start = System.currentTimeMillis()
val globalBankrollReportSetup = BankrollReportSetup()
val globalBankrollReport = BankrollCalculator.computeReport(globalBankrollReportSetup)
Timber.d("bankrollReport: ${globalBankrollReport.total}")
rows.add(globalBankrollReport)
// Bankrolls
rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.bankrolls))
bankrolls = LiveData.BANKROLL.items(getRealm()) as RealmResults<Bankroll>
Timber.d("Bankrolls: ${bankrolls.size}")
bankrolls.forEach {
val bankrollReportSetup = BankrollReportSetup(it)
val bankrollReport = BankrollCalculator.computeReport(bankrollReportSetup)
val computedStat = ComputedStat(Stat.NET_RESULT, bankrollReport.total)
rows.add(CustomizableRowRepresentable(RowViewType.TITLE_VALUE_ARROW, title = it.name, computedStat = computedStat))
}
Timber.d("Done in: ${System.currentTimeMillis() - start}ms")
Timber.d("initData: ${rows.size} rows")
} }
/** /**
@ -63,10 +123,12 @@ class BankrollFragment : PokerAnalyticsFragment() {
val viewManager = LinearLayoutManager(requireContext()) val viewManager = LinearLayoutManager(requireContext())
bankrollAdapter = RowRepresentableAdapter(this, this)
recyclerView.apply { recyclerView.apply {
setHasFixedSize(true) setHasFixedSize(true)
layoutManager = viewManager layoutManager = viewManager
//adapter = statsAdapter adapter = bankrollAdapter
} }
} }

@ -20,6 +20,9 @@ import com.github.mikephil.charting.data.LineDataSet
import kotlinx.android.synthetic.main.row_history_session.view.* import kotlinx.android.synthetic.main.row_history_session.view.*
import kotlinx.android.synthetic.main.row_transaction.view.* import kotlinx.android.synthetic.main.row_transaction.view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.ComputedStat
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.calculus.bankroll.BankrollReport
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.model.realm.Transaction
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
@ -75,6 +78,7 @@ enum class RowViewType(private var layoutRes: Int) {
STATS(R.layout.row_stats_title_value), STATS(R.layout.row_stats_title_value),
STATS_DOUBLE(R.layout.row_stats_double), STATS_DOUBLE(R.layout.row_stats_double),
GRAPH(R.layout.row_graph), GRAPH(R.layout.row_graph),
LEGEND_DEFAULT(R.layout.row_legend_default),
// Separator // Separator
SEPARATOR(R.layout.row_separator); SEPARATOR(R.layout.row_separator);
@ -110,6 +114,7 @@ enum class RowViewType(private var layoutRes: Int) {
STATS -> StatsTitleValueViewHolder(layout) STATS -> StatsTitleValueViewHolder(layout)
STATS_DOUBLE -> StatsDoubleViewHolder(layout) STATS_DOUBLE -> StatsDoubleViewHolder(layout)
GRAPH -> GraphViewHolder(layout) GRAPH -> GraphViewHolder(layout)
LEGEND_DEFAULT -> LegendDefaultViewHolder(layout)
// Separator // Separator
SEPARATOR -> SeparatorViewHolder(layout) SEPARATOR -> SeparatorViewHolder(layout)
@ -306,7 +311,7 @@ enum class RowViewType(private var layoutRes: Int) {
} }
/** /**
* Display a stat * Display a graph
*/ */
inner class GraphViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), inner class GraphViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder { BindableHolder {
@ -355,6 +360,32 @@ enum class RowViewType(private var layoutRes: Int) {
} }
} }
/**
* Display a legend
*/
inner class LegendDefaultViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
BindableHolder {
override fun bind(position: Int, row: RowRepresentable, adapter: RowRepresentableAdapter) {
if (row is BankrollReport) {
itemView.findViewById<AppCompatTextView>(R.id.stat1Name)?.let {
it.text = itemView.context.getString(R.string.total)
}
itemView.findViewById<AppCompatTextView>(R.id.stat1Value)?.let {
val formattedStat = ComputedStat(Stat.NET_RESULT, row.total).format()
it.setTextFormat(formattedStat, itemView.context)
}
itemView.findViewById<AppCompatTextView>(R.id.stat2Name)?.let {
it.text = itemView.context.getString(R.string.risk_of_ruin)
}
itemView.findViewById<AppCompatTextView>(R.id.stat2Value)?.let {
val riskOfRuin = row.riskOfRuin ?: 0.0
val formattedStat = ComputedStat(Stat.RISK_OF_RUIN, riskOfRuin).format()
it.setTextFormat(formattedStat, itemView.context)
}
}
}
}
/** /**
* Display a button in a row * Display a button in a row

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat1Name"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toTopOf="parent"
tools:text="NET RESULT" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat1Value"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsValue"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/stat2Value"
app:layout_constraintStart_toStartOf="@+id/guidelineStart"
app:layout_constraintTop_toBottomOf="@+id/stat1Name"
tools:text="$2000" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat2Name"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsTitle"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toStartOf="@+id/nextArrow"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/stat1Name"
app:layout_constraintTop_toTopOf="parent"
tools:text="NET RESULT" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/stat2Value"
style="@style/PokerAnalyticsTheme.TextView.LegendStatsValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/nextArrow"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@+id/stat1Value"
app:layout_constraintTop_toBottomOf="@id/stat2Name"
tools:text="$2000000000" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/nextArrow"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_arrow_right"
android:tint="@color/gray_light"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/guidelineEnd"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="16dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guidelineEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save