Chartjsv3和v4中的所有Chartjs实例更新不再工作。

huangapple go评论73阅读模式
英文:

Update all Chartjs instances in Chartjsv3 and v4 not working anymore

问题

以下是您要翻译的内容:

I used a nice method to update my darkmode color changes in chartjs which I got from here:
https://stackoverflow.com/questions/63565630/update-all-chart-js-instances-in-order-to-apply-changed-defaults

After updating to v3 or v4 the following line of code inside my darkmode.js doesn't work anymore and the color changes are not applied because the charts are not updated anymore:

Chart.helpers.each(Chart.instances, function(instance){
    instance.chart.update();
});

I get the following console error: caught TypeError: Cannot read properties of undefined (reading 'update')

I read the docs about all the breaking changes but I was unable to find anything related to update() in combination with instance.

Any idea what went wrong?

The upvoted answer solved my problem. However I would love to reduce code. Currently I call this function two times, once on initial load when theme comes from local storage and then again on the theme switch toggle. Is there a way to reduce this?

var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');

// Change the icons inside the button based on previous settings
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
    themeToggleLightIcon.classList.remove('hidden');
} else {
    themeToggleDarkIcon.classList.remove('hidden');
}

var themeToggleBtn = document.getElementById('theme-toggle');

console.log(Chart.instances);
//Chart.instances.update();

// Force updates to all charts
Chart.helpers.each(Chart.instances, function (instance) {
    if (localStorage.getItem('color-theme') === 'dark') {
        for (let scale in instance.config.options.scales) {
            // Update axes grid color
            instance.config.options.scales[scale].grid.color = 'white';
            instance.config.options.scales[scale].grid.color = 'white';

            Chart.defaults.color = 'white';

            instance.config.options.scales[scale].grid.borderColor = 'white';
            instance.config.options.scales[scale].grid.borderColor = 'white';

            // Update axes label font color
            instance.config.options.scales[scale].ticks.color = 'white';
            instance.config.options.scales[scale].ticks.color = 'white';
        }
    } else {
        for (let scale in instance.config.options.scales) {
            // Update axes grid color
            instance.config.options.scales[scale].grid.color =
                'rgba(0, 0, 0, 0.1)';
            instance.config.options.scales[scale].grid.color =
                'rgba(0, 0, 0, 0.1)';

            instance.config.options.scales[scale].grid.borderColor =
                'rgba(0, 0, 0, 0.1)';
            instance.config.options.scales[scale].grid.borderColor =
                'rgba(0, 0, 0, 0.1)';

            Chart.defaults.color = 'black';

            // Update axes label font color
            instance.config.options.scales[scale].ticks.color = 'black';
            instance.config.options.scales[scale].ticks.color = 'black';
        }
    }

    instance.update();
});

themeToggleBtn.addEventListener('click', function() {
    // toggle icons inside button
    themeToggleDarkIcon.classList.toggle('hidden');
    themeToggleLightIcon.classList.toggle('hidden');

    // if set via local storage previously
    if (localStorage.getItem('color-theme')) {
        if (localStorage.getItem('color-theme') === 'light') {
            document.documentElement.classList.add('dark');
            localStorage.setItem('color-theme', 'dark');
            Chart.defaults.color = 'white';
        } else {
            document.documentElement.classList.remove('dark');
            localStorage.setItem('color-theme', 'light');
            Chart.defaults.color = 'black';
        }
    } else {
        if (document.documentElement.classList.contains('dark')) {
            document.documentElement.classList.remove('dark');
            localStorage.setItem('color-theme', 'light');
            Chart.defaults.color = 'black';
        } else {
            document.documentElement.classList.add('dark');
            localStorage.setItem('color-theme', 'dark');
            Chart.defaults.color = 'white';
        }
    }

    console.log(Chart.instances);
    //Chart.instances.update();

    // Force updates to all charts
    Chart.helpers.each(Chart.instances, function (instance) {
        if (localStorage.getItem('color-theme') === 'dark') {
            for (let scale in instance.config.options.scales) {
                // Update axes grid color
                instance.config.options.scales[scale].grid.color = 'white';
                instance.config.options.scales[scale].grid.color = 'white';

                instance.config.options.scales[scale].grid.borderColor = 'white';
                instance.config.options.scales[scale].grid.borderColor = 'white';

                // Update axes label font color
                instance.config.options.scales[scale].ticks.color = 'white';
                instance.config.options.scales[scale].ticks.color = 'white';
            }
        } else {
            for (let scale in instance.config.options.scales) {
                // Update axes grid color
                instance.config.options.scales[scale].grid.color =
                    'rgba(0, 0, 0, 0.1)';
                instance.config.options.scales[scale].grid.color =
                    'rgba(0, 0, 0, 0.1)';

                instance.config.options.scales[scale].grid.borderColor =
                    'rgba(0, 0, 0, 0.1)';
                instance.config.options.scales[scale].grid.borderColor =
                    'rgba(0, 0, 0, 0.1)';

                // Update axes label font color
                instance.config.options.scales[scale].ticks.color = 'black';
                instance.config.options.scales[scale].ticks.color = 'black';
            }
        }

        instance.update();
    });
});
英文:

