diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts index f306fafb30..fc22425605 100644 --- a/src/chart/pie/PieSeries.ts +++ b/src/chart/pie/PieSeries.ts @@ -20,7 +20,7 @@ import createSeriesDataSimply from '../helper/createSeriesDataSimply'; import * as zrUtil from 'zrender/src/core/util'; import * as modelUtil from '../../util/model'; -import { getPercentWithPrecision } from '../../util/number'; +import { getPercentSeats } from '../../util/number'; import { makeSeriesEncodeForNameBased } from '../../data/helper/sourceHelper'; import LegendVisualProvider from '../../visual/LegendVisualProvider'; import SeriesModel from '../../model/Series'; @@ -133,6 +133,8 @@ class PieSeriesModel extends SeriesModel { static type = 'series.pie' as const; + seats: number[]; + /** * @overwrite */ @@ -159,31 +161,25 @@ class PieSeriesModel extends SeriesModel { * @overwrite */ getInitialData(this: PieSeriesModel): SeriesData { - return createSeriesDataSimply(this, { + const data = createSeriesDataSimply(this, { coordDimensions: ['value'], encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this) }); + const valueList:number[] = []; + data.each(data.mapDimension('value'), function (value: number) { + valueList.push(value); + }); + + this.seats = getPercentSeats(valueList, data.hostModel.get('percentPrecision')); + return data; } /** * @overwrite */ getDataParams(dataIndex: number): PieCallbackDataParams { - const data = this.getData(); const params = super.getDataParams(dataIndex) as PieCallbackDataParams; - // FIXME toFixed? - - const valueList: number[] = []; - data.each(data.mapDimension('value'), function (value: number) { - valueList.push(value); - }); - - params.percent = getPercentWithPrecision( - valueList, - dataIndex, - data.hostModel.get('percentPrecision') - ); - + params.percent = this.seats[dataIndex]; params.$vars.push('percent'); return params; } diff --git a/src/util/number.ts b/src/util/number.ts index aab32f1703..bf5b2562f0 100644 --- a/src/util/number.ts +++ b/src/util/number.ts @@ -233,11 +233,27 @@ export function getPercentWithPrecision(valueList: number[], idx: number, precis return 0; } + const seats = getPercentSeats(valueList, precision); + + return seats[idx] || 0; +} + +/** + * 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 valueList a list of all data + * @param precision integer number showing digits of precision + * @return {Array} + */ +export function getPercentSeats(valueList: number[], precision: number): number[] { const sum = zrUtil.reduce(valueList, function (acc, val) { return acc + (isNaN(val) ? 0 : val); }, 0); if (sum === 0) { - return 0; + return []; } const digits = Math.pow(10, precision); @@ -275,8 +291,9 @@ export function getPercentWithPrecision(valueList: number[], idx: number, precis remainder[maxId] = 0; ++currentSum; } - - return seats[idx] / digits; + return zrUtil.map(seats, function (seat) { + return seat / digits; + }); } /** diff --git a/test/pie-percent.html b/test/pie-percent.html new file mode 100644 index 0000000000..06372ba5ac --- /dev/null +++ b/test/pie-percent.html @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + diff --git a/test/pie3.html b/test/pie3.html index e799aaae16..1f3b418b3a 100644 --- a/test/pie3.html +++ b/test/pie3.html @@ -74,7 +74,7 @@ formatter: function (params) { return '
\

' + params.name + '

\ -
' + (params.percent * 100).toFixed(1) + '%
\ +
' + params.percent.toFixed(1) + '%
\
- \ No newline at end of file +