vue中通过tabs 切换 时 显示不同的echarts 特殊处理

发布于:2025-07-07 ⋅ 阅读:(36) ⋅ 点赞:(0)

需要进行特殊处理 

比如强制 进行resize 的方法 不然 大小显示会出现问题

我先把全部的代码弄上

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { message } from 'ant-design-vue'
import { useBrandStore } from '@/store/modules/brand'
import { Chart } from '@antv/g2'
import * as  echarts from 'echarts'
import { InfoCircleOutlined, CaretUpOutlined, CaretDownOutlined } from '@ant-design/icons-vue'

const brandStore = useBrandStore()
const route = useRoute()
const chart1 = ref(null)
const chart2 = ref(null)
const chartInstances = ref<{
  chart1: echarts.ECharts | null
  chart2: echarts.ECharts | null
}>({
  chart1: null,
  chart2: null
})

// 初始化图表实例
const initChartInstance = (container: HTMLElement | null) => {
  if (!container) return null
  return echarts.init(container)
}

// 初始化所有图表
const initAllCharts = () => {
  chartInstances.value.chart1 = initChartInstance(chart1.value)
  chartInstances.value.chart2 = initChartInstance(chart2.value)

  // 设置初始选项
  if (chartInstances.value.chart1) {
    initChart1()
  }
  if (chartInstances.value.chart2) {
    initChart2()
  }

  // 添加resize事件监听
  const resizeHandler = () => {
    Object.values(chartInstances.value).forEach(chart => {
      chart?.resize()
    })
  }
  window.addEventListener('resize', resizeHandler)

  // 组件卸载时清理
  onBeforeUnmount(() => {
    window.removeEventListener('resize', resizeHandler)
    Object.values(chartInstances.value).forEach(chart => {
      chart?.dispose()
    })
  })
}



const initChart = () => {
  var myChart = echarts.init(document.getElementById('chartContainer'));

  var option = {
    tooltip: {
      trigger: 'axis', // 触发类型,'axis' 表示在坐标轴上触发

      formatter: function (params) {
        // 自定义提示框内容
        var result = params[0].axisValue + '<br/>';
        result += '曝光数: ' + params[0].data;
        return result;
      }
    },
    grid: {
      top: 5,
      right: 5,
      bottom: 5,
      left: 5
    },
    xAxis: {
      type: 'category',
      // data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      show: false
    },
    yAxis: {
      type: 'value',
      show: false
    },
    series: [{
      data: [264, 417, 438, 887, 309, 397, 550, 575, 563, 430, 525, 592, 492, 467, 513,
        546, 983, 340, 539, 243, 226, 192,],
      type: 'line',
      smooth: true,
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
          offset: 0,
          color: 'rgba(128, 109, 224, 0.3)'
        }, {
          offset: 1,
          color: 'rgba(128, 109, 224, 0)'
        }])
      },
      lineStyle: {
        color: '#806de0'
      },
      symbol: 'none'
    }]
  };
  myChart.setOption(option);
  window.addEventListener('resize', function () {
    myChart.resize();
  });

}

const tabs = ref(["询单转换分析图", "热度数据分析图"])
const activeTab = ref(0)
onMounted(() => {
  initChart()
  initAllCharts()

})
const handleChangeTabs = async(index: any) => {
  activeTab.value = index
  // 等待DOM更新完成
  await nextTick()

  // 强制触发所有图表的resize
  Object.values(chartInstances.value).forEach(chart => {
    chart?.resize()
  })

  if (index == 0) {
    initChart1()
  }
  if (index == 1) {
    initChart2()
  }
}