I used a nice method to update my darkmode color changes in chartjs which I got from here:
https://stackoverflow.com/questions/63565630/update-all-chart-js-instances-in-order-to-apply-changed-defaults

After updating to v3 or v4 the following line of code inside my darkmode.js doesn't work anymore and the color changes are not applied because the charts are not updated anymore:

Chart.helpers.each(Chart.instances, function(instance){
instance.chart.update();
});

I get the following console error: caught TypeError: Cannot read properties of undefined (reading 'update')

I read the docs about all the breaking changes but I was unable to find anything related to update() in combination with instance.

Any idea what went wrong?

The upvoted answer solved my problem. However I would love to reduce code. Currently I call this function two times, once on initial load when theme comes from local storage and then again on the theme switch toggle. Is there a way to reduce this?

var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
// Change the icons inside the button based on previous settings
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
themeToggleLightIcon.classList.remove('hidden');
} else {
themeToggleDarkIcon.classList.remove('hidden');
}
var themeToggleBtn = document.getElementById('theme-toggle');
console.log(Chart.instances);
//Chart.instances.update();
// Force updates to all charts
Chart.helpers.each(Chart.instances, function (instance) {
if (localStorage.getItem('color-theme') === 'dark') {
for (let scale in instance.config.options.scales) {
// Update axes grid color
instance.config.options.scales[scale].grid.color = 'white';
instance.config.options.scales[scale].grid.color = 'white';
Chart.defaults.color = 'white';
instance.config.options.scales[scale].grid.borderColor = 'white';
instance.config.options.scales[scale].grid.borderColor = 'white';
// Update axes label font color
instance.config.options.scales[scale].ticks.color = 'white';
instance.config.options.scales[scale].ticks.color = 'white';
}
} else {
for (let scale in instance.config.options.scales) {
// Update axes grid color
instance.config.options.scales[scale].grid.color =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.color =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.borderColor =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.borderColor =
'rgba(0, 0, 0, 0.1)';
Chart.defaults.color = 'black';
// Update axes label font color
instance.config.options.scales[scale].ticks.color = 'black';
instance.config.options.scales[scale].ticks.color = 'black';
}
}
instance.update();
});
themeToggleBtn.addEventListener('click', function() {
// toggle icons inside button
themeToggleDarkIcon.classList.toggle('hidden');
themeToggleLightIcon.classList.toggle('hidden');
// if set via local storage previously
if (localStorage.getItem('color-theme')) {
if (localStorage.getItem('color-theme') === 'light') {
document.documentElement.classList.add('dark');
localStorage.setItem('color-theme', 'dark');
Chart.defaults.color = 'white';
} else {
document.documentElement.classList.remove('dark');
localStorage.setItem('color-theme', 'light');
Chart.defaults.color = 'black';
}
} 
// if NOT set via local storage previously
else {
if (document.documentElement.classList.contains('dark')) {
document.documentElement.classList.remove('dark');
localStorage.setItem('color-theme', 'light');
Chart.defaults.color = 'black';
} else {
document.documentElement.classList.add('dark');
localStorage.setItem('color-theme', 'dark');
Chart.defaults.color = 'white';
}
}
console.log(Chart.instances);
//Chart.instances.update();
// Force updates to all charts
Chart.helpers.each(Chart.instances, function (instance) {
if (localStorage.getItem('color-theme') === 'dark') {
for (let scale in instance.config.options.scales) {
// Update axes grid color
instance.config.options.scales[scale].grid.color = 'white';
instance.config.options.scales[scale].grid.color = 'white';
instance.config.options.scales[scale].grid.borderColor = 'white';
instance.config.options.scales[scale].grid.borderColor = 'white';
// Update axes label font color
instance.config.options.scales[scale].ticks.color = 'white';
instance.config.options.scales[scale].ticks.color = 'white';
}
} else {
for (let scale in instance.config.options.scales) {
// Update axes grid color
instance.config.options.scales[scale].grid.color =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.color =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.borderColor =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.borderColor =
'rgba(0, 0, 0, 0.1)';
// Update axes label font color
instance.config.options.scales[scale].ticks.color = 'black';
instance.config.options.scales[scale].ticks.color = 'black';
}
}
instance.update();
});
});

