What is the method to adjust the colors of the Y-Axis for values that are either above or below zero in Chart.js 2.6?

Is there a way to dynamically change the colors of bars in a chart created using chart.js 2.6 based on whether the values are above or below zero? The data for the graph series is currently generated randomly but will eventually come from a database query.

function adjustBarColors(chart) {
    var datasets = chart.data.datasets;
    var labelLen = chart.data.labels.length;
    if (datasets[0]) {
        for (i = 0, len = datasets.length; i < len; i++) {
            try {
                for (j = 0, len = labelLen; j < len; j++) {
                    datasets[i].data[j] = getRandomInt(-100, 100);
                }

            } catch (e) {
                console.log(e.message);
            }
        }
    }
}

The current appearance of the chart can be viewed here:

https://i.sstatic.net/CzjUh.png

I aim to have bars above zero displayed in blue and bars below zero in red.

Your assistance and feedback are greatly appreciated. Thank you in advance!

Griff

** Edit ** Included additional code provided by another user:

var myBarChart = new Chart(wowChart, {
    type: 'bar',
    data: wowData,
    plugins: [{
        beforeDraw: function (c) {
            var data = c.data.datasets[0].data;
            for (var i in data) {
                try {
                    var bar = c.data.datasets[0]._meta[0].data[i]._model;
                    if (data[i] > 0) {
                        bar.backgroundColor = '#07C';
                    } else bar.backgroundColor = '#E82020';

                } catch (ex) {
                    console.log(ex.message);
                }
                console.log(data[i]);
            }
        }
    }],
    options: wowOptions
});

I am encountering exceptions in the console output every other line, along with the data elements.

https://i.sstatic.net/qselW.png

Answer №1

To achieve this, you can utilize the chart plugin provided below:

plugins: [{
   beforeDraw: function(c) {
      var data = c.data.datasets[0].data;
      for (let i in data) {
         let bar = c.data.datasets[0]._meta['0'].data[i]._model;
         if (data[i] > 0) {
            bar.backgroundColor = '#07C';
         } else bar.backgroundColor = '#E82020';
      }
   }
}]

Include this code along with your chart customization options.

Demo

