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

如何让Chart.js图表适配Bootstrap/Vue容器尺寸?

问题:Chart.js图表破坏Bootstrap布局且无法适配容器尺寸

我的页面用Bootstrap布局,包含两个row,每行通过h-50类占页面一半高度。但在其中一列嵌入Chart.js图表后,该行被自动撑满整个页面,布局被破坏;图表虽然在页面缩放时有响应性,但无法适配所在列的容器尺寸。

页面布局代码:

<div class="border border-info" style="height:95%">
    <div class="row border border-primary h-50">
        <div class="col border border-danger w-50" >
            <DayChart></DayChart>
        </div>
        <div class="col border border-success w-50">
            today
        </div>
    </div>
    <div class="row border border-warning h-50">
        <div class="col border border-primary">
            zach put ur d3 here
        </div>
    </div>
</div>

图表组件(DayChart)代码:

<template>
    <Doughnut
      :chart-options="chartOptions"
      :chart-data="chartData"
      :chart-id="chartId"
      :dataset-id-key="datasetIdKey"
      :plugins="plugins"
      :css-classes="cssClasses"
      :styles="styles"
      :width="width"
      :height="height"
    />
</template>

<script>
    import { defineComponent, h } from 'vue';
    
    import { Doughnut } from 'vue-chartjs';
    
    import { Chart as ChartJS, Title, Tooltip, Legend, ArcElement, CategoryScale } from 'chart.js';
    
    ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale);
    
    export default defineComponent({
        name: 'DayChart',
        components: {
            Doughnut
        },
        props: {
            chartId: {
                type: String,
                default: 'doughnut-chart'
            },
            datasetIdKey: {
                type: String,
                default: 'label'
            },
            width: {
                type: Number,
                default: 100,
            },
            height: {
                type: Number,
                default: 100,
            },
            cssClasses: {
                default: '',
                type: String
            },
            styles: {
                default: {}
            },
            plugins: {
                default: []
            },
            chartData: {
                type: Object,
                default: () => ({
                    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
                    datasets: [{
                        label: '# of Votes',
                        data: [12, 19, 3, 5, 2, 3],
                        backgroundColor: [
                            'rgba(255, 99, 132, 0.2)',
                            'rgba(54, 162, 235, 0.2)',
                            'rgba(255, 206, 86, 0.2)',
                            'rgba(75, 192, 192, 0.2)',
                            'rgba(153, 102, 255, 0.2)',
                            'rgba(255, 159, 64, 0.2)'
                        ]
                    }]
                })
            }
        },
        setup(props) {
            return () =>
                h(Doughnut, {
                    chartData: props.chartData,
                    chartOptions: props.chartOptions,
                    chartId: props.chartId,
                    width: props.width,
                    height: props.height,
                    cssClasses: props.cssClasses,
                    styles: props.styles,
                    plugins: props.plugins
                });
        }
    });
</script>

解决方案

1. 移除图表固定宽高,让容器主导尺寸

当前DayChart组件默认设置了width:100和height:100的固定值,这会强制图表保持固定尺寸,破坏容器布局。修改组件的props,将宽高默认值改为undefined,让Chart.js自动读取容器尺寸:

// 在DayChart的props中修改
width: {
  type: Number,
  default: undefined,
},
height: {
  type: Number,
  default: undefined,
},

或者在父组件调用时直接覆盖这两个属性:

<DayChart :width="undefined" :height="undefined"></DayChart>

2. 配置Chart.js响应式选项

给chartOptions添加响应式配置,确保图表能完全适配容器,并且不强制固定宽高比:
在DayChart组件中新增chartOptions的props默认值:

props: {
  // ...其他props
  chartOptions: {
    type: Object,
    default: () => ({
      responsive: true, // 开启响应式
      maintainAspectRatio: false, // 关闭固定宽高比,完全适配容器尺寸
      // 可添加其他图表配置,比如标题、提示框等
    })
  }
}

3. 强化Bootstrap容器的高度约束

给图表所在的列添加h-100类,让列占满所在行的高度,避免高度塌陷:

<div class="col border border-danger w-50 h-100">
  <DayChart></DayChart>
</div>

同时确保外层容器的高度设置合理,比如将外层容器的height:95%改为height:100vh(占满视口高度),确保h-50类能正确计算高度:

<div class="border border-info" style="height: 100vh;">
  <!-- ...row内容 -->
</div>

4. 手动监听容器尺寸变化(可选)

如果图表在容器尺寸变化时没有自动更新,可以监听窗口resize事件,手动触发图表重绘:
在DayChart的setup函数中添加监听逻辑:

import { defineComponent, h, onMounted, onUnmounted } from 'vue';

// ...其他导入代码

setup(props) {
  let chartInstance = null;

  // 获取图表实例
  const onChartMounted = (chart) => {
    chartInstance = chart;
  };

  // 处理窗口resize
  const handleResize = () => {
    chartInstance?.resize();
  };

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

  onUnmounted(() => {
    window.removeEventListener('resize', handleResize);
  });

  return () =>
    h(Doughnut, {
      chartData: props.chartData,
      chartOptions: props.chartOptions,
      chartId: props.chartId,
      width: props.width,
      height: props.height,
      cssClasses: props.cssClasses,
      styles: props.styles,
      plugins: props.plugins,
      onChartMounted // 绑定图表挂载回调
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:35:26