With the *Percentages plugin*, a script I wrote back in 2016, you can calculate percentages with any values. Calculating percentages? Right, that shouldn’t be too hard. Let me clarify: the plugin, available as a JavaScript function and PHP class, solves the problem were calculating the sum of all percentages is not exactly 100%.

Not adding up to, or even exceeding 100 percent, is caused by rounding values down or up. My script makes use of the largest remainder method: until a total of 100 percent is reached, it looks which unrounded value has the largest remainder of all. The corresponding percentage value is then incremented by 1.

You might (or might not – it all depends on whether you care if the sum of percentages should be 100%) use Percentages for polls, for example. I’ve included a quick interactive demo below, powered by VueJS.

Option | Votes | Percentage | |
---|---|---|---|

{{ item.name }} | {{ item.votes }} | {{ item.percentage }}% | |

Total | {{ totalVotes }} | {{ totalPercentage }}% |

Because this is only a demo, the amount of options in the poll are limited. For every option, we keep track of two properties: the amount of votes and the calculated percentage. For now, all values besides the names (or identifiers) of the available options are set to 0. Additionally, we keep track of the total votes percentage by defining two computed values.

data: { | |

items: [ | |

{ name: 1, votes: 0, percentage: 0 }, | |

{ name: 2, votes: 0, percentage: 0 }, | |

{ name: 3, votes: 0, percentage: 0 } | |

] | |

} |

computed: { | |

// Count total votes and percentage | |

totalVotes: function() { | |

return this.sum(this.items, "votes"); | |

}, | |

totalPercentage: function() { | |

return this.sum(this.items, "percentage"); | |

} | |

} |

When the button is pressed, the `vote()`

function is called. That function looks like this:

vote: function(item) { | |

// Update value and recalculate percentages | |

item.votes += 1; | |

this.calc(); | |

} |

Only one argument –the corresponding item– is passed to the function. After its vote count is updated, percentages are recalculated by the `calc()`

function.

calc: function() { | |

var votes = [], | |

i = 0, | |

j = 0; | |

// Store votes in an array we can use with Percentages.js | |

for (i; i < this.items.length; i++) { | |

votes.push(this.items[i].votes); | |

} | |

// Set percentage values | |

var percentages = new Percentages(votes).corrected; | |

for (j; j < percentages.length; j++) { | |

this.$set(this.items[j], "percentage", percentages[j]); | |

} | |

} |

Due to the fact that the Percentages script expects an array as the only argument, we need to create one in order to be able to exchange data between the Vue instance and the Percentages script. After the new array is filled with the vote count for each item, we can get the calculated percentages. Each percentage value in the Vue data is updated afterwards.

Lastly, the computed values for the total amount of votes and total percentage are updated automatically. Because the largest remainder method is used, the sum of percentages is always 100 percent.

For more explanation, be sure to check out the GitHub repository.

Check it out on GitHub