javascriptapexcharts

change the color of the bar based on the value of the x axis


The current result What I want

Hi, I have this problem, I don't understand how to change the color of the bars based on the value of the X axis, I searched online but I didn't find a solution.

The need is to make the bars green if the X-axis value is >= 0 and red if < 0

In the code example the modification occurs only on the change in value of the Y axis, which I don't need.

Does anyone have a solution? Thank you!

Example code:

var options = {
    series: [{
        name: 'Occorrenze',
        data: [2, 10, 45, 70, 47, 36, 7, 3] // _jSon.occorenze
    }],              
    chart: {
        height: 415,
        type: 'bar',
        foreColor: '#ffffff'
    },
    plotOptions: {
        bar: {
            dataLabels: {
                position: 'top'
            },
            colors: {
                /*
                    this block changes the color of the bar based on the value of the Y axis
                */
                ranges: [{
                    from: 0,
                    to: -100,
                    color: '#FF0000'
                }, {
                    from: 0,
                    to: 100,
                    color: '#02DFDE'
                }]
            }                        
        }
    },                
    dataLabels: {
        enabled: true,
        formatter: function (val) {
            return val;
        },
        offsetY: -20,
        style: {
            fontSize: '12px',
            colors: ["#fff"]
        }
    },
    xaxis: {
        //type: 'Delta',
        type: 'category',
        categories: [3, 2, 1, 0, -0, -1, -2, 3], // _jSon.percentuali,
        labels: {
            show: true,
            formatter: function (val) {
                return val + "%";
            }
        },
        tooltip: {
            enabled: true,
        }                    
    },
    yaxis: {
        show: true,
        labels: {
            show: false,
            formatter: function (val) {
                return val;
            }
        },
        tooltip: {
            y: {
                formatter: function (val) {
                    return "Occorrenze"
                }
            }
        }
    }               
};

var chart = new ApexCharts(document.querySelector("#historical_occurrences"), options);
chart.render();

Solution

  • You can control bar colors dynamically, using the function version for options.colors:

    const options = {
        //......... series, chart, other options
        colors: [
             function({dataPointIndex, w}){
                const xValue = w.config.xaxis.categories[dataPointIndex];
                return isNegative(xValue) ? '#02DFDE' : '#FF0000';
            }
        ]
    };
    

    where I used

    const isNegative = x => x < 0 || x === 0 && 1/x === Number.NEGATIVE_INFINITY;
    

    to cover negative zero that you have set for categories.

    Here's a snippet with your code and these changes:

    const isNegative = x => x < 0 || x === 0 && 1/x === Number.NEGATIVE_INFINITY;
    const options = {
        series: [{
            name: 'Occorrenze',
            data: [2, 10, 45, 70, 47, 36, 7, 3] // _jSon.occorenze
        }],
        chart: {
            height: 415,
            type: 'bar',
            //foreColor: '#ffffff'
        },
        colors: [
            function({dataPointIndex, w}){
                const xValue = w.config.xaxis.categories[dataPointIndex];
                return isNegative(xValue) ? '#02DFDE' : '#FF0000';
            }
        ],
        plotOptions: {
            bar: {
                dataLabels: {
                    position: 'top'
                }
            }
        },
        dataLabels: {
            enabled: true,
            formatter: function (val) {
                return val;
            },
            offsetY: -20,
            style: {
                fontSize: '12px',
                colors: ["#fff"]
            }
        },
        xaxis: {
            //type: 'Delta',
            type: 'category',
            categories: [3, 2, 1, 0, -0, -1, -2, -3], // _jSon.percentuali,
            labels: {
                show: true,
                formatter: function (val) {
                    return val + "%";
                }
            },
            tooltip: {
                enabled: true,
            }
        },
        yaxis: {
            show: true,
            labels: {
                show: false,
                formatter: function (val) {
                    return val;
                }
            },
            tooltip: {
                y: {
                    formatter: function (val) {
                        return "Occorrenze"
                    }
                }
            }
        }
    };
    
    new ApexCharts(document.querySelector("#historical_occurrences"), options).render();
    <div id="historical_occurrences"></div>
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>

    I see that your data and category values are set statically in the code you posted, and by the look of the comments, they are obtained by parsing some json input at a moment before the chart is constructed. Then, the colors can also be set statically, at the same moment you get the data and categories; to have apexcharts use an array for colors of the same series, one has to enable distributed: true in plotOptions:

    const categories = [3, 2, 1, 0, -0, -1, -2, -3]; // _jSon.occorenze
    const data = [2, 10, 45, 70, 47, 36, 7, 3]; // _jSon.occorenze
    const colors_s1 = categories.map(cat => isNegative(cat) ? '#02DFDE' : '#FF0000'); // s1 for first series
    
    const options = {
        //......... series, chart, other options
        colors: [
             colors_s1
        ],
        plotOptions: {
            distributed: true,
            //......... other plotOptions options
        }
    };
    

    Snippet for this version:

    const isNegative = x => x < 0 || x === 0 && 1/x === Number.NEGATIVE_INFINITY;
    
    const data = [2, 10, 45, 70, 47, 36, 7, 3]; // _jSon.percentuali,
    const categories = [3, 2, 1, 0, -0, -1, -2, -3];  // _jSon.percentuali,
    const colors_s1 = categories.map(cat => isNegative(cat) ? '#02DFDE' : '#FF0000');
    
    const options = {
        series: [{
            name: 'Occorrenze',
            data
        }],
        chart: {
            height: 415,
            type: 'bar',
            //foreColor: '#ffffff'
        },
        colors: //[
            colors_s1,
        //],
        plotOptions: {
            bar: {
                distributed: true,
                dataLabels: {
                    position: 'top'
                }
            }
        },
        dataLabels: {
            enabled: true,
            formatter: function (val) {
                return val;
            },
            offsetY: -20,
            style: {
                fontSize: '12px',
                colors: ["#fff"]
            }
        },
        xaxis: {
            //type: 'Delta',
            type: 'category',
            categories,
            labels: {
                show: true,
                formatter: function (val) {
                    return val + "%";
                }
            },
            tooltip: {
                enabled: true,
            }
        },
        yaxis: {
            show: true,
            labels: {
                show: false,
                formatter: function (val) {
                    return val;
                }
            },
            tooltip: {
                y: {
                    formatter: function (val) {
                        return "Occorrenze"
                    }
                }
            }
        }
    };
    
    new ApexCharts(document.querySelector("#historical_occurrences"), options).render();
    <div id="historical_occurrences"></div>
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>