I'm using Apache ECharts to visualize data with very large integer values (JavaScript bigint type) on the X-axis, configured as type: 'value'. However, I'm encountering unexpected behavior:
My data looks like this:
data: [
{ value: [12345678901234567890n, 10] }, // bigint X-value
{ value: [12345678901234567891n, 20] },
// ...
]
Issue:
Expected Behavior:
Display the full precision of bigint values as readable labels (e.g., "12345678901234567890").
Attempted Solutions:
Tried setting axisLabel: { formatter: (value) => value.toString() }, but the original value is already rounded.
Question:
How can I configure ECharts to correctly handle and display bigint-scale integers on a 'value'-type X-axis without losing precision? Are there workarounds for axis formatting or data representation?
Echarts doesn't seem to support BigInt, this request for this feature is still pending.
A search for BigInt in the source code doesn't produce any results.
As for what's happening in the current version, all data points are passed through the function parseDataValue, (source code - dataValueHelper#L34) that applies Number
constructor (called as function) to each numeric data value
(see dataValueHelper#L80 in the same function),
which casts the BigInts to number values, losing the precision, which appears in some cases as the values being "rounded" to a multiple of 10k, integer k > 1 (e.g., Number(12345678901234567890n) === 12345678901234567000).
Also, if BigNums are given as values for some options, like if one sets the min or max of an axis to a BigInt, they will be passed (see scaleRawExtentInfo.ts#L205) through the global function isFinite,
that doesn't accept BigInts as arguments, throwing the error Cannot convert a BigInt value to a number.
A solution to avoid using BigNums can, of course, be improvised by anyone,
tailored to the needs of their specific dataset; but since I put this as an answer rather than a comment, let me add a suggestion in this regard. One could choose any value of the BigInts, call it _bigNumZero, and extract it from each of the other values and convert that value to a number, presuming that the range of the BigNums is small enough to be covered without loss of precision by values of type number:
let _bigNumZero = null;
function resetBigNum(data){
if(_bigNumZero === null){ // just for the first dataset
_bigNumZero = data[0][0]; // the x value of the first point
}
for(const point of data){
point[0] = Number(point[0] - _bigNumZero); // 0 for x dimension
}
return data;
}
used in the chart configuration as:
series: [
{
// ... other series options
data: resetBigNum(.....)
},
// ... other series, similar treatment
]
the argument of resetBigNum being a series' data as an array of [x, y] arrays, where x is always a BigInt.
Then, formatters should be added everywhere the x value might be displayed, to add to the numeric value used by the chart, the "zero point" _bigNumZero. In the following echarts demo, I set formatters for the x axis and the tooltip.