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 BigInt
s 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 BigNum
s 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 BigInt
s as arguments, throwing the error Cannot convert a BigInt value to a number
.
A solution to avoid using BigNum
s 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 BigInt
s, 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 BigNum
s 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.