antvis/G2

[Bug]: G2 V5使用折线图, 在鼠标放置上去移动一会儿后页面会卡死. #6649

zhangtao101 posted onGitHub

Describe the bug / 问题描述

版本

vue版本: 3.5.13 g2版本: 5.2.11

复现代码

<script lang="ts" setup>
import { onMounted, ref } from 'vue';

import { Page } from '@vben/common-ui';

// eslint-disable-next-line n/no-extraneous-import
import { Chart } from '@antv/g2';
import { Card, Col, RadioGroup, Row } from 'ant-design-vue';

// region 类型选择
// 当前选中查看的类型
const type = ref('1');
// 类型列表
const typeOptions = [
  {
    label: '用能概览',
    value: '1',
  },
  {
    label: '统计分析',
    value: '2',
  },
];

// endregion

// region 分项用能分析

// 分项用能分析图表数据
const itemizedEnergyUseData = ref<any>([
  { name: '电能', month: '1.', data: 18.9 },
  { name: '电能', month: '2.', data: 28.8 },
  { name: '电能', month: '3.', data: 39.3 },
  { name: '电能', month: '4.', data: 81.4 },
  { name: '电能', month: '5', data: 47 },
  { name: '电能', month: '6.', data: 20.3 },
  { name: '电能', month: '7.', data: 24 },
  { name: '电能', month: '8.', data: 35.6 },
  { name: '煤气', month: '1.', data: 12.4 },
  { name: '煤气', month: '2.', data: 23.2 },
  { name: '煤气', month: '3.', data: 34.5 },
  { name: '煤气', month: '4.', data: 99.7 },
  { name: '煤气', month: '5', data: 52.6 },
  { name: '煤气', month: '6.', data: 35.5 },
  { name: '煤气', month: '7.', data: 37.4 },
  { name: '煤气', month: '8.', data: 42.4 },
]);
// 分项用能分析图表
const itemizedEnergyAnalysisChart = ref<any>(null);

/**
 * 分项用能分析图表创建
 * @returns viod
 */
function itemizedEnergyAnalysisChartCreation() {
  console.log('itemizedEnergyAnalysisChart');
  if (!itemizedEnergyAnalysisChart.value) {
    itemizedEnergyAnalysisChart.value = new Chart({
      container: 'energyContrast',
      autoFit: true,
    });

    itemizedEnergyAnalysisChart.value
      .interval()
      .coordinate({ transform: [{ type: 'transpose' }] })
      .data(itemizedEnergyUseData.value)
      .encode('x', 'month')
      .encode('y', 'data')
      .encode('color', 'name')
      .transform({ type: 'dodgeX' })
      .interaction('elementHighlight', { background: true });

    itemizedEnergyAnalysisChart.value.render();
  }
}
// endregion

// region 同比分析
// endregion
// region 分析用能占比
// endregion
// region 分项用能趋势
// endregion

onMounted(() => {
  itemizedEnergyAnalysisChartCreation();
});
</script>

<template>
  <Page>
    <RadioGroup
      v-model:value="type"
      option-type="button"
      :options="typeOptions"
    />

    <Row :gutter="20" class="mb-4 mt-4">
      <Col :span="12">
        <Card>
          <div id="energyContrast"></div>
        </Card>
      </Col>
      <Col :span="12">
        <Card>
          <div id="yearOnYearAnalysis"></div>
        </Card>
      </Col>
    </Row>

    <Row :gutter="20">
      <Col :span="12">
        <Card>
          <div id="energyUseRatio"></div>
        </Card>
      </Col>
      <Col :span="12">
        <Card>
          <div id="energyUseTrend"></div>
        </Card>
      </Col>
    </Row>
  </Page>
</template>

<style scoped></style>

复现视频

https://github.com/user-attachments/assets/d752854e-84fe-414d-9624-f6c9652e15e4

No response

Steps to Reproduce the Bug or Issue / 重现步骤

No response

Version / 版本

🆕 5.x

OS / 操作系统

  • macOS
  • Windows
  • Linux
  • Others / 其他

Browser / 浏览器

  • Chrome
  • Edge
  • Firefox
  • Safari (Limited support / 有限支持)
  • IE (Nonsupport / 不支持)
  • Others / 其他

问题出现在对 vue 响应式的处理上,感觉 g2 的 chart 最好不要用 ref 包裹,你可以这样试一试

<script setup lang="ts">
import { onMounted, ref, onBeforeUnmount, shallowRef } from "vue";

// eslint-disable-next-line n/no-extraneous-import
import { Chart } from "@antv/g2";
import { Card, Col, RadioGroup, Row } from "ant-design-vue";

const type = ref("1");
const typeOptions = [
  {
    label: "用能概览",
    value: "1",
  },
  {
    label: "统计分析",
    value: "2",
  },
];

const itemizedEnergyUseData = shallowRef([
  { name: "电能", month: "1.", data: 18.9 },
  { name: "电能", month: "2.", data: 28.8 },
  { name: "电能", month: "3.", data: 39.3 },
  { name: "电能", month: "4.", data: 81.4 },
  { name: "电能", month: "5", data: 47 },
  { name: "电能", month: "6.", data: 20.3 },
  { name: "电能", month: "7.", data: 24 },
  { name: "电能", month: "8.", data: 35.6 },
  { name: "煤气", month: "1.", data: 12.4 },
  { name: "煤气", month: "2.", data: 23.2 },
  { name: "煤气", month: "3.", data: 34.5 },
  { name: "煤气", month: "4.", data: 99.7 },
  { name: "煤气", month: "5", data: 52.6 },
  { name: "煤气", month: "6.", data: 35.5 },
  { name: "煤气", month: "7.", data: 37.4 },
  { name: "煤气", month: "8.", data: 42.4 },
]);

