@@ -279,6 +279,63 @@ export function getPercentWithPrecision(valueList: number[], idx: number, precis
279279 return seats [ idx ] / digits ;
280280}
281281
282+ /**
283+ * Get a data of given precision, assuring the sum of percentages
284+ * in valueList is 1.
285+ * The largest remainer method is used.
286+ * https://en.wikipedia.org/wiki/Largest_remainder_method
287+ *
288+ * @param valueList a list of all data
289+ * @param precision integer number showing digits of precision
290+ * @return {Array<number> } percent ranging from 0 to 100
291+ */
292+ export function getPercentSeats ( valueList : number [ ] , precision : number ) : number [ ] {
293+ const sum = zrUtil . reduce ( valueList , function ( acc , val ) {
294+ return acc + ( isNaN ( val ) ? 0 : val ) ;
295+ } , 0 ) ;
296+ if ( sum === 0 ) {
297+ return [ ] ;
298+ }
299+
300+ const digits = Math . pow ( 10 , precision ) ;
301+ const votesPerQuota = zrUtil . map ( valueList , function ( val ) {
302+ return ( isNaN ( val ) ? 0 : val ) / sum * digits * 100 ;
303+ } ) ;
304+ const targetSeats = digits * 100 ;
305+
306+ const seats = zrUtil . map ( votesPerQuota , function ( votes ) {
307+ // Assign automatic seats.
308+ return Math . floor ( votes ) ;
309+ } ) ;
310+ let currentSum = zrUtil . reduce ( seats , function ( acc , val ) {
311+ return acc + val ;
312+ } , 0 ) ;
313+
314+ const remainder = zrUtil . map ( votesPerQuota , function ( votes , idx ) {
315+ return votes - seats [ idx ] ;
316+ } ) ;
317+
318+ // Has remainding votes.
319+ while ( currentSum < targetSeats ) {
320+ // Find next largest remainder.
321+ let max = Number . NEGATIVE_INFINITY ;
322+ let maxId = null ;
323+ for ( let i = 0 , len = remainder . length ; i < len ; ++ i ) {
324+ if ( remainder [ i ] > max ) {
325+ max = remainder [ i ] ;
326+ maxId = i ;
327+ }
328+ }
329+
330+ // Add a vote to max remainder.
331+ ++ seats [ maxId ] ;
332+ remainder [ maxId ] = 0 ;
333+ ++ currentSum ;
334+ }
335+
336+ return seats ;
337+ }
338+
282339/**
283340 * Solve the floating point adding problem like 0.1 + 0.2 === 0.30000000000000004
284341 * See <http://0.30000000000000004.com/>
0 commit comments