答案1

得分: 0

对于 Chart.js v3 和 v4,

instance.chart.update() 替换为 instance.update() 应该解决问题。

此外,还有一些需要迁移的代码,例如 Chart.defaults.global,根据文档,如果你是从 Chart.js v1 迁移过来的。

我认为从第 3 版开始,Chart.defaults.color 不能更新轴和轴标签的字体颜色。因此,你应该更新每个轴实例的颜色 (instance.config.options.scales[scale].grid.color) 和轴标签 (instance.config.options.scales[scale].ticks.color)。

function changeTheme(darkTheme = false) {
  if (darkTheme) {
    document.body.classList.add('dark-theme');
    Chart.defaults.color = 'white';
  } else {
    document.body.classList.remove('dark-theme');
    Chart.defaults.color = 'black';
  }

  // 强制更新所有图表
  Chart.helpers.each(Chart.instances, function (instance) {
    if (darkTheme) {
      for (let scale in instance.config.options.scales) {
        // 更新轴网格颜色
        instance.config.options.scales[scale].grid.color = 'white';
        instance.config.options.scales[scale].grid.color = 'white';

        instance.config.options.scales[scale].grid.borderColor = 'white';
        instance.config.options.scales[scale].grid.borderColor = 'white';

        // 更新轴标签字体颜色
        instance.config.options.scales[scale].ticks.color = 'white';
        instance.config.options.scales[scale].ticks.color = 'white';
      }
    } else {
      for (let scale in instance.config.options.scales) {
        // 更新轴网格颜色
        instance.config.options.scales[scale].grid.color =
          'rgba(0, 0, 0, 0.1)';
        instance.config.options.scales[scale].grid.color =
          'rgba(0, 0, 0, 0.1)';

        instance.config.options.scales[scale].grid.borderColor =
          'rgba(0, 0, 0, 0.1)';
        instance.config.options.scales[scale].grid.borderColor =
          'rgba(0, 0, 0, 0.1)';

        // 更新轴标签字体颜色
        instance.config.options.scales[scale].ticks.color = 'black';
        instance.config.options.scales[scale].ticks.color = 'black';
      }
    }

    instance.update();
  });
}

在 StackBlitz 上演示

参考资料: 如何在 Chart JS 中实现深色模式 (适用于 Chart.JS 版本 3.6)

英文:

For Chart.js v3 and v4,

Replace instance.chart.update() with instance.update() should resolve the issue.

Aside, there are also some codes that need to be migrated for example Chart.defaults.global according to the documentation if you are working from Chart.js v1.

While I think from version 3 onwards, Chart.defaults.color won't able to update the font color for axes, axes' label as well. Thus, you should update each instance for the axes (instance.config.options.scales[scale].grid.color) and axes label (instance.config.options.scales[scale].ticks.color) colors accordingly.

function changeTheme(darkTheme = false) {
if (darkTheme) {
document.body.classList.add('dark-theme');
Chart.defaults.color = 'white';
} else {
document.body.classList.remove('dark-theme');
Chart.defaults.color = 'black';
}
// Force updates to all charts
Chart.helpers.each(Chart.instances, function (instance) {
if (darkTheme) {
for (let scale in instance.config.options.scales) {
// Update axes grid color
instance.config.options.scales[scale].grid.color = 'white';
instance.config.options.scales[scale].grid.color = 'white';
instance.config.options.scales[scale].grid.borderColor = 'white';
instance.config.options.scales[scale].grid.borderColor = 'white';
// Update axes label font color
instance.config.options.scales[scale].ticks.color = 'white';
instance.config.options.scales[scale].ticks.color = 'white';
}
} else {
for (let scale in instance.config.options.scales) {
// Update axes grid color
instance.config.options.scales[scale].grid.color =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.color =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.borderColor =
'rgba(0, 0, 0, 0.1)';
instance.config.options.scales[scale].grid.borderColor =
'rgba(0, 0, 0, 0.1)';
// Update axes label font color
instance.config.options.scales[scale].ticks.color = 'black';
instance.config.options.scales[scale].ticks.color = 'black';
}
}
instance.update();
});
}

Demo @ StackBlitz

Reference: How to Implement Dark Mode in Chart JS (for Chart.JS version 3.6)

huangapple
  • 本文由 发表于 2023年5月28日 15:39:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76350438.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定