Skip to content

Commit

Permalink
[feat] #40 통계 뷰 로직 작성 및 특정 부분 색상 지정
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan2dani committed Dec 5, 2023
1 parent 25a87c6 commit 54697a1
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.example.howdroid.presentation.chart

import android.os.Bundle
import android.view.View
import androidx.fragment.app.activityViewModels
import com.example.howdroid.R
import com.example.howdroid.databinding.FragmentChartStatisticBinding
import com.example.howdroid.util.binding.BindingFragment

class ChartFeedbackFragment :
BindingFragment<FragmentChartStatisticBinding>(R.layout.fragment_chart_feedback) {
private val viewModel: ChartViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package com.example.howdroid.presentation.chart
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.howdroid.R
import com.example.howdroid.databinding.FragmentChartBinding
import com.example.howdroid.util.binding.BindingFragment
import com.google.android.material.tabs.TabLayoutMediator

class ChartFragment : BindingFragment<FragmentChartBinding>(R.layout.fragment_chart) {
private val viewModel: ChartViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ package com.example.howdroid.presentation.chart

import android.graphics.Typeface
import android.os.Bundle
import android.text.Html
import android.view.View
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.example.howdroid.R
import com.example.howdroid.data.model.response.ResponseStatistic
import com.example.howdroid.databinding.FragmentChartStatisticBinding
import com.example.howdroid.util.binding.BindingFragment
import com.github.mikephil.charting.charts.BarChart
Expand All @@ -16,23 +21,65 @@ 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.formatter.ValueFormatter
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class ChartStatisticFragment :
BindingFragment<FragmentChartStatisticBinding>(R.layout.fragment_chart_statistic) {
private val viewModel: ChartViewModel by activityViewModels()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val achievementRateBarChart: BarChart = binding.barChartAchievementRate
val barList = setAchievementRateData(achievementRateBarChart)
setAchievementRateBarChart(achievementRateBarChart, barList)

val categoryRatePieChart: PieChart = binding.pieChartCategoryRate
val categoryPieList = setCategporyRateData()
setCategoryRatePieChart(categoryRatePieChart, categoryPieList)
collectData()
}

val failTagRatePieChart: PieChart = binding.pieChartFailTagRate
val failTagPieList = setFailTagRateData()
setFailTagRatePieChart(failTagRatePieChart, failTagPieList)
private fun collectData() {
viewModel.rateOfChange.flowWithLifecycle(lifecycle).onEach { rateOfChange ->
val rateString = String.format("%d%%", rateOfChange)
val formattedString = getString(
R.string.chart_statistic_achievement_rate_des,
Html.fromHtml(rateString, Html.FROM_HTML_MODE_LEGACY)
)
binding.tvAchievementRateDes.text =
Html.fromHtml(formattedString, Html.FROM_HTML_MODE_LEGACY)
}.launchIn(lifecycleScope)
viewModel.nowToDoAchievementRate.flowWithLifecycle(lifecycle)
.onEach { nowToDoAchievementRate ->
val achievementRateBarChart: BarChart = binding.barChartAchievementRate
val barList =
setAchievementRateData(
viewModel.preToDoAchievementRate.value,
nowToDoAchievementRate
)
setAchievementRateBarChart(achievementRateBarChart, barList)
}.launchIn(lifecycleScope)
viewModel.nowBestCategory.flowWithLifecycle(lifecycle).onEach { nowBestCategory ->
val content = getString(
R.string.chart_statistic_category_des,
Html.fromHtml(nowBestCategory, Html.FROM_HTML_MODE_LEGACY)
)
binding.tvCategoryRateDes.text = Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY)
}.launchIn(lifecycleScope)
viewModel.nowCategoryRateList.flowWithLifecycle(lifecycle).onEach { nowCategoryRateList ->
val categoryRatePieChart: PieChart = binding.pieChartCategoryRate
val categoryPieList = setCategoryRateData(nowCategoryRateList)
setCategoryRatePieChart(categoryRatePieChart, categoryPieList)
}.launchIn(lifecycleScope)
viewModel.nowWorstFailTag.flowWithLifecycle(lifecycle).onEach { nowWorstFailTag ->
val content = getString(
R.string.chart_statistic_fail_tag_des,
Html.fromHtml(nowWorstFailTag, Html.FROM_HTML_MODE_LEGACY)
)
binding.tvFailTagRateDes.text = Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY)
}.launchIn(lifecycleScope)
viewModel.nowFailTagList.flowWithLifecycle(lifecycle).onEach { nowFailTagList ->
val failTagRatePieChart: PieChart = binding.pieChartFailTagRate
val failTagPieList = setFailTagRateData(nowFailTagList)
setFailTagRatePieChart(failTagRatePieChart, failTagPieList)
}.launchIn(lifecycleScope)
}

private fun setAchievementRateBarChart(barChart: BarChart, barList: ArrayList<BarEntry>) {
Expand Down Expand Up @@ -90,11 +137,10 @@ class ChartStatisticFragment :
barChart.invalidate()
}

