echarts icon indicating copy to clipboard operation
echarts copied to clipboard

[Feature] Create a continuous VisualMap with log distribution

Open rjyunis opened this issue 2 years ago • 4 comments

What problem does this feature solve?

When creating a series of type "heatmap", it would be nice to have a continuous VisualMap distributed on a log scale. Currently it can only be distributed linearly.

It is possible to achieve similar results by taking the log of all the series data, but in doing so you lose the physical meaning behind the numbers.

An analogous example in python is the difference between numpy.linspace(), and numpy.geomspace().

I propose having a VisualMap option called "scaling", which defaults to "linear", but can be set to "log".

What does the proposed API look like?

option = {
  series: [{
    type: "heatmap",
    //...
  }],
  visualMap: {
    type: "continuous",
    scaling: "log" // use the logic from numpy.geomspace()
  }
};

rjyunis avatar Mar 28 '23 23:03 rjyunis

Workaround I have discovered:

Take the log of the Z data, then

visualMap: {
  formatter: function (value){ return Math.E**value }
},
//...
tooltip:{
  "valueFormatter": (value) => Math.E**value
}

This is messy, but it will get the job done for a basic heatmap where the values aren't shown except on the tooltop and visualMap.

rjyunis avatar Mar 29 '23 06:03 rjyunis

Alternatively, can we apply the VisualMap to a non-physical dimension? For example, can I set dimension: 3 //fourth column and "hide" the values that are being tracked for the colors there?

rjyunis avatar Mar 30 '23 18:03 rjyunis

I think this could be a useful feature but the community is mainly working on the project in their spare time so if you would like to make a pull request to implement this, it should save much of your waiting time. Thanks!

Ovilia avatar Mar 31 '23 02:03 Ovilia

There is a way to achieve:

let processedData = rawData.map(item => {
    const safeValue = Math.max(1, item.value);
    return {
        name: item.name,
        value: Math.log10(safeValue),
        origin: safeValue
    };
});
...
tooltip: {
    formatter: function (params) {
        if (params.data && params.data.origin !== undefined)
            return params.name + ': ' + params.data.origin;
        return params.name;
    }
},
...
visualMap: {
    formatter: (value) => Math.round(Math.pow(10, value)),
},
...
series: [{
    data: processedData
}]
Image

YiHui-Liu avatar Nov 13 '25 18:11 YiHui-Liu