let itemizedEnergyAnalysisChart: Chart | null = null;

function itemizedEnergyAnalysisChartCreation() {
  console.log("itemizedEnergyAnalysisChart");
  if (!itemizedEnergyAnalysisChart) {
    itemizedEnergyAnalysisChart = new Chart({
      container: "energyContrast",
      autoFit: true,
    });

    itemizedEnergyAnalysisChart
      .interval()
      .coordinate({ transform: [{ type: "transpose" }] })
      .data(itemizedEnergyUseData.value)
      .encode("x", "month")
      .encode("y", "data")
      .encode("color", "name")
      .transform({ type: "dodgeX" })
      .interaction("elementHighlight", { background: true });

    itemizedEnergyAnalysisChart.render();
  }
}

function destroyChart() {
  if (itemizedEnergyAnalysisChart) {
    itemizedEnergyAnalysisChart.destroy();
    itemizedEnergyAnalysisChart = null;
  }
}

onMounted(() => {
  itemizedEnergyAnalysisChartCreation();
});

onBeforeUnmount(() => {
  destroyChart();
});
</script>

<template>
  <RadioGroup
    v-model:value="type"
    option-type="button"
    :options="typeOptions"
  />

  <Row :gutter="20" class="mb-4 mt-4">
    <Col :span="12">
      <Card>
        <div id="energyContrast"></div>
      </Card>
    </Col>
    <Col :span="12">
      <Card>
        <div id="yearOnYearAnalysis"></div>
      </Card>
    </Col>
  </Row>

  <Row :gutter="20">
    <Col :span="12">
      <Card>
        <div id="energyUseRatio"></div>
      </Card>
    </Col>
    <Col :span="12">
      <Card>
        <div id="energyUseTrend"></div>
      </Card>
    </Col>
  </Row>
</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
posted by BQXBQX about 1 month ago

问题出现在对 vue 响应式的处理上,感觉 g2 的 chart 最好不要用 ref 包裹,你可以这样试一试

<script setup lang="ts"> import { onMounted, ref, onBeforeUnmount, shallowRef } from "vue"; // eslint-disable-next-line n/no-extraneous-import import { Chart } from "@antv/g2"; import { Card, Col, RadioGroup, Row } from "ant-design-vue"; const type = ref("1"); const typeOptions = [ { label: "用能概览", value: "1", }, { label: "统计分析", value: "2", }, ]; const itemizedEnergyUseData = shallowRef([ { name: "电能", month: "1.", data: 18.9 }, { name: "电能", month: "2.", data: 28.8 }, { name: "电能", month: "3.", data: 39.3 }, { name: "电能", month: "4.", data: 81.4 }, { name: "电能", month: "5", data: 47 }, { name: "电能", month: "6.", data: 20.3 }, { name: "电能", month: "7.", data: 24 }, { name: "电能", month: "8.", data: 35.6 }, { name: "煤气", month: "1.", data: 12.4 }, { name: "煤气", month: "2.", data: 23.2 }, { name: "煤气", month: "3.", data: 34.5 }, { name: "煤气", month: "4.", data: 99.7 }, { name: "煤气", month: "5", data: 52.6 }, { name: "煤气", month: "6.", data: 35.5 }, { name: "煤气", month: "7.", data: 37.4 }, { name: "煤气", month: "8.", data: 42.4 }, ]); let itemizedEnergyAnalysisChart: Chart | null = null; function itemizedEnergyAnalysisChartCreation() { console.log("itemizedEnergyAnalysisChart"); if (!itemizedEnergyAnalysisChart) { itemizedEnergyAnalysisChart = new Chart({ container: "energyContrast", autoFit: true, }); itemizedEnergyAnalysisChart .interval() .coordinate({ transform: [{ type: "transpose" }] }) .data(itemizedEnergyUseData.value) .encode("x", "month") .encode("y", "data") .encode("color", "name") .transform({ type: "dodgeX" }) .interaction("elementHighlight", { background: true }); itemizedEnergyAnalysisChart.render(); } } function destroyChart() { if (itemizedEnergyAnalysisChart) { itemizedEnergyAnalysisChart.destroy(); itemizedEnergyAnalysisChart = null; } } onMounted(() => { itemizedEnergyAnalysisChartCreation(); }); onBeforeUnmount(() => { destroyChart(); }); </script>

<template> <RadioGroup v-model:value="type" option-type="button" :options="typeOptions" />

<Row :gutter="20" class="mb-4 mt-4"> <Col :span="12"> <Card> <div id="energyContrast"></div> </Card> </Col> <Col :span="12"> <Card> <div id="yearOnYearAnalysis"></div> </Card> </Col> </Row>

<Row :gutter="20"> <Col :span="12"> <Card> <div id="energyUseRatio"></div> </Card> </Col> <Col :span="12"> <Card> <div id="energyUseTrend"></div> </Card> </Col> </Row> </template>

<style scoped> .logo { height: 6em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.vue:hover { filter: drop-shadow(0 0 2em #42b883aa); } </style>

谢谢大佬

posted by zhangtao101 about 1 month ago

感觉可以帮忙出一个 g2-vue 的包,规避这些问题。

posted by hustcc about 1 month ago

Fund this Issue

$0.00
Funded

Pull requests