From 7d8efb34c61e21e4a38c4949295ec857e039d265 Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 29 Feb 2024 18:16:50 +1100 Subject: [PATCH 1/2] Update TrafficBarChartViewHolder.kt Fix for week, and year bars starting above zero. --- .../refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt index 92e741fce46d..fe7caa691820 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt @@ -131,6 +131,7 @@ class TrafficBarChartViewHolder(parent: ViewGroup) : BlockListItemViewHolder( setDrawZeroLine(false) setDrawLabels(false) setDrawAxisLine(false) + axisMinimum = 0f } chart.axisRight.apply { From fbd990067f4110211a220c8b26f5ec27d2d91cac Mon Sep 17 00:00:00 2001 From: Ravi Date: Thu, 29 Feb 2024 18:53:26 +1100 Subject: [PATCH 2/2] Fix detail views bar chart labels Created a separate TrafficBarChartItem to avoid collision with detail views bar chart --- .../ui/stats/refresh/BlockDiffCallback.kt | 2 ++ .../lists/sections/BlockListAdapter.kt | 7 +++-- .../refresh/lists/sections/BlockListItem.kt | 16 ++++++++++ .../traffic/TrafficBarChartViewHolder.kt | 12 +++---- .../sections/traffic/TrafficOverviewMapper.kt | 6 ++-- .../refresh/utils/BarChartLabelFormatter.kt | 2 +- .../ui/stats/refresh/utils/StatsUtils.kt | 31 +++++++++++++++++++ 7 files changed, 64 insertions(+), 12 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/BlockDiffCallback.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/BlockDiffCallback.kt index 136e2ebf0af9..5912d1a1bae4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/BlockDiffCallback.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/BlockDiffCallback.kt @@ -15,6 +15,7 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.TabsI import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.ACTION_CARD import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.ACTIVITY_ITEM import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.BAR_CHART +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.TRAFFIC_BAR_CHART import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.BIG_TITLE import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.CHART_LEGEND import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.CHART_LEGENDS_BLUE @@ -69,6 +70,7 @@ class BlockDiffCallback( COLUMNS, CHIPS, BAR_CHART, + TRAFFIC_BAR_CHART, PIE_CHART, LINE_CHART, ACTIVITY_ITEM, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListAdapter.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListAdapter.kt index e5b70b631637..aba687be74fe 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListAdapter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListAdapter.kt @@ -8,6 +8,7 @@ import org.wordpress.android.ui.stats.refresh.BlockDiffCallback.BlockListPayload import org.wordpress.android.ui.stats.refresh.BlockDiffCallback.BlockListPayload.TAB_CHANGED import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.ActivityItem import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.BarChartItem +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.TrafficBarChartItem import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.BigTitle import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.ChartLegend import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.ChartLegendsBlue @@ -41,6 +42,7 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Title import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.ACTION_CARD import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.ACTIVITY_ITEM import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.BAR_CHART +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.TRAFFIC_BAR_CHART import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.BIG_TITLE import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.CHART_LEGEND import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.CHART_LEGENDS_BLUE @@ -150,7 +152,8 @@ class BlockListAdapter( COLUMNS -> if (trafficTabEnabled) TrafficFourColumnsViewHolder(parent) else FourColumnsViewHolder(parent) CHIPS -> ChipsViewHolder(parent) LINK -> LinkViewHolder(parent) - BAR_CHART -> if (trafficTabEnabled) TrafficBarChartViewHolder(parent) else BarChartViewHolder(parent) + BAR_CHART -> BarChartViewHolder(parent) + TRAFFIC_BAR_CHART -> TrafficBarChartViewHolder(parent) PIE_CHART -> PieChartViewHolder(parent) LINE_CHART -> LineChartViewHolder(parent) CHART_LEGEND -> ChartLegendViewHolder(parent) @@ -202,7 +205,7 @@ class BlockListAdapter( is ChipsViewHolder -> holder.bind(item as Chips) is LinkViewHolder -> holder.bind(item as Link) is BarChartViewHolder -> holder.bind(item as BarChartItem) - is TrafficBarChartViewHolder -> holder.bind(item as BarChartItem) + is TrafficBarChartViewHolder -> holder.bind(item as TrafficBarChartItem) is PieChartViewHolder -> holder.bind(item as PieChartItem) is LineChartViewHolder -> holder.bind(item as LineChartItem) is ChartLegendViewHolder -> holder.bind(item as ChartLegend) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListItem.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListItem.kt index 222fc9b6bb50..cab6f03e2e9b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListItem.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/BlockListItem.kt @@ -39,6 +39,7 @@ import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type. import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.TEXT import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.TITLE import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.TITLE_WITH_MORE +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.TRAFFIC_BAR_CHART import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.VALUES_ITEM import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.VALUE_ITEM import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.Type.VALUE_WITH_CHART_ITEM @@ -71,6 +72,7 @@ sealed class BlockListItem(val type: Type) { CHIPS, LINK, BAR_CHART, + TRAFFIC_BAR_CHART, PIE_CHART, LINE_CHART, CHART_LEGEND, @@ -266,6 +268,20 @@ sealed class BlockListItem(val type: Type) { get() = entries.hashCode() } + data class TrafficBarChartItem( + val entries: List, + val overlappingEntries: List? = null, + val selectedItem: String? = null, + val onBarSelected: ((period: String?) -> Unit)? = null, + val onBarChartDrawn: ((visibleBarCount: Int) -> Unit)? = null, + val entryContentDescriptions: List + ) : BlockListItem(TRAFFIC_BAR_CHART) { + data class Bar(val label: String, val id: String, val value: Int) + + override val itemId: Int + get() = entries.hashCode() + } + data class PieChartItem( val entries: List, val totalLabel: String, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt index fe7caa691820..14a1d15e47d5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficBarChartViewHolder.kt @@ -18,7 +18,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.wordpress.android.R import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem -import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.BarChartItem.Bar +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.TrafficBarChartItem.Bar import org.wordpress.android.ui.stats.refresh.lists.sections.viewholders.BlockListItemViewHolder import org.wordpress.android.ui.stats.refresh.utils.BarChartAccessibilityHelper import org.wordpress.android.ui.stats.refresh.utils.BarChartLabelFormatter @@ -35,7 +35,7 @@ class TrafficBarChartViewHolder(parent: ViewGroup) : BlockListItemViewHolder( private lateinit var accessibilityHelper: BarChartAccessibilityHelper - fun bind(item: BlockListItem.BarChartItem) { + fun bind(item: BlockListItem.TrafficBarChartItem) { chart.setNoDataText("") coroutineScope.launch { delay(50) @@ -67,7 +67,7 @@ class TrafficBarChartViewHolder(parent: ViewGroup) : BlockListItemViewHolder( } } - private fun BarChart.draw(item: BlockListItem.BarChartItem): Int { + private fun BarChart.draw(item: BlockListItem.TrafficBarChartItem): Int { resetChart() data = BarData(getData(item)) @@ -82,7 +82,7 @@ class TrafficBarChartViewHolder(parent: ViewGroup) : BlockListItemViewHolder( private fun hasData(entries: List) = entries.isNotEmpty() && entries.any { it.value > 0 } - private fun getData(item: BlockListItem.BarChartItem): List { + private fun getData(item: BlockListItem.TrafficBarChartItem): List { val minColumnCount = 5 val graphWidth = DisplayUtils.pxToDp(chart.context, chart.width) @@ -122,7 +122,7 @@ class TrafficBarChartViewHolder(parent: ViewGroup) : BlockListItemViewHolder( } } - private fun configureYAxis(item: BlockListItem.BarChartItem) { + private fun configureYAxis(item: BlockListItem.TrafficBarChartItem) { val minYValue = 4f val maxYValue = item.entries.maxByOrNull { it.value }?.value ?: 0 @@ -155,7 +155,7 @@ class TrafficBarChartViewHolder(parent: ViewGroup) : BlockListItemViewHolder( } } - private fun configureXAxis(item: BlockListItem.BarChartItem) { + private fun configureXAxis(item: BlockListItem.TrafficBarChartItem) { chart.xAxis.apply { granularity = 1f setDrawAxisLine(false) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficOverviewMapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficOverviewMapper.kt index 4587edf22f4c..b9f3e192c267 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficOverviewMapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/lists/sections/traffic/TrafficOverviewMapper.kt @@ -95,7 +95,7 @@ class TrafficOverviewMapper @Inject constructor( Comments -> it.comments else -> 0L } - BlockListItem.BarChartItem.Bar( + BlockListItem.TrafficBarChartItem.Bar( statsDateFormatter.printTrafficGranularDate(it.period, statsGranularity), it.period, value.toInt() @@ -111,13 +111,13 @@ class TrafficOverviewMapper @Inject constructor( else -> R.string.stats_views } - val contentDescriptions = statsUtils.getBarChartEntryContentDescriptions( + val contentDescriptions = statsUtils.getTrafficBarChartEntryContentDescriptions( entryType, chartItems ) result.add( - BlockListItem.BarChartItem( + BlockListItem.TrafficBarChartItem( chartItems, selectedItem = selectedItemPeriod, onBarSelected = onBarSelected, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/BarChartLabelFormatter.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/BarChartLabelFormatter.kt index 207910902583..3a82b457604d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/BarChartLabelFormatter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/BarChartLabelFormatter.kt @@ -2,7 +2,7 @@ package org.wordpress.android.ui.stats.refresh.utils import com.github.mikephil.charting.components.AxisBase import com.github.mikephil.charting.formatter.ValueFormatter -import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.BarChartItem.Bar +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.TrafficBarChartItem.Bar import javax.inject.Inject class BarChartLabelFormatter @Inject constructor( diff --git a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsUtils.kt b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsUtils.kt index f328c0a95e71..3f14f0dc1b86 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsUtils.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/stats/refresh/utils/StatsUtils.kt @@ -2,6 +2,7 @@ package org.wordpress.android.ui.stats.refresh.utils import androidx.annotation.StringRes import org.wordpress.android.R +import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.BarChartItem.Bar import org.wordpress.android.ui.stats.refresh.lists.sections.BlockListItem.LineChartItem.Line import org.wordpress.android.util.LocaleManagerWrapper @@ -168,6 +169,36 @@ class StatsUtils @Inject constructor( return contentDescriptions } + fun getTrafficBarChartEntryContentDescriptions( + @StringRes entryType: Int, + entries: List, + @StringRes overlappingEntryType: Int? = null, + overlappingEntries: List? = null + ): List { + val contentDescriptions = mutableListOf() + entries.forEachIndexed { index, bar -> + var contentDescription = resourceProvider.getString( + R.string.stats_bar_chart_accessibility_entry, + bar.label, + bar.value, + resourceProvider.getString(entryType) + ) + + overlappingEntries?.getOrNull(index)?.let { overlappingBar -> + overlappingEntryType?.let { + contentDescription += resourceProvider.getString( + R.string.stats_bar_chart_accessibility_overlapping_entry, + overlappingBar.value, + resourceProvider.getString(overlappingEntryType) + ) + } + } + + contentDescriptions.add(contentDescription) + } + return contentDescriptions + } + fun getLineChartEntryContentDescriptions( @StringRes entryType: Int, entries: List