diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt index 93a97dc41..72e3c0479 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/FrequencyChart.kt @@ -29,6 +29,7 @@ import org.isoron.uhabits.core.utils.DateUtils.Companion.getShortWeekdayNames import org.isoron.uhabits.core.utils.DateUtils.Companion.getStartOfTodayCalendar import org.isoron.uhabits.core.utils.DateUtils.Companion.getStartOfTodayCalendarWithOffset import org.isoron.uhabits.core.utils.DateUtils.Companion.getWeekdaySequence +import org.isoron.uhabits.core.utils.DateUtils.Companion.getWeekdaysInMonth import org.isoron.uhabits.utils.ColorUtils.mixColors import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.toSimpleDataFormat @@ -166,6 +167,7 @@ class FrequencyChart : ScrollableChart { private fun drawColumn(canvas: Canvas, rect: RectF?, date: GregorianCalendar) { val values = frequency[Timestamp(date)] + val weekDaysInMonth = getWeekdaysInMonth(Timestamp(date)) val rowHeight = rect!!.height() / 8.0f prevRect!!.set(rect) val localeWeekdayList: Array = getWeekdaySequence(firstWeekday) @@ -174,7 +176,7 @@ class FrequencyChart : ScrollableChart { rect.offset(prevRect!!.left, prevRect!!.top + baseSize * j) val i = localeWeekdayList[j] % 7 if (values != null) - drawMarker(canvas, rect, values[i]) + drawMarker(canvas, rect, values[i], weekDaysInMonth[i]) rect.offset(0f, rowHeight) } drawFooter(canvas, rect, date) @@ -222,7 +224,7 @@ class FrequencyChart : ScrollableChart { canvas.drawLine(rGrid.left, rGrid.top, rGrid.right, rGrid.top, pGrid!!) } - private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?) { + private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?, frequency: Int) { // value can be negative when the entry is skipped val valueCopy = value?.let { max(0, it) } @@ -230,7 +232,8 @@ class FrequencyChart : ScrollableChart { // maximal allowed mark radius val maxRadius = (rect.height() - 2 * padding) / 2.0f // the real mark radius is scaled down by a factor depending on the maximal frequency - val scale = 1.0f / maxFreq * valueCopy!! + + val scale = 1.0f / frequency * valueCopy!! val radius = maxRadius * scale val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt()) pGraph!!.color = colors[colorIndex] diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/DateUtils.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/DateUtils.kt index 7c2c0a4fd..010b26e4a 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/DateUtils.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/utils/DateUtils.kt @@ -19,6 +19,7 @@ package org.isoron.uhabits.core.utils import org.isoron.uhabits.core.models.Timestamp +import java.time.YearMonth import java.util.Calendar import java.util.Calendar.DAY_OF_MONTH import java.util.Calendar.DAY_OF_WEEK @@ -178,6 +179,26 @@ abstract class DateUtils { return getWeekdayNames(GregorianCalendar.SHORT, firstWeekday) } + /** + * Returns a vector of Int representing the frequency of each weekday in a given month. + * + * @param startOfMonth a Timestamp representing the beginning of the month. + */ + @JvmStatic + fun getWeekdaysInMonth(startOfMonth: Timestamp): Array { + val month = startOfMonth.toCalendar()[Calendar.MONTH] + 1 + val year = startOfMonth.toCalendar()[Calendar.YEAR] + val weekday = startOfMonth.weekday + val extraWeekdays = YearMonth.of(year, month).lengthOfMonth() - 28 + + val freq = Array(7) { 4 } + for (day in weekday until weekday + extraWeekdays) { + freq[day % 7] = 5 + } + + return freq + } + @JvmStatic fun getToday(): Timestamp = Timestamp(getStartOfToday())