[Chartjs]-Chart.js with prefers-color-scheme on Safari: scales' color doesn't change

1👍

This was a bug in Chart.js 2.8.0. It was fixed in version 2.9.0:

const white = 'hsl(42, 0%, 90%)';
const black = 'hsl(42, 0%, 10%)';

const perfectPrimaryLight = 'hsl(270, 50%, 40%)';
const perfectSecondaryLight = 'hsla(270, 50%, 40%, .2)';

const myPrimaryLight = 'hsl(0, 50%, 40%)';
const mySecondaryLight = 'hsla(0, 50%, 40%, .2)';

const perfectPrimaryDark = 'hsl(340, 50%, 80%)';
const perfectSecondaryDark = 'hsla(340, 50%, 80%, .2)';

const myPrimaryDark = 'hsl(0, 50%, 80%)';
const mySecondaryDark = 'hsla(0, 50%, 80%, .2)';

Chart.defaults.global.defaultFontFamily = 'system-ui, sans-serif';
Chart.defaults.global.defaultFontSize = 16; 
Chart.defaults.global.defaultFontColor = black;

function updateToLight(chart) {
    chart.options.legend.labels.fontColor = black;

    chart.options.scales.yAxes[0].ticks.fontColor = black;
    chart.options.scales.xAxes[0].ticks.fontColor = black;

    chart.data.datasets[0].borderColor = perfectPrimaryLight;
    chart.data.datasets[0].backgroundColor = perfectSecondaryLight;

    chart.data.datasets[1].borderColor = myPrimaryLight;
    chart.data.datasets[1].backgroundColor = mySecondaryLight;

    
    chart.update();
}

function updateToDark(chart) {
    chart.options.legend.labels.fontColor = white;

    chart.options.scales.yAxes[0].ticks.fontColor = white;
    chart.options.scales.xAxes[0].ticks.fontColor = white;

    chart.data.datasets[0].borderColor = perfectPrimaryDark;
    chart.data.datasets[0].backgroundColor = perfectSecondaryDark;

    chart.data.datasets[1].borderColor = myPrimaryDark;
    chart.data.datasets[1].backgroundColor = mySecondaryDark;

    
    chart.update();
}

const ctx = document.getElementById('myChart').getContext('2d');
const data = {
    datasets: [{
        label: 'Perfect-calibration dataset',
        data: [{"x":0.01,"y":0.01},{"x":0.05,"y":0.05},{"x":0.10,"y":0.10},{"x":0.15,"y":0.15},{"x":0.20,"y":0.20},{"x":0.25,"y":0.25},{"x":0.30,"y":0.30},{"x":0.35,"y":0.35},{"x":0.40,"y":0.40},{"x":0.45,"y":0.45},{"x":0.50,"y":0.50},{"x":0.55,"y":0.55},{"x":0.60,"y":0.60},{"x":0.65,"y":0.65},{"x":0.70,"y":0.70},{"x":0.75,"y":0.75},{"x":0.80,"y":0.80},{"x":0.85,"y":0.85},{"x":0.90,"y":0.90},{"x":0.95,"y":0.95},{"x":0.99,"y":0.99}],
    }, {
        label: 'My predictions',
        data: [{"x":0.10,"y":0.00},{"x":0.50,"y":0.25},{"x":0.60,"y":0.00},{"x":0.70,"y":0.62},{"x":0.80,"y":0.25},{"x":0.90,"y":0.68},{"x":0.95,"y":0.83}]
    }]
};

const options = {
    title: {
        display: false,
        text: 'A Chart.js Scatter Chart'
    },
    scales: {
        yAxes: [{
            ticks: {
                min: 0,
                max: 1
            }
        }],
        xAxes: [{
            ticks: {
                min: 0,
                max: 1
            }
        }]
    }
}

const c = new Chart(ctx, {
    type: 'scatter',
    data: data,
    options: options
});

const query = window.matchMedia("(prefers-color-scheme: dark)");

let darkMode = false;

function toggleDark() {
    darkMode = !darkMode;
    if (darkMode) {
        document.body.style.background = 'black';
        updateToDark(c);
    } else {
        document.body.style.background = 'white';
        updateToLight(c);    
    }
}

updateToLight(c);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.0/Chart.bundle.min.js"></script>
<canvas id="myChart" onclick="toggleDark()"></canvas>

Version 2.9.0 is also obsolete now, though. Adapting the code sample to 3.8.0 would involve some work, though.

Leave a comment