Search code examples
javascriptamcharts5

Custom function in AM5 heatmap for min and max color range with 0 being outside of that


I want a color range for min and max but have 0 be very light grey (or white) to make it stand out and not try to gradient from 0.

I am using a US map from AM5 charts and need the gradients to nicely transition from 1 to 100, preferably not being in a range like 1-10, 11-20, etc. Most often the number will be 20 or less.

The main issue is that the color range they choose (different from the example below) works nicely but a 0 value needs to be outside of that range specification.

The following example does NOT work but shows the intent. Does anyone know how to make this work?

External reference

polygonSeries.set("heatRules", [{
  target: polygonSeries.mapPolygons.template,
  dataField: "value",
  customFunction: function(sprite, min, max, value){
    if (value < 1) {
      sprite.set("fill", am5.color(0xffffff));
    }
    else {
      min: am5.color(0xff621f),
      max: am5.color(0x661f00)
    }
  }  
  key: "fill"
}]);

AMChart5_Test_Site


Solution

  • Disclaimer: I do not know if this is the most simple answer to your question, but I could not find a better way of doing this.

    First I looked at the source code of AM5 Charts to find how they apply the heatRules to the charts and I found the basic implementation here. (FYI: It is written in TypeScript)

    The logic boils down to the following:

    Step 1: Calculate a percent value with the current value and the min/max value of the used dataset.

    const percent = (value - min) / (max - min)
    

    Step 2: Calculate the color using the Color.interpolate function using the percent value and a minColor and maxColor. The Color.interpolate is a internal function of AM5 that you can find here.

    const spriteColor = am5.Color.interpolate(percent, minColor, maxColor)
    

    After understanding this I modified the code you provided like this:

    const minColor = am5.color(0xff621f)
    const maxColor = am5.color(0x661f00)
    
    polygonSeries.set('heatRules', [
      {
        target: polygonSeries.mapPolygons.template,
        dataField: 'value',
        customFunction: function (sprite, min, max, value) {
          if (value < 1) {
            sprite.set('fill', am5.color(0xffffff))
          } else {
            const percent = (value - min) / (max - min)
            const spriteColor = am5.Color.interpolate(
              percent,
              minColor,
              maxColor
            )
            sprite.set('fill', spriteColor)
          }
        },
      },
    ])
    
    

    The complete code can be found here: Codepen

    (I set the value of Utah to 0 in the codepen so you can see the effect of my changes)