Search code examples
javascriptecharts

Display more than 40,000 bars in EChart GL


I'm trying to display a large amount of data in a 3d EChart. At first I used a scatter3D type, which worked fine, but I thought that using a bar3D chart would be more clear. Then I noticed that if I exceed 40,000 instances of data the chart would appear empty. Is there a way to overpass this limit?

40,000 random points:

40,000 random points

40,001 random points:

40,001 random points

No errors nor logs are displayed in the console.


Solution

  • I finally found out the source of this issue, that's rather puzzling once one realizes that OP's observation is exactly verified, and it's not depending on hardware or WebGL limitations.

    Let me start with the solution: to increase the number of bars that are drawn from the default limit of 40000, you multiply by a (> 1) factor the following options: grid3D.boxWidth, grid3D.boxHeight, grid3D.boxDepth and grid3D.viewControl.distance, e.g.,

    {
        grid3D: {
            boxWidth: 150,   // default is 100
            boxHeight: 150,  // default is 100
            boxDepth: 150,   // default is 100
            viewControl:{
                distance: 300 // default is 200
            }
            // other grid3D options .........
        }
    }
    

    The multiplicative factor being 1.5, the number of bars will increase from 40_000 (200x200) to 90_000 (300x300). Only boxWidth and boxHeight are essential; the others are increased to keep the initial viewport unchanged.

    And now the explanation: with the default settings, the width and the depth of each bar becomes zero if you have more than 40000 data points. So there are actually 40001+ bars processed and sent to rendering, but there's nothing visible because of the zero sizes.

    The problem is that, if x axis and y axis are value axes, the barWidth and barDepth are calculated using:

    barWidth = Math.round(size[0] / Math.sqrt(data.count())) * 0.6;
    barDepth = Math.round(size[1] / Math.sqrt(data.count())) * 0.6;
    

    that can be found in the source code at cartesian3DLayout.js L30 and L36. There size[0] is initialized to boxWidth and size[1] to boxHeight, as per grid3DCreator.js L38.

    Thus, the mathematical condition for the number of bars that are rendered (with all sizes > 0) is:

    data.count() <= (2 * Math.min(boxWidth, boxHeight)) ** 2
    

    which renders 40000 for box sizes of 100.

    I was initially inclined to consider this a bug, but I'd say now that there are probably good reasons for these choices.