const initChart1 = () => {
  var myChart = echarts.init(chart1.value);

  // 指定图表的配置项和数据
  var option = {
    title: {
      // text: '询单转化分析图',
      // subtext: '热度数据分析图'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      data: ['询单次', '支付单数'],

    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: ['2025-05-29', '2025-05-30', '2025-05-31', '2025-06-01', '2025-06-02', '2025-06-03', '2025-06-04']
    },
    yAxis: {
      type: 'value'
    },
    series: [
      {
        name: '询单次',
        type: 'bar',
        barWidth: '40%', // 调整柱子的宽度
        itemStyle: {
          color: '#1E90FF' // 蓝色
        },
        data: [50, 300, 600, 580, 480, 280, 100]
      },
      {
        name: '支付单数',
        type: 'bar',
        barWidth: '40%',
        itemStyle: {
          color: '#00CED1' // 绿色
        },
        data: [200, 400, 450, 300, 200, 100, 20]
      }
    ]
  };


  // 使用配置项显示图表
  myChart.setOption(option);
  window.addEventListener('resize', function () {
    myChart.resize();
  });

}
const initChart2 = () => {

  const myChart = echarts.init(chart2.value);

  const option = {
    title: {
      // text: '数据趋势分析',
      // subtext: '想要数、浏览数、曝光数变化趋势',
      left: 'center'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      }
    },
    legend: {
      data: ['想要数', '浏览数', '曝光数'],
      top: 30
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: ['2025-05-28', '2025-05-29', '2025-05-30', '2025-05-31', '2025-06-01', '2025-06-02', '2025-06-03']
    },
    yAxis: {
      type: 'value'
    },
    series: [
      {
        name: '曝光数',
        type: 'line',
        stack: '总量',
        areaStyle: {},
        emphasis: {
          focus: 'series'
        },
        data: [10, 20, 200, 180, 10, 5, 2],
        itemStyle: {
          color: '#73DDD7' // 浅青色
        },
        lineStyle: {
          width: 2
        },
        symbol: 'circle',
        symbolSize: 8
      },
      {
        name: '浏览数',
        type: 'line',
        stack: '总量',
        areaStyle: {},
        emphasis: {
          focus: 'series'
        },
        data: [5, 15, 160, 150, 8, 3, 1],
        itemStyle: {
          color: '#FFD591' // 浅橙色
        },
        lineStyle: {
          width: 2
        },
        symbol: 'circle',
        symbolSize: 8
      },
      {
        name: '想要数',
        type: 'line',
        stack: '总量',
        areaStyle: {},
        emphasis: {
          focus: 'series'
        },
        data: [2, 10, 80, 70, 5, 2, 0.5],
        itemStyle: {
          color: '#A6C8FF' // 浅蓝色
        },
        lineStyle: {
          width: 2
        },
        symbol: 'circle',
        symbolSize: 8
      }
    ]
  };

  myChart.setOption(option);

  // 响应式调整
  window.addEventListener('resize', function () {
    myChart.resize();
  });
}


const storeList = ref([
  {
    id: 1,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 2,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 3,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 4,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 5,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 6,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 7,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 8,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 9,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 10,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 1,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 2,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 3,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 4,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 5,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 6,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 7,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 8,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 9,
    name: "xxxxxxxxxx",
    number: 323214
  },
  {
    id: 10,
    name: "xxxxxxxxxx",
    number: 323214
  }
])

