vue-echarts/echarts结合flex布局,v-show,charts无法自动计算容器大小自适应

vue-echarts/echarts结合flex布局,v-show,charts无法自动计算容器大小自适应

<template>
  <v-chart ref="child" class="chart" :autoresize="true" :option="option" />
</template>

问题1: 首先设置一个非常简单的echarts或v-charts,注意autoresize=true这个参数一定要设置,否则echart无法自动适应容器大小变化

<template>
  <button
    v-for="(show, index) in chartShows"
    :key="index"
    @click="changeShow(index)"
    style="width: 200px"
  >
    helloword{{ index + 1 }}
  </button>
   <ChangeableChart
      v-show="show"
      :autoresize="true"
      v-for="(show, index) in chartShows"
      :key="index"
    />
</template>

<script lang="ts" setup>
import ChangeableChart from './components/ChangeableChart.vue'
import { nextTick, getCurrentInstance, ref, reactive } from 'vue'
const chartShows = reactive([true, true, true, true])
const textStyle = ref(true)
const vChart = ref()
const changeShow = (id) => {
  chartShows[id] = !chartShows[id]
}
</script>

问题2 这种写法的问题是隐藏后,echart的display:none,变化为display:block后无法在次获取到布局的大小,虽然可见但没有高度

解决方式是在echarts外面包裹一层div

    <div
      class="content"
      v-show="show"
      :autoresize="true"
      v-for="(show, index) in chartShows"
      :key="index"
    >
      <ChangeableChart ref="vChart" />
    </div>

问题3 经过上述操作后,div可见度可以调整,图表可以适应容器大小变化,但是多个图表隐藏一个后,其余的放大以适应屏幕,重新显示时,无法根据变化缩小,导致溢出到屏幕外面

原因可能是echart自适应不能响应div变化

解决方式:在div变化完成后,在手动调用图表自适应api调整大小

const changeShow = (id) => {
  chartShows[id] = !chartShows[id]
  nextTick(() => {
    vChart.value.forEach((item, index) => {
      if (index !== id) {
        item.resize()
      }
    })
  })
}

最后贴上完整代码

<template>
  <v-chart ref="child" class="chart" :autoresize="true" :option="option" />
</template>
<script setup>
import { getCurrentInstance, onBeforeMount, onMounted, reactive, ref, computed } from 'vue'
import 'echarts'
const child = ref(null)
import VChart from 'vue-echarts'
const data = ref([
  ['2000-06-05', 116],
  ['2000-06-06', 129],
  ['2000-06-07', 135],
  ['2000-06-08', 86],
  ['2000-06-09', 73],
  ['2000-06-10', 85],
  ['2000-06-11', 73],
  ['2000-06-12', 68],
  ['2000-06-13', 92],
  ['2000-06-14', 130],
  ['2000-06-15', 245],
  ['2000-06-16', 139],
  ['2000-06-17', 115],
  ['2000-06-18', 111],
  ['2000-06-19', 309],
  ['2000-06-20', 206],
  ['2000-06-21', 137],
  ['2000-06-22', 128],
  ['2000-06-23', 85],
  ['2000-06-24', 94],
  ['2000-06-25', 71],
  ['2000-06-26', 106],
  ['2000-06-27', 84],
  ['2000-06-28', 93],
  ['2000-06-29', 85],
  ['2000-06-30', 73],
  ['2000-07-01', 83],
  ['2000-07-02', 125],
  ['2000-07-03', 107],
  ['2000-07-04', 82],
  ['2000-07-05', 44],
  ['2000-07-06', 72],
  ['2000-07-07', 106],
  ['2000-07-08', 107],
  ['2000-07-09', 66],
  ['2000-07-10', 91],
  ['2000-07-11', 92],
  ['2000-07-12', 113],
  ['2000-07-13', 107],
  ['2000-07-14', 131],
  ['2000-07-15', 111],
  ['2000-07-16', 64],
  ['2000-07-17', 69],
  ['2000-07-18', 88],
  ['2000-07-19', 77],
  ['2000-07-20', 83],
  ['2000-07-21', 111],
  ['2000-07-22', 57],
  ['2000-07-23', 55],
  ['2000-07-24', 60],
  ['2000-07-25', 44],
  ['2000-07-26', 127],
  ['2000-07-27', 114],
  ['2000-07-28', 86],
  ['2000-07-29', 73],
  ['2000-07-30', 52],
  ['2000-07-31', 69],
  ['2000-08-01', 86],
  ['2000-08-02', 118],
  ['2000-08-03', 56],
  ['2000-08-04', 91],
  ['2000-08-05', 121],
  ['2000-08-06', 127],
  ['2000-08-07', 78],
  ['2000-08-08', 79],
  ['2000-08-09', 46],
  ['2000-08-10', 108],
  ['2000-08-11', 80],
  ['2000-08-12', 79],
  ['2000-08-13', 69],
  ['2000-08-14', 80],
  ['2000-08-15', 105],
  ['2000-08-16', 119],
  ['2000-08-17', 105],
  ['2000-08-18', 55],
  ['2000-08-19', 74],
  ['2000-08-20', 41],
  ['2000-08-21', 62],
  ['2000-08-22', 104],
  ['2000-08-23', 118],
  ['2000-08-24', 121],
  ['2000-08-25', 126],
  ['2000-08-26', 99],
  ['2000-08-27', 92],
  ['2000-08-28', 75],
  ['2000-08-29', 91],
  ['2000-08-30', 94],
  ['2000-08-31', 69],
  ['2000-09-01', 93],
  ['2000-09-02', 124],
  ['2000-09-03', 120],
  ['2000-09-04', 93],
  ['2000-09-05', 26],
  ['2000-09-06', 32],
  ['2000-09-07', 70],
  ['2000-09-08', 89],
  ['2000-09-10', 117],
  ['2000-09-11', 144]
])
const resize = () => {
  child.value.resize()
}

