Skip to content

Instantly share code, notes, and snippets.

@casschin
Last active March 1, 2019 16:18
Show Gist options
  • Save casschin/702ec6b122afe1b617d9951d42b34d59 to your computer and use it in GitHub Desktop.
Save casschin/702ec6b122afe1b617d9951d42b34d59 to your computer and use it in GitHub Desktop.
Sum percentages to 100%
// Stolen from: https://revs.runtime-revolution.com/getting-100-with-rounded-percentages-273ffa70252b
export const processDatasetWithAdjustedPercentages = dataset => {
// get the total count to caluclate the actual percentage
const totalCount = dataset.reduce((acc, data) => acc + data.value, 0);
// map the dataset and add properties for the percentage values we'll need
const datasetWithPercentages = dataset.map(data => {
const rawPercentage = (data.value / totalCount) * 100; // ex: 43.234235235
const floorPercentage = Math.floor(rawPercentage); // ex: 43
const decimalRemainderPercentage = rawPercentage - floorPercentage; // ex: .234235235
return {
...data,
rawPercentage,
floorPercentage,
decimalRemainderPercentage,
};
});
// calculate the remaining percent point total value that needs to be distributed
const remainder =
100 -
datasetWithPercentages.reduce((acc, data) => acc + data.floorPercentage, 0);
// sort the dataset by the remainder decimal value
const datasetSortedByDecimal = datasetWithPercentages.sort((a, b) => {
if (a.decimalRemainderPercentage > b.decimalRemainderPercentage) return -1;
if (b.decimalRemainderPercentage > a.decimalRemainderPercentage) return 1;
return 0;
});
// distribute the remainder percent points
const datasetWithAdjustedPercentages = datasetSortedByDecimal.map(
(data, i) => {
const adjustedPercentage =
i < remainder ? data.floorPercentage + 1 : data.floorPercentage;
return { ...data, adjustedPercentage };
}
);
return datasetWithAdjustedPercentages;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment