echarts 随窗口的移动,改变图表size

错误写法:

// 错误原因:依赖项数组的用法不符合 React 响应式原理
useEffect(() => {
  // ...
}, [PieRef, PieRef.current?.clientHeight, PieRef.current?.clientHeight]);

关键问题

以上三点得出:这个pie ref 这样子盯着变动是无效的。

正确的写法是👇,关键点在 resizeObserver这里,类似intercetion observer, 这样直接观察pie ref 就不需要再去手动判断宽高,这很好了

  const PieRef = useRef<HTMLDivElement | null>(null);
  const chartInstance = useRef<echarts.ECharts>(undefined);
  const resizeObserver = useRef<ResizeObserver>(undefined);

  useEffect(() => {
    chartInstance.current = echarts.init(PieRef.current);
    chartInstance.current?.setOption(option);

    resizeObserver.current = new ResizeObserver((entries) => {
      if (entries[0].contentRect.width > 0) {
        chartInstance.current?.resize({
          animation: { duration: 1000 }, // 添加平滑过渡
        });
      }
    });
    if (!PieRef.current) return;
    resizeObserver.current.observe(PieRef.current);

    return () => {
      if (chartInstance.current) {
        chartInstance.current.dispose();
        resizeObserver.current?.disconnect();
      }
    };
  }, [option.series]);
  
		  

这个里面,一样的结构,entires里先事0

然后里面东西很全啊

就这样,可以拿contentRect - width

  1. PieRef 是 ref 对象,其引用地址永远不会变化
  2. clientHeight 是派生值,React 无法自动检测其变化
  3. 依赖项数组中实际只有 undefined(首次渲染时)会被跟踪

### Vue 项目 ECharts 图表实现响应式布局 #### 使用 `flexible` 和 `cssrem` 插件进行基础适配 为了确保整个项目的布局能够在不同分辨率下正常显示,推荐先引入并配置 `flexible` 插件[^1]。此插件通过调整 HTML 文档根元素字体大小的方式,使得页面中的尺寸单位可以从 px 转换为相对单位 rem,从而达到更好的跨屏兼容效果。 ```javascript // main.js 或入口文件中引入 flexible import 'flexible' ``` 接着,在全局样式文件中定义好基本的比例关系: ```scss /* style.scss */ html { font-size: 16px; } @media screen and (max-width: 768px){ html{ font-size: 14px !important; } } body { margin: 0; padding: 0; box-sizing: border-box; } ``` #### 设置容器宽度采用百分比而非绝对像素值 对于承载 ECharts 的 DOM 容器而言,应避免为其指定固定的宽度和高度属性,而是利用 CSS 百分比形式来表达其尺寸,以便于跟随父级元素的变化而自动伸缩[^3]。 ```html <div id="chart-container" class="container"></div> ``` ```scss .container { width: 90%; /* 占据父元素90%的空间 */ height: calc(100vh - 2em); /* 高度可以根据视口高度计算得出 */ background-color: white; position: relative; } ``` #### 动态监听窗口变动事件触发重绘操作 为了让图表能及时感知到浏览器窗口尺寸的动态变化,可以在初始化完成后注册一个针对 `window.resize` 事件的处理函数,每当检测到屏幕尺寸发生改变时便调用 ECharts 实例对象上的 `.resize()` 方法强制刷新图表绘制区域[^2]。 ```typescript <template> <div ref="myChartRef" :style="{width:'100%',height:'100%' }"></div> </template> <script setup lang="ts"> import * as echarts from 'echarts'; import { onMounted, ref, nextTick } from 'vue'; const myChartRef = ref(null); let chartInstance; onMounted(() => { const initChart = () => { if (!chartInstance && myChartRef.value) { chartInstance = echarts.init(myChartRef.value); // 初始化数据... window.addEventListener('resize', handleWindowResize); } }; function handleWindowResize() { setTimeout(() => { if (chartInstance) { chartInstance.resize(); } }, 200); } nextTick(initChart); }); defineExpose({ destroy }); function destroy(){ window.removeEventListener('resize',handleWindowResize ); } </script> ``` 以上措施结合起来可以帮助开发者构建出具有良好弹性的可视化界面,无论是在桌面端还是移动设备上都能保持良好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值