AgGrid heatmap cell renderer

I’m trying to create a heatmap in AgGrid and have been having some problems making it look good.

The main issue is that there is left and right padding in the cell rather than a completely filled background:

In my column definitions I added

    "cellRenderer": "heatMap",
    "cellRendererParams": {"min": data[col_name].min(), "max": data[col_name].max()},

And I’ve added the corresponding function below to my dashAgGridComponentFunctions.js in my assets folder:

var dagcomponentfuncs = window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {};

function rgbToHex(r, g, b) {
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};

dagcomponentfuncs.heatMap = function (props) {
    const min = props.colDef.cellRendererParams.min;
    const max = props.colDef.cellRendererParams.max;
    const val = props.value;

    if(min > 0) {
        g = 255;
        r = b = Math.round(255 * (1 - val / max));
    }
    else {
        if(val > 0) {
            g = 255;
            r = b = Math.round(255 * (1 - val / max));
        }
        else {
            r = 255;
            g = b = Math.round(255 * (1 - val / min));
        }
    };

    return React.createElement(
        'div',
        {
            style: {
                backgroundColor: rgbToHex(r, g, b),
                color: 'black',
            },
        },
        props.valueFormatted
    );
};

One work around to make the cell fully colored is to add

"cellStyle": {"padding-right": 0, "padding-left": 0},

to the column definition but then the alignment of the cell content is off.

Is there a better way to achieve what I want to have the cells have the appropriate background fully and not to have to define custom padding in the cell content?

Hello @mathman79,

Welcome to the community!

All you are doing is styling in the component, is that correct?

Have you looked into conditionally styling the cells?

var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

function rgbToHex(r, g, b) {
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};

dagfuncs.heatMap = function (props) {
    const min = props.colDef.cellRendererParams.min;
    const max = props.colDef.cellRendererParams.max;
    const val = props.value;

    if(min > 0) {
        g = 255;
        r = b = Math.round(255 * (1 - val / max));
    }
    else {
        if(val > 0) {
            g = 255;
            r = b = Math.round(255 * (1 - val / max));
        }
        else {
            r = 255;
            g = b = Math.round(255 * (1 - val / min));
        }
    };

return {
                backgroundColor: rgbToHex(r, g, b),
                color: 'black',
            }
}

Then in the columnDef:

"cellStyle": {"function": "heatMap(params)"},
"cellRendererParams": {"min": data[col_name].min(), "max": data[col_name].max()},

@jinnyzor Thank you and thanks for the solution. This is exactly what I was looking for!

I didn’t realize the cellStyle could have a dynamic function similar to the cellRenderer. This is very elegant.

1 Like

Yup, AG grid is very powerful and very flexible. :slight_smile:

1 Like

Updated my code to below, in case there are other folks interesting in an AgGrid heatmap:

var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};

function rgbToHex(r, g, b) {
    return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};

dagfuncs.heatMap = function (props) {
    const min = props.colDef.cellRendererParams.min;
    const max = props.colDef.cellRendererParams.max;
    const val = props.value;

    if(val) {
        if(val > 0) {
            g = 255;
            r = b = Math.round(255 * (1 - val / max));
        }
        else {
            r = 255;
            g = b = Math.round(255 * (1 - val / min));
        };

        return {
            backgroundColor: rgbToHex(r, g, b),
            color: 'black',
        }
    }
    else {
        return {};
    }
};
2 Likes