You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flexbox布局下C3图表窗口缩小显示异常问题求助

解决Flexbox布局下C3图表窗口缩小时显示异常的问题

我仔细看了你的实现,问题出在C3图表没有及时响应窗口尺寸的变化,再加上flex布局的特性,缩小窗口时容器尺寸更新了,但图表没有跟着重新计算布局,导致显示异常。咱们来一步步修复:

问题根源拆解

  1. 你只在图表初始化的onresized回调里执行了fixSize,但这个回调只有图表内部触发resize时才会跑,窗口手动缩小/放大时不会触发。
  2. flex容器#widget-container的尺寸变化后,C3没有自动感知到,需要手动触发图表的resize逻辑。
  3. CSS里用!important强制设置C3容器尺寸,虽然能生效,但容易覆盖C3内部的尺寸计算逻辑,反而引发冲突。

修复方案

1. 添加窗口resize监听 + 防抖优化

窗口resize事件会频繁触发,咱们加个简单的防抖函数,避免频繁调用图表resize影响性能,同时确保每次窗口调整完成后都触发图表尺寸更新。

2. 优化尺寸修正函数

确保fixSize能正确获取容器的最新尺寸,并且调用C3的resize方法时传递正确的参数。

3. 调整CSS约束

去掉不必要的!important,用更合理的样式继承确保图表铺满容器。

修改后的完整代码

HTML部分

<html lang="en">
<head>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.min.css" rel="stylesheet">
</head>
<body>
  <h1>A chart!</h1>
  <div id="widget-container">
    <div id="chart_a"></div>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.min.js"></script>
</body>
</html>

CSS部分

body{
  height: 100vh ;
  width: 100vw ;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin: 0; /* 去掉默认margin,避免出现滚动条 */
  padding: 0;
}
#widget-container{
  background-color: fuchsia;
  flex-grow: 1;
  position: relative; /* 确保子元素能正确继承尺寸 */
}
#chart_a, div.c3{
  height: 100% !important;
  width: 100% !important;
}

JavaScript部分

function showChart(config){ 
  return c3.generate(config); 
}

// 防抖函数:避免resize频繁触发
function debounce(func, delay = 100) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, arguments), delay);
  }
}

function fixSize() {
  const container = document.getElementById("widget-container");
  if (container && cs) {
    cs.resize({
      height: container.clientHeight, 
      width: container.clientWidth
    });
  }
}

// 初始化图表数据
var labels = ['Month 0', 'Month 18', 'Month 24', 'Month 30', 'Month 36'];
var values = ['Index', 4, 4, null, null, null];
labels.unshift('x');

var config = {
  bindto: d3.select("#chart_a"),
  onresized: fixSize,
  line: { connectNull: true },
  legend: { show: false },
  data: {
    x : "x",
    columns: [ labels, values ],
    type: "bar"
  },
  grid: {
    show: true,
    y: {
      lines: [
        {value: 8, text: 'Goal', class: 'goal'},
        {value: 4, text: 'Baseline', class:'baseline'}
      ]
    }
  },
  axis: {
    x: { type: 'category' },
    y:{ show:false, max: 9 }
  }
};

let cs = showChart(config);
cs.flush();

// 监听窗口resize事件,触发图表尺寸修正
window.addEventListener('resize', debounce(fixSize));

// 初始化时先执行一次,确保图表尺寸正确
fixSize();

关键修改说明

  • 防抖函数:避免窗口resize时频繁调用图表resize,提升性能。
  • 窗口resize监听:确保每次窗口尺寸变化时,图表都会重新计算布局。
  • CSS调整:去掉body的默认margin/padding,避免出现不必要的滚动条;给#widget-containerposition: relative,确保子元素的尺寸继承更可靠。
  • 初始化触发fixSize:确保页面加载完成后图表就能正确铺满容器。

这样修改后,不管窗口放大还是缩小,图表都会跟着容器尺寸同步变化,不会再出现显示异常的问题啦~

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

火山引擎 最新活动