Live2d Test Env

echart动态渲染宽高度

先说需求与思路

  1. 需求:三个按钮,分别是展示前十、后十、与全部 下方的图表要动态的配置宽高,(通常情况下是某一边)

  2. 思路: 父组件根据传入数组长度动态设置overflow 如果是auto,则会根据子元素即echart容器是否溢出来显示滚动条,内部的echart元素可以根据长度来动态设置宽高,初始值可以自行调整

本例中为动态设置高,给父元素加scrollRef是为了让其在按钮切换时可以将高度重置为0

dom

    <div ref={scrollRef} style={{ overflowY: myArr.length > 10 ? 'auto' : 'hidden', overflowX: 'hidden', height: 400 }}>
        <div ref={divRef} style={{
          height: 400
        }} >
        </div>
      </div>

逻辑

// 本组件为echart图表 前后都为十条,全部则所有的数据
function MyEchart({receive}){
//  receive:源数据 divRef:echart元素  scrollRef:echart父元素 
   const divRef = useRef()
   const scrollRef = useRef()
  // 初始化时,默认渲染前十条
  const [myArr, setmyArr] = useState(receive.slice(0, 10))
  // 单选框 
  const [showType, setShowType] = useState('0')
  // 过滤方法,根据key动态切割源数据
   const filterArr = {
      '0': () => receive.slice(0, 10),
      '1': () => receive.slice(-10),
      '2': () => receive
    }
    // 切割数组的方法
    const streamRepairList = (index) => {
      setmyArr(pre => filterArr[index]())
    }
    // 在useeffect中,定义echart并动态定义宽高
useEffect(() => {
    if (!divRef.current) return
    let timer
    // 如果父元素有current,则将其父元素的高度设为0
    if (scrollRef.current) {
      scrollRef.current.scrollTop = 0
    }
    const option = {...} // 不再赘述
    // 如果有chart实例,则让其重渲染
    if (myChart) {
      myChart.resize()
    }
    // 这里为根据myarr高度动态定义的单个柱子的长度
   const echartHeight = myArr.length > 10 ? 40 : 46
    // 生成mychart实例
    const myChart = echarts.getInstanceByDom(divRef.current) ?? echarts.init(divRef.current, ECHARTS_THEME)
   // 关键代码!!!!!!!!!!!!!!!动态设置echart元素的高度
    myChart.getDom().style.height = `${myArr.length * echartHeight}px`
   // 关键代码!!!!!!!!!!!!!!!
    myChart.setOption(option)
   // 如果屏幕宽高有变化,则重新渲染
    window.onresize = () => {
      myChart.resize()
    }
    // 判断外部传入数组是否有值,如果有则执行延时器
    if (myArr.length > 0) {
      timer = setTimeout(() => {
        myChart?.resize()
      }, 10)
    }
    return () => {
      timer && clearTimeout(timer)
      //   卸载前销毁echart便节省性能
      myChart.dispose()
    }
},[myArr]}
//return的dom在上方有写
}

想到可能有的读者想看下y轴services

      series: [
        { 
          data: myArr.map(v => v.num),
          type: 'bar',
          barGap: 10,
          smooth: true,
          barWidth: 20,
          label: {
            show: true,
            position: 'right',
            // formatter: "{c}",
            offset: [5, -2]
          },
        }
      ],
      yAxis: {
        type: 'category',
        inverse: true, // 是否倒叙
        axisTick: false,
        axisLine: {
          show: true
        },
        splitLine: {
          lineStyle: {
            color: '#00000026',
          }
        },
        axisLabel: {
          show: true,
          color: '#00000073',
          fontSize: 12,
          interval: 0,
          textStyle: {
            lineHeight: 16,
          },
        },
        data: myArr.map(v => v.name)
      },

以上。

posted @ 2023-02-16 14:43  致爱丽丝  阅读(388)  评论(0编辑  收藏  举报