You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte应用中Chart.js图表无法随浏览器窗口响应的问题求助

在Svelte中实现Chart.js响应式图表的问题

我想在Svelte应用里用Chart.js做一个能随浏览器窗口大小变化的响应式图表。现在把图表放在div容器里,但容器尺寸能随窗口变化,canvas却不行——放大窗口图表不跟着变大,缩小也不同步缩小。我试过手动控制canvas尺寸,但没解决问题:

const clientHeight = document.getElementsByClassName('chart-container')[0].clientHeight;
const clientWidth = document.getElementsByClassName('chart-container')[0].clientWidth;
chart.canvas.height = clientHeight;
chart.canvas.width = clientWidth;

我的完整代码如下:

<script>
    import { onMount } from 'svelte';
    import Chart from 'chart.js/auto';

    let data = [20, 100, 50, 12, 20, 130, 45];
    let labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
    let ctx;
    let canvas;

    onMount(() => {
        ctx = canvas.getContext('2d');
        var chart = new Chart(ctx, {
            options: {
                layout: {
                    responsive: true,
                    maintainAspectRatio: false
                }
            },
            type: 'bar',
            data: {
                labels: labels,
                datasets: [
                    {
                        label: 'Unit Sales',
                        data: data
                    }
                ]
            }
        });
    });
</script>

<div class="chart-container">
    <canvas bind:this={canvas} />
</div>

<style>
    div {
        position: relative;
        height: 100vh;
        width: 100vw;
    }
</style>

请问还有什么办法解决这个问题?


解决方法

1. 修正Chart.js响应式配置的位置

你已经设置了responsive: true和maintainAspectRatio: false,但这两个属性是options下的顶级配置,不能嵌套在layout对象里。调整代码如下:

var chart = new Chart(ctx, {
    options: {
        responsive: true,
        maintainAspectRatio: false,
        // 其他配置项
    },
    // 图表类型、数据等其他参数
});

错误的嵌套位置会导致Chart.js无法识别响应式配置,这是核心问题之一。

2. 监听窗口resize事件并触发图表重绘

即使配置正确,Svelte的DOM更新和Chart.js的响应式触发可能不同步,需要手动监听窗口大小变化,调用图表的resize()方法:

修改onMount中的代码,添加resize监听:

onMount(() => {
    const ctx = canvas.getContext('2d');
    const chart = new Chart(ctx, {
        options: {
            responsive: true,
            maintainAspectRatio: false
        },
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: 'Unit Sales',
                data: data
            }]
        }
    });

    // 监听窗口resize
    const handleResize = () => {
        chart.resize();
    };
    window.addEventListener('resize', handleResize);

    // 组件销毁时清理监听和图表实例,避免内存泄漏
    return () => {
        window.removeEventListener('resize', handleResize);
        chart.destroy();
    };
});

3. 给canvas设置占满容器的样式

Chart.js会自动给canvas生成内联样式,需要强制让它继承容器尺寸:

.chart-container canvas {
    width: 100% !important;
    height: 100% !important;
}

完整修正后的代码

<script>
    import { onMount } from 'svelte';
    import Chart from 'chart.js/auto';

    let data = [20, 100, 50, 12, 20, 130, 45];
    let labels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
    let canvas;

    onMount(() => {
        const ctx = canvas.getContext('2d');
        const chart = new Chart(ctx, {
            options: {
                responsive: true,
                maintainAspectRatio: false
            },
            type: 'bar',
            data: {
                labels: labels,
                datasets: [{
                    label: 'Unit Sales',
                    data: data
                }]
            }
        });

        const handleResize = () => {
            chart.resize();
        };
        window.addEventListener('resize', handleResize);

        return () => {
            window.removeEventListener('resize', handleResize);
            chart.destroy();
        };
    });
</script>

<div class="chart-container">
    <canvas bind:this={canvas} />
</div>

<style>
    .chart-container {
        position: relative;
        height: 100vh;
        width: 100vw;
    }

    .chart-container canvas {
        width: 100% !important;
        height: 100% !important;
    }
</style>

内容的提问来源于stack exchange,提问作者andrewshih

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:20:42