</script>
<template>
  <page-container :title="route.meta.title">
    <!-- <a-card>待开发...</a-card> -->
    <a-row :gutter="[16, 24]">
      <a-col class="gutter-row" :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-card>
          <div class="col-data-item">
            <div class="col-data-item__title">
              <div>影票代订-询单次数-今日实时</div>
              <InfoCircleOutlined />
            </div>
            <div class="col-data-item__number">163次</div>
            <div class="col-data-item__compare">
              <div class="compare_1">
                <div class="compare_1__title">周同比</div>
                <div class="compare_1__number">
                  <span>12%</span>
                  <span>
                    <CaretUpOutlined style="color: red" />
                  </span>
                </div>
              </div>
              <div class="compare_2">
                <div class="compare_1__title">日同比</div>
                <div class="compare_1__number">
                  <span>12%</span>
                  <span>
                    <CaretDownOutlined style="color: green" />
                  </span>
                </div>
              </div>
            </div>
            <div class="col-data-item__line">
              <a-divider style="height: 1px; background-color: #f7f8f9; padding: 0" />
            </div>
            <div class="col-data-item__footer">
              <div>
                <span>支付单数 35单</span>
                <span>转换率 (21.4%)</span>
              </div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col class="gutter-row" :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-card>
          <div class="col-data-item">
            <div class="col-data-item__title">
              <div>影票代订-订单提交-今日实时</div>
              <InfoCircleOutlined />
            </div>
            <div class="col-data-item__number">163次</div>
            <div class="col-data-item__compare">
              <div class="compare_1">
                <div class="compare_1__title">周同比</div>
                <div class="compare_1__number">
                  <span>12%</span>
                  <span>
                    <CaretUpOutlined style="color: red" />
                  </span>
                </div>
              </div>
              <div class="compare_2">
                <div class="compare_1__title">日同比</div>
                <div class="compare_1__number">
                  <span>12%</span>
                  <span>
                    <CaretDownOutlined style="color: green" />
                  </span>
                </div>
              </div>
            </div>
            <div class="col-data-item__line">
              <a-divider style="height: 1px; background-color: #f7f8f9; padding: 0" />
            </div>
            <div class="col-data-item__footer">
              <div>
                <span>支付单数 35单</span>
                <span>转换率 (21.4%)</span>
              </div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col class="gutter-row" :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-card>
          <div class="col-data-item">
            <div class="col-data-item__title">
              <div>影票代订-订单利润-今日实时</div>
              <InfoCircleOutlined />
            </div>
            <div class="col-data-item__number">163次</div>
            <div class="col-data-item__compare">
              <div class="compare_1">
                <div class="compare_1__title">周同比</div>
                <div class="compare_1__number">
                  <span>12%</span>
                  <span>
                    <CaretUpOutlined style="color: red" />
                  </span>
                </div>
              </div>
              <div class="compare_2">
                <div class="compare_1__title">日同比</div>
                <div class="compare_1__number">
                  <span>12%</span>
                  <span>
                    <CaretDownOutlined style="color: green" />
                  </span>
                </div>
              </div>
            </div>
            <div class="col-data-item__line">
              <a-divider style="height: 1px; background-color: #f7f8f9; padding: 0" />
            </div>
            <div class="col-data-item__footer">
              <div>
                <span>支付单数 35单</span>
                <span>转换率 (21.4%)</span>
              </div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col class="gutter-row" :xl="6" :lg="12" :md="12" :sm="24" :xs="24">
        <a-card>
          <div class="col-data-item">
            <div class="col-data-item__title">
              <div>今日曝光新增</div>
              <InfoCircleOutlined />
            </div>
            <div class="col-data-item__number">8,846</div>
            <div class="col-data-item__compare">
              <div id="chartContainer" style="width: 100%; height: 80px"></div>
            </div>
            <div class="col-data-item__line">
              <a-divider style="height: 1px; background-color: #f7f8f9; padding: 0" />
            </div>

          </div>
        </a-card>
      </a-col>
    </a-row>
    <div class="echart-content-container">
      <div class="row1">
        <div class="left-tabs">
          <div class="item" v-for="(item, index) in tabs" @click="handleChangeTabs(index)"
            :class="{ active: index === activeTab }" :key="index">{{ item }}</div>
        </div>
      </div>
      <a-row :gutter="24">
        <a-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
          <div class="left-chart1" v-show="activeTab == 0">
            <div ref="chart1" style="width: 100%; height: 100%;"></div>

          </div>
          <div class="left-chart1" v-show="activeTab == 1">
            <div ref="chart2" style="width: 100%; height: 100%;"></div>

          </div>


        </a-col>
        <a-col :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
          <div class="right-chart1">
            <div class="list-product">
              <div class="item" v-for="(item, index) in storeList" :key="index">
                <div class="left">
                  <div class="number">{{ item.id }}</div>
                  <div class="name">{{ item.name }}</div>
                </div>
                <div class="right">
                  {{ item.number }}
                </div>
              </div>

            </div>

          </div>
        </a-col>


      </a-row>


    </div>
    <!-- <a-row :gutter="[16, 24]">
    
    </a-row> -->

  </page-container>