const option = computed(() => {
  return {
    title: {
      show: true,
      text: 'Beijing AQI',
      left: '1%',
      top: '10%',
      textStyle: {
        color: 'white'
      }
    },
    // tooltip: {
    //   show: false,
    //   trigger: 'axis'
    // },
    grid: {
      top: 20,
      left: 60,
      right: 20,
      bottom: 40
    },
    xAxis: {
      axisLabel: {
        color: '#FFF'
      },
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      data: data.value.map(function (item) {
        return item[0]
      })
    },
    yAxis: {
      //隐藏y轴标签
      axisLabel: {
        show: false
      },
      //隐藏y刻度线
      splitLine: {
        show: false
      }
    },
    // toolbox: {
    //   right: 10,
    //   feature: {
    //     dataZoom: {
    //       yAxisIndex: 'none'
    //     },
    //     restore: {},
    //     saveAsImage: {}
    //   }
    // },
    // dataZoom: [
    //   {
    //     startValue: '2014-06-01'
    //   },
    //   {
    //     type: 'inside'
    //   }
    // ],
    visualMap: {
      show: false,
      top: 50,
      right: 10,
      pieces: [
        {
          gt: 0,
          lte: 50,
          color: '#93CE07'
        },
        {
          gt: 50,
          lte: 100,
          color: '#FBDB0F'
        },
        {
          gt: 100,
          lte: 150,
          color: '#FC7D02'
        },
        {
          gt: 150,
          lte: 200,
          color: '#FD0100'
        },
        {
          gt: 200,
          lte: 300,
          color: '#AA069F'
        },
        {
          gt: 300,
          color: '#AC3B2A'
        }
      ],
      outOfRange: {
        color: '#999'
      }
    },
    series: {
      name: 'Beijing AQI',
      type: 'line',
      axisTick: {
        show: false
      },
      axisLine: { show: false },
      data: data.value.map(function (item) {
        return item[1]
      }),
      //标线设置
      markLine: {
        symbol: 'none', // 移除箭头
        silent: true,
        lineStyle: {
          type: 'solid', // 设置为实线
          width: 2 // 设置线宽
        },
        label: {
          show: true, // 显示标签
          color: 'white', // 设置默认标签文字颜色
          position: 'start',
          distance: 20
        },
        data: [
          {
            yAxis: 50,
            lineStyle: {
              color: '#8C1C3E'
            }
          },
          {
            yAxis: 100,
            lineStyle: {
              color: '#8C9C3E'
            }
          },
          {
            yAxis: 150,
            lineStyle: {
              color: '#0B6136'
            }
          },
          {
            yAxis: 200,
            lineStyle: {
              color: '#BFC822'
            }
          },
          {
            yAxis: 250,
            lineStyle: {
              color: '#8C1C3E'
            }
          }
        ]
      }
    }
  }
})

const setData = () => {
  setInterval(() => {
    data.value.forEach((item) => {
      item[1] = Math.round(Math.random() * 2)
    })
  }, 500)
}
const { proxy } = getCurrentInstance()
const emits = defineEmits([])
const props = defineProps({})
const state = reactive({})
onBeforeMount(() => {})
onMounted(() => {
  // setData()
})
defineExpose({ resize })
</script>
<style scoped>
.chart {
  border-top: 2px solid #3d76e9;
  border-right: 2px solid #3d76e9;
  border-left: 2px solid #3d76e9;
  border-bottom: none;
  /* background-color: #1a397d; */
  box-sizing: border-box; /* 更改盒模型计算方式 */
}
</style>

<script lang="ts" setup>
import ChangeableChart from './components/ChangeableChart.vue'
import { nextTick, getCurrentInstance, ref, reactive } from 'vue'
const chartShows = reactive([true, true, true, true])
const textStyle = ref(true)
const vChart = ref()
const changeShow = (id) => {
  chartShows[id] = !chartShows[id]
  nextTick(() => {
    vChart.value.forEach((item, index) => {
      if (index !== id) {
        item.resize()
      }
    })
  })
}
</script>

<template>
  <button
    v-for="(show, index) in chartShows"
    :key="index"
    @click="changeShow(index)"
    style="width: 200px"
  >
    helloword{{ index + 1 }}
  </button>
  <div class="charts">
    <div
      class="content"
      v-show="show"
      :autoresize="true"
      v-for="(show, index) in chartShows"
      :key="index"
    >
      <ChangeableChart ref="vChart" />
    </div>
  </div>
</template>

<style scoped>
header {
  line-height: 1.5;
}
.charts {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.logo {
  display: block;
  margin: 0 auto 2rem;
}
.content {
  flex: 1;
  overflow: hidden;
  /* display: flex;
  flex-direction: column; */
}
.wrapper {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
@media (min-width: 1024px) {
  header {
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }
}
</style>


不足之处,欢迎交流

码字不易,如果帮助到您,麻烦您的小手点一下赞,让更多的人看到

posted @ 2024-07-16 16:44  别动我神奇小饼干  阅读(325)  评论(0)    收藏  举报