Skip to content

Commit

Permalink
Merge branch 'release/v3.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
SamAmco committed Jun 2, 2023
2 parents ab5dfbc + 5d279fd commit 3200183
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 35 deletions.
16 changes: 8 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.763.0)
aws-sdk-core (3.172.0)
aws-partitions (1.773.0)
aws-sdk-core (3.174.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.64.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (1.65.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.122.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-s3 (1.123.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (1.5.2)
Expand Down Expand Up @@ -65,7 +65,7 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastimage (2.2.7)
fastlane (2.206.2)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
Expand Down Expand Up @@ -106,7 +106,7 @@ GEM
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.41.0)
google-apis-androidpublisher_v3 (0.42.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.0)
addressable (~> 2.5, >= 2.5.1)
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ android {
applicationId "com.samco.trackandgraph"
minSdkVersion 23
targetSdkVersion 33
versionCode 300301
versionName "3.3.1"
versionCode 300400
versionName "3.4.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,11 @@ fun GraphStatTypeSelector(

val spinnerItems = mapOf(
GraphStatType.LINE_GRAPH to stringResource(id = R.string.graph_type_line_graph),
GraphStatType.BAR_CHART to stringResource(id = R.string.graph_type_bar_chart),
GraphStatType.PIE_CHART to stringResource(id = R.string.graph_type_pie_chart),
GraphStatType.AVERAGE_TIME_BETWEEN to stringResource(id = R.string.graph_type_average_time_between),
GraphStatType.TIME_HISTOGRAM to stringResource(id = R.string.graph_type_time_histogram),
GraphStatType.LAST_VALUE to stringResource(id = R.string.graph_type_last_value),
GraphStatType.BAR_CHART to stringResource(id = R.string.graph_type_bar_chart),
)

TextMapSpinner(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class BarChartDataFactory @Inject constructor(
fun getBarData(
timeHelper: TimeHelper,
dataSample: DataSample,
endTime: ZonedDateTime,
endTime: ZonedDateTime?,
barSize: BarChartBarPeriod,
duration: Duration?,
sumByCount: Boolean,
Expand All @@ -102,36 +102,41 @@ class BarChartDataFactory @Inject constructor(
val barDates = mutableListOf<ZonedDateTime>()
val barValuesByLabel = mutableMapOf<String, MutableList<Double>>()
val iterator = dataSample.iterator()

//First find the last end time of the last bar
val roundedEndTime = timeHelper.findEndOfTemporal(
endTime,
barSize.asTemporalAmount()
)

barDates.add(roundedEndTime)

val endTimeMinusDuration = duration?.let { roundedEndTime.minus(it) }

val barPeriod = barSize.asTemporalAmount()

var currentBarStartTime = roundedEndTime.minus(barPeriod)
var currentBarEndTime = roundedEndTime
//Some variables we will calculate as soon as we have the first data point
// and use to iterate backwards from the end time grouping the data points into bars
var roundedEndTime: ZonedDateTime? = null
var endTimeMinusDuration: ZonedDateTime? = null
var currentBarStartTime: ZonedDateTime? = null
var currentBarEndTime: ZonedDateTime? = null

//Then count backwards from the last end time to the start time of the duration
while (iterator.hasNext()) {
//Grab the next data point to be placed
val next = iterator.next()
val timestamp = timeHelper.toZonedDateTime(next.timestamp)

//If we were passed a null end time find the end time of the first data point
// instead
if (roundedEndTime == null) {
roundedEndTime = endTime?.let {
timeHelper.findEndOfTemporal(it, barSize.asTemporalAmount())
} ?: timeHelper.findEndOfTemporal(timestamp, barSize.asTemporalAmount())
currentBarStartTime = roundedEndTime.minus(barPeriod)
currentBarEndTime = roundedEndTime
endTimeMinusDuration = duration?.let { roundedEndTime.minus(it) }
barDates.add(roundedEndTime)
}

//If the next data point is before the start of the duration we are interested in, we
// can stop
if (endTimeMinusDuration != null && timestamp.isBefore(endTimeMinusDuration)) break

while (timestamp.isBefore(currentBarStartTime)) {
//we have reached the end of the current bar, so we need to move to the next one
currentBarStartTime = currentBarStartTime.minus(barPeriod)
currentBarEndTime = currentBarEndTime.minus(barPeriod)
currentBarStartTime = currentBarStartTime!!.minus(barPeriod)
currentBarEndTime = currentBarEndTime!!.minus(barPeriod)
barDates.add(currentBarEndTime)
}

Expand Down Expand Up @@ -215,7 +220,7 @@ class BarChartDataFactory @Inject constructor(
private fun getBarDataWithYAxisParams(
timeHelper: TimeHelper,
dataSample: DataSample,
endTime: ZonedDateTime,
endTime: ZonedDateTime?,
config: BarChart
): BarDataWithYAxisParams {

Expand Down Expand Up @@ -254,12 +259,17 @@ class BarChartDataFactory @Inject constructor(
onDataSampled: (List<DataPoint>) -> Unit
): IBarChartData {
val dataSample = dataInteractor.getDataSampleForFeatureId(config.featureId)

if (!dataSample.iterator().hasNext()) return object : IBarChartData {
override val state = IGraphStatViewData.State.READY
override val graphOrStat = graphOrStat
}

try {
//TODO basically everywhere you see zone id i think you might wanna use time helper
// and inject it.
val timeHelper = TimeHelper(GlobalAggregationPreferences)
val endTime = config.endDate?.let { timeHelper.toZonedDateTime(it) }
?: ZonedDateTime.now()

val barData = withContext(ioDispatcher) {
getBarDataWithYAxisParams(
Expand All @@ -276,7 +286,7 @@ class BarChartDataFactory @Inject constructor(
override val xDates = barData.dates
override val bars = barData.bars
override val durationBasedRange = dataSample.dataSampleProperties.isDuration
override val endTime = endTime
override val endTime = endTime ?: barData.dates.last()
override val bounds = barData.bounds
override val yAxisRangeParameters = barData.yAxisParameters
override val state = IGraphStatViewData.State.READY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.samco.trackandgraph.graphstatview.factories.viewdto
import com.androidplot.xy.RectRegion
import com.androidplot.xy.SimpleXYSeries
import com.androidplot.xy.StepMode
import org.threeten.bp.Duration
import org.threeten.bp.Period
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.temporal.TemporalAmount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ fun DateTimeButtonRow(
odt
.withHour(selectedDateTime.hour)
.withMinute(selectedDateTime.minute)
.withSecond(selectedDateTime.second)
.withNano(selectedDateTime.nano)
)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class BarChartDataFactoryTest {
)

@Test
fun `test bar chart, no label, no end time, no duration`() {
fun `test bar chart, no label, end time, no duration`() {
//PREPARE
val end = ZonedDateTime.now().withHour(22)

Expand Down Expand Up @@ -71,7 +71,7 @@ class BarChartDataFactoryTest {
}

@Test
fun `test bar chart, with multiple labels, no end time, no duration`() {
fun `test bar chart, with multiple labels, end time, no duration`() {
//PREPARE
val end = ZonedDateTime.now().withHour(22)

Expand Down Expand Up @@ -332,6 +332,47 @@ class BarChartDataFactoryTest {
assertEquals(18, barData.bounds.maxY.toInt())
}

@Test
fun `test bar chart no end time`() {
//PREPARE
val end = ZonedDateTime.now().withHour(22)

val dataSample = DataSample.fromSequence(
listOf(
dp(end.minusHours(1)),
dp(end.minusDays(1)),
dp(end.minusDays(2).minusHours(1)),
dp(end.minusDays(2).minusHours(2)),
dp(end.minusDays(2).minusHours(3))
).asSequence()
)

//EXECUTE
val barData = BarChartDataFactory.getBarData(
timeHelper = defaultTimeHelper,
dataSample = dataSample,
endTime = null,
barSize = BarChartBarPeriod.DAY,
duration = null,
sumByCount = false,
yRangeType = YRangeType.DYNAMIC,
yTo = 0.0,
scale = 1.0
)

//VERIFY
val endOfDay = end
.plusDays(1)
.withHour(0)
.withMinute(0)
.withSecond(0)
.withNano(0)
.minusNanos(1)
assertEquals(1, barData.bars.size)
assertEquals(listOf(3.0, 1.0, 1.0), barData.bars[0].getyVals())
assertEquals(listOf(endOfDay.minusDays(2), endOfDay.minusDays(1), endOfDay), barData.dates)
}

private fun dp(
time: ZonedDateTime,
value: Double = 1.0,
Expand Down
4 changes: 2 additions & 2 deletions base/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,8 @@
<string name="data_point_tutorial_page_3_description">Use labels if you want to group the data points</string>
<string name="data_point_tutorial_page_3_hint">(Hint: If you want to add more context or description use the note instead of the label field)</string>
<string name="help">Help</string>
<string name="faq_page_link" translatable="false">https://github.com/SamAmco/track-and-graph/blob/release/v3.3.1/docs/faq/index.md#faq</string>
<string name="faq_page_link_1" translatable="false">https://github.com/SamAmco/track-and-graph/blob/release/v3.3.1/docs/faq/faq_1.md#how-do-i-start-tracking-something</string>
<string name="faq_page_link" translatable="false">https://github.com/SamAmco/track-and-graph/blob/release/v3.4.0/docs/faq/index.md#faq</string>
<string name="faq_page_link_1" translatable="false">https://github.com/SamAmco/track-and-graph/blob/release/v3.4.0/docs/faq/faq_1.md#how-do-i-start-tracking-something</string>
<string name="advanced_options">Advanced options</string>
<string name="type_colon">"Type: "</string>
<string name="order_colon">"Order: "</string>
Expand Down
25 changes: 25 additions & 0 deletions docs/faq/faq_3_5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# How do bar charts work?

Bar charts in Track & Graph provide a visual representation of how your tracked data fluctuates over time. While they share similarities with line graphs, bar charts offer an additional feature: displaying the ratio of each label, similar to a Pie Chart, within each bar. The disadvantage is that bar charts do not support showing multiple tracker on the same graphs where as line graphs do.

Let's consider an example where you sell T-Shirts in different sizes: Small, Medium, and Large. Suppose you want to track the daily sales and the distribution of each size. To set up your bar chart select the "Daily" option for the bar period like so:

<img src="images/faq_3_5_1.png" width="50%">

Now you can create a bar chart like the one below:

<img src="images/faq_3_5_2.png" width="50%">

---

However, if your tracking system assigns a value of 1 for Small, 2 for Medium, and 3 for Large T-Shirts, the bar chart will display the sales of a Large T-Shirt as 3 instead of 1. To rectify this, check the box labeled "Check here to count the number of data points tracked rather than the total of their values." This option ignores the assigned values and counts each data point as 1 on the bar chart.

Additionally, you can utilize the scale variable to multiply all the values by a constant factor.

After creating your bar chart, you can tap on it to view it in full-screen mode. The notes section below the chart displays any relevant notes from the data points used. Tapping on a note highlights the corresponding bar on the chart. Moreover, tapping directly on a bar provides further details about it.

<img src="images/faq_3_5_3.png" width="50%">

---

The labels are ordered such that the label with the highest cumulative value is first (at the bottom of the bar chart) and the label with the smallest cumulative value is last (at the top of the bar chart)
Binary file added docs/faq/images/faq_3_5_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/faq/images/faq_3_5_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/faq/images/faq_3_5_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/faq/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
2. [Pie charts](faq_3_2.md)
3. [Stats](faq_3_3.md)
4. [Time histograms](faq_3_4.md)
5. [Bar charts](faq_3_5.md)
4. [How do notes work?](faq_4.md)
5. [How do i read the timestamps](faq_5.md)
4 changes: 4 additions & 0 deletions fastlane/metadata/android/en-GB/changelogs/300400.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- Add Bar charts
- Fix bug graphs not updating and wrong graph showing on scroll


0 comments on commit 3200183

Please sign in to comment.