private fun setAchievementRateData(barChart: BarChart): ArrayList<BarEntry> {
private fun setAchievementRateData(prePercent: Int, nowPercent: Int): ArrayList<BarEntry> {
val barList = ArrayList<BarEntry>()
// 임시 데이터 연동
barList.add(BarEntry(1f, 60f))
barList.add(BarEntry(2f, 100f))
barList.add(BarEntry(1f, prePercent.toFloat()))
barList.add(BarEntry(2f, nowPercent.toFloat()))

return barList
}
Expand Down Expand Up @@ -135,13 +181,17 @@ class ChartStatisticFragment :
pieChart.invalidate()
}

private fun setCategporyRateData(): ArrayList<PieEntry> {
private fun setCategoryRateData(nowCategoryRateList: MutableList<ResponseStatistic.NowCategoryDate>): ArrayList<PieEntry> {
val pieList = ArrayList<PieEntry>()

pieList.add(PieEntry(28f, "취미"))
pieList.add(PieEntry(32f, "운동"))
pieList.add(PieEntry(40f, "공부"))

for (nowCategoryRate in nowCategoryRateList) {
pieList.add(
PieEntry(
nowCategoryRate.nowCategoryRate.toFloat(),
nowCategoryRate.nowCategory
)
)
}
return pieList
}

Expand Down Expand Up @@ -183,14 +233,12 @@ class ChartStatisticFragment :
pieChart.invalidate()
}

private fun setFailTagRateData(): ArrayList<PieEntry> {
private fun setFailTagRateData(failTagList: MutableList<ResponseStatistic.NowFailtag>): ArrayList<PieEntry> {
val pieList = ArrayList<PieEntry>()

pieList.add(PieEntry(5f, ""))
pieList.add(PieEntry(10f, "일정변경"))
pieList.add(PieEntry(20f, "갑작스런일정"))
pieList.add(PieEntry(30f, "무리한계획"))
pieList.add(PieEntry(35f, "의지박약"))
for (failTag in failTagList) {
pieList.add(PieEntry(failTag.nowFailtagRate.toFloat(), failTag.nowFailtag))
}

return pieList
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.howdroid.presentation.chart

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.howdroid.data.model.response.ResponseStatistic
import com.example.howdroid.domain.repository.ChartRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import java.time.LocalDate
import javax.inject.Inject

@HiltViewModel
class ChartViewModel @Inject constructor(
private val chartRepository: ChartRepository
) : ViewModel() {
private val _preToDoAchievementRate = MutableStateFlow(0)
val preToDoAchievementRate get() = _preToDoAchievementRate.asStateFlow()
private val _nowToDoAchievementRate = MutableStateFlow(0)
val nowToDoAchievementRate get() = _nowToDoAchievementRate.asStateFlow()
private val _rateOfChange = MutableStateFlow(0)
val rateOfChange get() = _rateOfChange.asStateFlow()
private val _nowCategoryRateList =
MutableStateFlow<MutableList<ResponseStatistic.NowCategoryDate>>(
mutableListOf()
)
val nowCategoryRateList get() = _nowCategoryRateList.asStateFlow()
private val _nowBestCategory = MutableStateFlow("")
val nowBestCategory get() = _nowBestCategory.asStateFlow()
private val _nowFailTagList = MutableStateFlow<MutableList<ResponseStatistic.NowFailtag>>(
mutableListOf()
)
val nowFailTagList get() = _nowFailTagList.asStateFlow()
private val _nowWorstFailTag = MutableStateFlow("")
val nowWorstFailTag get() = _nowWorstFailTag.asStateFlow()

init {
fetchStatistic()
}

// TODO 초기화 유사한 거 끼리 함수화
private fun fetchStatistic() {
val today = LocalDate.now()
viewModelScope.launch {
chartRepository.fetchStatistic(today.toString())
.onSuccess { chartInfo ->
val prePercent =
chartInfo.prevTodoDoneCnt.toFloat() / chartInfo.prevTodoCnt.toFloat() * 100
val nowPercent =
chartInfo.nowTodoDoneCnt.toFloat() / chartInfo.nowTodoCnt.toFloat() * 100
val totalPercent = prePercent + nowPercent
_preToDoAchievementRate.value =
(prePercent / totalPercent * 100).toInt()
_nowToDoAchievementRate.value = (nowPercent / totalPercent * 100).toInt()
_rateOfChange.value = chartInfo.rateOfChange
_nowCategoryRateList.value = chartInfo.nowCategoryDate.toMutableList()
_nowFailTagList.value = chartInfo.nowFailtagList.toMutableList()
_nowBestCategory.value = chartInfo.nowBestCategory
_nowWorstFailTag.value = chartInfo.nowWorstFailtag
}
.onFailure { throwable ->
Timber.e(throwable.message)
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ class HomeFragment :

private fun showPutFailTagBottomFragment() {
val bottomSheetFragment = PutFailTagBottomSheetFragment()
.apply { putDataToBundle() }
.apply {
val bundle = Bundle()
// TODO putDataToBundle() 삭제
val bundle = putDataToBundle()
bundle.putInt(TODO_ID, this@HomeFragment.toDoId)
arguments = bundle
}
Expand Down

0 comments on commit 54697a1

Please sign in to comment.