var ctx = document.getElementById("canvas").getContext('2d');
var myChart = new Chart(ctx, {
   type: 'bar',
   data: {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
      datasets: [{
         label: 'LEGEND',
         data: [9, 14, -4, 15, -8, 10]
      }]
   },
   options: {},
   plugins: [{
      beforeDraw: function(c) {
         var data = c.data.datasets[0].data;
         for (let i in data) {
            let bar = c.data.datasets[0]._meta['0'].data[i]._model;
            if (data[i] > 0) {
               bar.backgroundColor = '#07C';
            } else bar.backgroundColor = '#E82020';
         }
      }
   }]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="canvas" height="180"></canvas>

Answer №2

If you are working with chartjs version 3, you have the ability to utilize the Simply scriptable option like this:

    datasets: [
          {
            data: this.chartData,
            backgroundColor(context) {
              const index = context.dataIndex
              const value = context.dataset.data[index]
              return value < 0 ? 'red' : 'blue'
            }
          }
        ]

For more information, you can check out https://www.chartjs.org/docs/latest/general/options.html#scriptable-options

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered while presenting canvas on HTML due to Firebase information

Even though I believe I'm following the correct steps, I am facing an issue where the graph displaying real-time database values is not showing up. The first image shows my real-time database and a demostration as shown in images 2 and 3. While the da ...

Change the dropdown menu text to show the selected option text once the page has been redirected

Hey there, I am looking to dynamically update the dropdown text with the selected option after a page redirect and reload of the dropdown. Check out my code below: <div class="sorting-option"> <select id="selectdropdown" class="dropdown-selec ...

Angular's Components and Directives: A Comprehensive Guide

My goal is to render a subview within a template and define the state inside the subview's controller when an element is clicked. I am separating it from the main controller because there will be further subviews within this initial subview. However, ...

Modifying the content inside a div element and inserting an image into it

I am facing a problem where I am unable to display the image when trying to change the inner HTML of a div by inserting an img source into it. Below is my JavaScript code snippet: var sliderimg = document.getElementById('abc_'+obj).src; $("#eve ...

Unable to transfer a callback function from SocketIO to typescript

My server is built with nodeJS and Typescript utilizing SocketIO for an online chat application. However, I am facing difficulties in transferring the callback function provided by TypeScript library. Can someone guide me on how to correctly call the call ...

Placing content inside a text area upon clicking a div element

I am currently developing a submission system and I want to implement a feature where clicking on a div will insert certain text (like [b][/b]). Here is an example of what we are working with: <div class="insertBBC" title="Bold Text" onClick="moveNumbe ...

Apply Jquery to add emphasis to every item on the list

Can someone help me with this assignment? I need to create a jQuery function that italicizes all list elements on the page when triggered by the client. Here is my current approach: $(document).ready(function() { $("li").click(function() { ...

Vue Eslint Extension

My current project utilizes the eslint vue plugin with specific rules set in place. "rules": { "vue/html-closing-bracket-newline": ["error", { "singleline": "never", "multiline": "always" }], "vue/html-closi ...

Filter a Vue table by column name with specific conditions

I am working on code that filters a table based on user input. The process involves selecting a column from a drop-down menu, choosing an operator from another drop-down menu, and entering a search value. I want to filter the table based on these criteria. ...

Transform the array of objects into different clusters

I am facing a challenge where I have an object returning two arrays of objects from an API. My goal is to transform this data into a new array of objects in order to effectively group the information for the Vue v-select component. For a visual representat ...

Creating a TypeScript module declaration for exporting a class

Just starting out with TypeScript and running into issues while trying to load an es6 javascript module. Here's the code snippet from my javascript file: //TemplateFactory.js export class TemplateFactory{ static getTemplate(module){ } } In ...

Creating Three-Dimensional Faces in THREE.BufferGeometry

I have programmatically created a basic mesh structure: var CreateSimpleMesh = new function () { var xy = [], maxX = 7, maxY = 10, river = [[0, 5], [0, 4], [1, 3], [2, 2], [3, 2], [4, 1], [5, 1], [6, 0]], grassGeometry ...

Is it possible to enable autocomplete for JavaScript generated code in .proto files?

I recently created a basic .proto file with the following content: syntax = "proto3"; message Event { optional string name = 1; } After downloading and installing the protoc linux compiler (protoc-3.19.3-linux-x86_64.zip) on my local machine, ...

Introduce a fresh parameter into the promise all chain

I am using the code below and it is functioning as expected. However, I now need to incorporate the modifyOpt() function. Currently, the code works and returns args[2] but I also need to include another step... I want to pass the return value (port) from ...

Struggling with integrating Bootstrap 4 Modals in Angular 2 environment

I attempted to incorporate a modal from into my navbar, but nothing happens when I click on it. <div class="pos-f-t fixed-top header"> <nav class="navbar navbar-inverse bg-inverse navbar-toggleable-md"> <button class="navbar- ...

Click-triggered Animation of Glyphicon

I'm attempting to create an animation for a glyphicon-refresh icon that rotates when clicked. I've been trying to achieve this effect using CSS3, but haven't had much success. Below is the code I've used: <a id="update" href="#"> ...

How to locate the data-id of the next element in a jQuery list

Is it possible to retrieve the data-id of the following list element when clicking a button while on the current active list item? <div class="nbrs"> <ul> <li id="item1" data-id="1" class="active ...

When using Python Selenium, we can see JavaScript in the view page source, but inspecting elements reveals the

I'm currently facing a challenge in accessing links to attachments for a web automation project. The issue lies in the fact that while I can view the HTML Code (divs and tables) when loading the webpage via Chrome and inspecting element, all I see in ...

The TypeScript inference feature is not functioning correctly

Consider the following definitions- I am confused why TypeScript fails to infer the types correctly. If you have a solution, please share! Important Notes: * Ensure that the "Strict Null Check" option is enabled. * The code includes c ...

Guide to setting up a trigger/alert to activate every 5 minutes using Angular

limitExceed(params: any) { params.forEach((data: any) => { if (data.humidity === 100) { this.createNotification('warning', data.sensor, false); } else if (data.humidity >= 67 && data.humidity <= 99.99) { ...