Search code examples
chart.js

Setting Chartjs Global Defaults for Individual Axes


According to the documentation, Chartjs (v4) grid styling is controlled using the options.scales[scaleId].grid namespace. I can control the styling globally of select elements using statements like:

Chart.defaults.scale.grid.display = true;
Chart.defaults.scale.grid.lineWidth = 5;

However, I can not seem to find the syntax for controlling defaults for individual axes using the [scaleId] portion of the above namespace. I have tried the following to no avail:

Chart.defaults.scales.x.grid.display = true;
Chart.defaults.scales['x'].grid.display = true;

What is the proper syntax to set defaults for the axes individually?

TLDR; I am setting global display properties in a separate file and importing those settings into each chart (I have over 20 charts) within a Vue 3 project.

chartDefaults.js

// Set project defaults

import Chart from "chart.js/auto"

// general
Chart.defaults.responsive = true;
Chart.defaults.maintainAspectRatio = false;

// animations
Chart.defaults.animation.duration = 2000;
Chart.defaults.animation.easing = 'easeInOutQuart';

...

I've inspected the Chart.defaults object, but I don't see references to the individual axes within the defaults object.


UPDATE: I've found a construction my IDE will accept, but it doesn't seem to affect the charts.

Chart.defaults.scales.linear.axis.x = {
  grid: {
    borderColor: '#FF0000',
    display: true,
  }
};

Solution

In order to show the proper formatted solution for my question, I am attaching it here. The solution was provided by @kikon below.

if(!Chart.defaults.scales.category.grid){
   Chart.defaults.scales.category.grid = {};
}
Chart.defaults.scales.category.grid.color = 'red'; // x-axis

Solution

  • There's no difference in the definition of axes between their roles as x, y or r. You may set the defaults by their type, i.e., linear, category, time, etc.

    The default state of most plot types is that x axis is of type "category" and y axis of type "linear". If that's the case for all of your charts, then you may use that to set the defaults:

    if(!Chart.defaults.scales.linear.border){
       Chart.defaults.scales.linear.border = {};
    }
    Chart.defaults.scales.linear.border.color = 'blue'; // y-axis
    
    if(!Chart.defaults.scales.category.border){
       Chart.defaults.scales.category.border = {};
    }
    Chart.defaults.scales.category.border.color = 'red'; // x-axis
    

    However, if you are about to use different-than-default the axes types, like using linear axes for both x and y, you may use the fact that the options you need are scriptable, so you may set their default values to functions that interrogate the role of the scale at run-time, through the .axis property (its value may be x, y or r):

    if(!Chart.defaults.scales.linear.border){
       Chart.defaults.scales.linear.border = {};
    }
    Chart.defaults.scales.linear.border.color = function({scale}){
       if(scale.axis === 'x'){
          return 'red'
       }
       if(scale.axis === 'y'){
          return 'blue'
       }
    };
    

    Here's a more elaborate example:

    for(axisType of ['linear', 'category']){
        Chart.defaults.scales[axisType].border = Chart.defaults.scales[axisType].border ?? {};
        Chart.defaults.scales[axisType].border.color = function({scale}){
            if(scale.axis === 'x'){
                return 'red'
            }
            if(scale.axis === 'y'){
                return 'blue'
            }
        }
    
        Chart.defaults.scales[axisType].grid = Chart.defaults.scales[axisType].grid ?? {};
    
        Chart.defaults.scales[axisType].grid.color = 'rgba(0,0,0,0.3)'
        Chart.defaults.scales[axisType].grid.display = function({scale}){
            if(scale.axis === 'x'){
                return true
            }
            if(scale.axis === 'y'){
                return false
            }
        }
        Chart.defaults.scales[axisType].grid.tickColor = function({scale}){
            if(scale.axis === 'x'){
                return 'red';
            }
            if(scale.axis === 'y'){
                return 'blue';
            }
        }
    
        Chart.defaults.scales[axisType].ticks = Chart.defaults.scales[axisType].ticks ?? {};
        Chart.defaults.scales[axisType].ticks.color = function({scale}){
            if(scale.axis === 'x'){
                return 'rgb(128, 0, 0)';
            }
            if(scale.axis === 'y'){
                return 'rgb(0, 0, 192)';
            }
        }
    }
    const data = {
        datasets: [
            {
                label: 'Some data',
                showLine: true,
                pointRadius: 2,
                data:
                    [ {x: 8.25257, y: 8.25257}, {x: 9.30005, y: 12.30005}, {x: 9.90518, y: 9.90518} ],
            }
        ]
    };
    
    const config = {
        type: 'line',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales:{
                x:{
                    type: 'linear'
                },
            }
        },
    };
    
    new Chart(document.querySelector('#chart1'), config);
    <div style="min-height:400px">
        <canvas id="chart1"></canvas>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>