</template>

<style lang="less" scoped>
.echart-content-container {
  padding: 20px;
  border-radius: 5px;
  margin-top: 20px;
  background-color: #fff;

  .row1 {
    padding: 10px 0;
    border-bottom: 1px solid #eee;

    .left-tabs {
      display: flex;
      align-items: center;

      .item {
        font-size: 14px;
        color: #000;
        cursor: pointer;
        transition: all 0.6s;
      }

      .item:nth-child(n+2) {
        margin-left: 20px;
      }

      .active {
        color: #1890ff;
        position: relative;

        &::after {
          content: "";
          height: 2px;
          width: 100%;
          position: absolute;
          top: 30px;
          left: 0;
          background-color: #1890ff;
          transition: all 0.6s;
          /* 可选:为下划线添加过渡效果 */

        }
      }

    }
  }

  .left-chart1 {
    width: 100%;
    height: 400px; // 固定高度确保图表显示
    min-height: 400px; // 防止内容压缩

    #chart1 {
      width: 100%;
      height: 100%;
    }

    #chart2 {
      width: 100%;
      height: 100%;
    }
  }

  .right-chart1 {
    width: 100%;
    height: 400px; // 与左侧保持一致
    padding-left: 20px; // 替代 margin-left 更安全

    .list-product {
      height: 100%;
      overflow-y: auto; // 明确指定垂直滚动
      padding: 10px;
      background: #fff;
      border-radius: 4px;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

      .item {
        display: flex;
        justify-content: space-between;
        align-items: center; // 垂直居中
        padding: 12px 0;
        border-bottom: 1px solid #f0f0f0;

        .left {
          display: flex;
          align-items: center;

          .number {
            font-weight: bold;
            color: #1890ff;
            min-width: 24px; // 防止数字跳动
          }

          .name {
            margin-left: 12px;
            color: #333;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 200px; // 防止过长文本
          }
        }

        .right {
          font-weight: bold;
          color: #52c41a;
        }
      }

      .item:last-child {
        border-bottom: none; // 移除最后一项的下边框
      }
    }
  }

  // 响应式调整
  @media (max-width: 768px) {
    .left-chart1 {
      margin-top: 20px;
      padding-left: 0;
      height: auto;
      max-height: 300px;
      width: 100%;
    }
  }
}


.col-data-item {
  height: 200px;

  .col-data-item__title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 16px;
    color: #858a99;
  }

  .col-data-item__number {
    font-size: 24px;
    font-weight: 700;
    margin-top: 5px;
  }

  .col-data-item__compare {
    display: flex;
    align-items: center;
    margin-top: 10px;

    .compare_1 {
      display: flex;
      align-items: center;

      .compare_1__title {}

      .compare_1__number {
        margin-left: 10px;
      }
    }

    .compare_2 {
      display: flex;
      align-items: center;
      margin-left: 30px;

      .compare_1__title {}

      .compare_1__number {
        margin-left: 10px;
      }
    }
  }
}

.hiddenText {
  display: inline-block;
  width: 1000px;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

a:hover {
  color: red;
}

.one {
  width: 100%;
  height: 400px;
}
</style>

这里的 chart1 和chart2 是这两个echarts 图

进行tabs 切换的时候 这两个echarts 其实 是一开始是显示好的

目前我是这样处理的 在点击tabs 的时候  显示echarts  当前的echarts 的大小会有问题

目前我没想到怎么处理


网站公告

今日签到

点亮在社区的每一天
去签到