Skip to content

Commit

Permalink
Goal lines refactoring (#5258)
Browse files Browse the repository at this point in the history
**Story card:** None - bug fix

## Because

Needed to refactor monthIndexFromDateKey() function. 
This will be needed in a follow up PR that fixes a bug on the dashed
lines of the overdue chart

## This addresses

Refactor complete plus some additional work to simplify the goal lines
functionality and make it easier to follow

Changes:
- goalPeriodValue() renamed to getThreeMonthAverageAndImprovementRatio()
- improvement ratio is calculated inside the
getThreeMonthAverageAndImprovementRatio() rather than passing data
around
- simplified check for isEndMonthOfYear() (previously named
isLastDateKeysArrayMonthDec)
- improved variable naming
- monthIndexFromDateKey() uses built in javascript function
- calculateGoalUpwards() and calculateGoalDownwards() have parameter
names that match the data being passed (monthValue -> threeMonthAverage)
- correction to how the remaining months in the year is calculated: 
```
const monthsRemainingForYear = monthThreeIndex === 11 ? 12 : 11 - monthThreeIndex;
```

## Test instructions

Switch between this branch and the current master branch to check that
the figures are the same.
Note: there was a previous miscalculation on the goal lines.
When checking the figures are the same there might be a small chance
'this branch/PR' shows a figure that is 1% less than that shows on the
current master. This is correct - the master was +0.0083 higher than it
should have been after running the calculations. Figures are rounded so
there should be no change unless it crosses to the next integer.

To view the goal lines add the commented line to your reports.js file

``` 
const enabledRegions = {
      IN: ["state"], // add this line <-
      BD: ["organization", "state", "district"],
      ET: ["organization", "state"],
      LK: ["organization"],
    };
```
the line for copying
``` 
IN: ["state"], 
```

---------

Co-authored-by: Priyanga P Kini <[email protected]>
  • Loading branch information
jamiecarter7 and PriyangaPKini authored Sep 7, 2023
1 parent 7eead8b commit 8aa9209
Showing 1 changed file with 36 additions and 50 deletions.
86 changes: 36 additions & 50 deletions app/assets/javascripts/common/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -662,83 +662,70 @@ Reports = function ({
}

function calculateGoal(periodValues, goalDownwards) {
const { threeMonthAverage, monthThreeIndexOfYear } = goalPeriodValue(periodValues);
const improvementRatio = relativeImprovementRatio(monthThreeIndexOfYear);
const { threeMonthAverage, improvementRatio } = getThreeMonthAverageAndImprovementRatio(periodValues);

if (goalDownwards) {
return calculateGoalDownwards(threeMonthAverage, improvementRatio);
}
return calculateGoalUpwards(threeMonthAverage, improvementRatio);
}

function goalPeriodValue(periodValues) {
const dateKeysArray = Object.keys(periodValues);
function getThreeMonthAverageAndImprovementRatio(periodValues) {
const evaluationMonth = "Dec"
const dateKeys = Object.keys(periodValues);
const evaluationMonthKeys = dateKeys.filter((item) => item.includes(evaluationMonth));

const decemberKeys = dateKeysArray.filter((item) => item.includes("Dec"));
const isLastDateKeysArrayMonthDec =
monthIndexFromDateString(dateKeysArray[dateKeysArray.length - 1]) === 11;
if (isLastDateKeysArrayMonthDec) {
decemberKeys.splice(-1);
const [lastMonthKey] = dateKeys.slice(-1);
const isEndMonthOfYear = lastMonthKey.includes(evaluationMonth);
if (isEndMonthOfYear) {
evaluationMonthKeys.splice(-1);
}
const mostRecentDecemberKey = decemberKeys[decemberKeys.length - 1];
const indexOfLatestDecember = dateKeysArray.indexOf(mostRecentDecemberKey);

const mostEvaluationMonthKey = evaluationMonthKeys[evaluationMonthKeys.length - 1];
const mostEvaluationMonthKeyIndex = dateKeys.indexOf(mostEvaluationMonthKey);

const monthThreeDateKey =
indexOfLatestDecember < defaultMonthsRequired - 1
? dateKeysArray[defaultMonthsRequired - 1] // month 6
: mostRecentDecemberKey; // december
mostEvaluationMonthKeyIndex < defaultMonthsRequired - 1
? dateKeys[defaultMonthsRequired - 1] // month 6
: mostEvaluationMonthKey; // eveluation month

const monthThreeIndex = dateKeys.indexOf(monthThreeDateKey);

const monthThreeValue = periodValues[monthThreeDateKey];
const indexOfMonthThreeInDateKeys = dateKeysArray.indexOf(monthThreeDateKey);
const monthTwoValue = periodValues[dateKeysArray[indexOfMonthThreeInDateKeys - 1]];
const monthOneValue = periodValues[dateKeysArray[indexOfMonthThreeInDateKeys - 2]];
const monthTwoValue = periodValues[dateKeys[monthThreeIndex - 1]];
const monthOneValue = periodValues[dateKeys[monthThreeIndex - 2]];

const sumValues = monthOneValue + monthTwoValue + monthThreeValue;
const threeMonthAverage = sumValues === 0 ? 0 : sumValues / 3;

const monthThreeIndexOfYear = monthIndexFromDateKey(monthThreeDateKey);
const improvementRatio = relativeImprovementRatio(monthThreeIndexOfYear);

const monthThreeIndexOfYear = monthIndexFromDateString(monthThreeDateKey);
return {
threeMonthAverage,
monthThreeIndexOfYear,
improvementRatio,
};
}

function monthIndexFromDateString(dateString) {
const [month, year] = dateString.split("-");
const months = [
"jan",
"feb",
"mar",
"apr",
"may",
"jun",
"jul",
"aug",
"sep",
"oct",
"nov",
"dec",
];

return months.indexOf(month.toLowerCase());
function monthIndexFromDateKey(dateString) {
return new Date(dateString).getMonth();
}

function calculateGoalUpwards(monthValue, improvementRatio) {
const goal = monthValue + (100 - monthValue) * improvementRatio;
return Math.ceil(goal);
function relativeImprovementRatio(monthThreeIndex) {
const annualRelativeImprovement = 0.1; // 10%
const monthlyRelativeImprovement = annualRelativeImprovement / 12;
const monthsRemainingForYear = monthThreeIndex === 11 ? 12 : 11 - monthThreeIndex; // dec = 12, jan = 11... nov = 1
return monthlyRelativeImprovement * monthsRemainingForYear;
}

function calculateGoalDownwards(monthValue, improvementRatio) {
const goal = monthValue - monthValue * improvementRatio;
return Math.floor(goal);
function calculateGoalUpwards(threeMonthAverage, improvementRatio) {
const goal = threeMonthAverage + ((100 - threeMonthAverage) * improvementRatio);
return Math.ceil(goal);
}

function relativeImprovementRatio(goalMonthIndex) {
const defaultRelativeImprovementPercentage = 10;
const improvementPercentagePerMonth =
defaultRelativeImprovementPercentage / 100 / 12;
const monthsRemainingInYear = 12 - (goalMonthIndex % 11); // dec is full year (0 index)
return improvementPercentagePerMonth * monthsRemainingInYear;
function calculateGoalDownwards(threeMonthAverage, improvementRatio) {
const goal = threeMonthAverage - (threeMonthAverage * improvementRatio);
return Math.floor(goal);
}

// - canvas drawing
Expand Down Expand Up @@ -1693,7 +1680,6 @@ function baseBarChartConfig() {
};
}


// [Segment] Functions
//
/**
Expand Down

0 comments on commit 8aa9209

Please sign in to comment.