Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用最大余额法计算百分比 #93

Open
akaxiaok opened this issue Jun 10, 2020 · 1 comment
Open

使用最大余额法计算百分比 #93

akaxiaok opened this issue Jun 10, 2020 · 1 comment

Comments

@akaxiaok
Copy link
Owner

getPercentWithPrecision 如果用了 echarts 的话 可以直接用

import { getPercentWithPrecision } from 'echarts/src/util/number';
@akaxiaok
Copy link
Owner Author

/**
 * Get a data of given precision, assuring the sum of percentages
 * in valueList is 1.
 * The largest remainer method is used.
 * https://en.wikipedia.org/wiki/Largest_remainder_method
 *
 * @param {Array.<number>} valueList a list of all data
 * @param {number} idx index of the data to be processed in valueList
 * @param {number} precision integer number showing digits of precision
 * @return {number} percent ranging from 0 to 100
 */
export function getPercentWithPrecision(valueList, idx, precision) {
    if (!valueList[idx]) {
        return 0;
    }

    var sum = zrUtil.reduce(valueList, function (acc, val) {
        return acc + (isNaN(val) ? 0 : val);
    }, 0);
    if (sum === 0) {
        return 0;
    }

    var digits = Math.pow(10, precision);
    var votesPerQuota = zrUtil.map(valueList, function (val) {
        return (isNaN(val) ? 0 : val) / sum * digits * 100;
    });
    var targetSeats = digits * 100;

    var seats = zrUtil.map(votesPerQuota, function (votes) {
        // Assign automatic seats.
        return Math.floor(votes);
    });
    var currentSum = zrUtil.reduce(seats, function (acc, val) {
        return acc + val;
    }, 0);

    var remainder = zrUtil.map(votesPerQuota, function (votes, idx) {
        return votes - seats[idx];
    });

    // Has remainding votes.
    while (currentSum < targetSeats) {
        // Find next largest remainder.
        var max = Number.NEGATIVE_INFINITY;
        var maxId = null;
        for (var i = 0, len = remainder.length; i < len; ++i) {
            if (remainder[i] > max) {
                max = remainder[i];
                maxId = i;
            }
        }

        // Add a vote to max remainder.
        ++seats[maxId];
        remainder[maxId] = 0;
        ++currentSum;
    }

    return seats[idx] / digits;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant