Commit 06e56074 authored by 水玉婷's avatar 水玉婷
Browse files

feat:修复图表从无数据切换回有数据的时候图表不渲染

parent 5a041e1a
......@@ -6,7 +6,7 @@
<div class="empty-text">暂无数据</div>
<div class="empty-desc">当前查询条件下没有找到相关数据</div>
</div>
<div v-else ref="chartContainer" class="chart-container"></div>
<div v-else :key="chartDataKey" ref="chartContainer" class="chart-container"></div>
<div v-if="error" class="chart-error">{{ error }}</div>
</div>
</template>
......@@ -35,6 +35,8 @@ const chartContainer = ref<HTMLElement>();
const chartInstance = shallowRef<echarts.ECharts | null>(null);
const error = ref<string>('');
const isEmpty = ref<boolean>(false);
// 用于强制重新渲染图表容器的key
const chartDataKey = ref<number>(0);
// ========== 工具函数抽离 ==========
......@@ -670,11 +672,15 @@ const initChartResizeListener = (chartConfig: any, chartTypeForLogic: string) =>
/**
* 创建ECharts图表
*/
const createChart = () => {
if (!chartContainer.value) return;
const createChart = async () => {
// 检查数据是否为空
isEmpty.value = checkDataEmpty(props.chartData);
const newIsEmpty = checkDataEmpty(props.chartData);
// 只有当isEmpty状态真正发生变化时才更新,避免不必要的重新渲染
if (isEmpty.value !== newIsEmpty) {
isEmpty.value = newIsEmpty;
}
if (isEmpty.value) {
// 清理之前的图表实例
if (chartInstance.value) {
......@@ -685,39 +691,56 @@ const createChart = () => {
return;
}
// 等待DOM更新完成,确保chartContainer存在
await nextTick();
if (!chartContainer.value) {
console.warn('图表容器未找到,无法渲染图表');
return;
}
// 清理之前的图表实例,确保每次数据变化时创建全新实例
if (chartInstance.value) {
chartInstance.value.dispose();
chartInstance.value = null;
}
const chartConfig = formatData(props.chartData);
try {
const chartConfig = formatData(props.chartData);
// 根据数据特征自动选择图表类型
const chartTypeForLogic = chartConfig.isMultiY && chartConfig.yFields && chartConfig.yFields.length > 1
? 'dualColumn'
: 'column';
// 根据数据特征自动选择图表类型
const chartTypeForLogic = chartConfig.isMultiY && chartConfig.yFields && chartConfig.yFields.length > 1
? 'dualColumn'
: 'column';
// 创建ECharts实例
chartInstance.value = echarts.init(chartContainer.value);
// 创建ECharts实例
chartInstance.value = echarts.init(chartContainer.value);
// 生成图表配置
const option = chartTypeForLogic === 'column'
? createSingleColumnOption(chartConfig)
: createDualColumnOption(chartConfig);
// 生成图表配置
const option = chartTypeForLogic === 'column'
? createSingleColumnOption(chartConfig)
: createDualColumnOption(chartConfig);
// 设置图表选项
chartInstance.value.setOption(option);
error.value = '';
// 设置图表选项
chartInstance.value.setOption(option);
error.value = '';
// 初始化响应式监听
initChartResizeListener(chartConfig, chartTypeForLogic);
// 初始化响应式监听
initChartResizeListener(chartConfig, chartTypeForLogic);
} catch (err) {
console.error('图表创建失败:', err);
error.value = '图表渲染失败,请重试';
}
};
// ========== 生命周期和响应式 ==========
// 监听数据变化
watch(() => props.chartData, createChart);
watch(() => props.chartData, async () => {
// 更新key来强制重新渲染图表容器
chartDataKey.value++;
await createChart();
});
onMounted(() => {
nextTick(createChart);
......
......@@ -6,7 +6,7 @@
<div class="empty-text">暂无数据</div>
<div class="empty-desc">当前查询条件下没有找到相关数据</div>
</div>
<div v-else ref="chartContainer" class="chart-container"></div>
<div v-else :key="chartDataKey" ref="chartContainer" class="chart-container"></div>
<div v-if="error" class="chart-error">{{ error }}</div>
</div>
</template>
......@@ -35,6 +35,8 @@ const chartContainer = ref<HTMLElement>();
const chartInstance = shallowRef<echarts.ECharts | null>(null);
const error = ref<string>('');
const isEmpty = ref<boolean>(false);
// 用于强制重新渲染图表容器的key
const chartDataKey = ref<number>(0);
// ========== 工具函数抽离 ==========
......@@ -671,11 +673,15 @@ const initChartResizeListener = (chartConfig: any, chartTypeForLogic: string) =>
/**
* 创建ECharts图表
*/
const createChart = () => {
if (!chartContainer.value) return;
const createChart = async () => {
// 检查数据是否为空
isEmpty.value = checkDataEmpty(props.chartData);
const newIsEmpty = checkDataEmpty(props.chartData);
// 只有当isEmpty状态真正发生变化时才更新,避免不必要的重新渲染
if (isEmpty.value !== newIsEmpty) {
isEmpty.value = newIsEmpty;
}
if (isEmpty.value) {
// 清理之前的图表实例
if (chartInstance.value) {
......@@ -686,39 +692,56 @@ const createChart = () => {
return;
}
// 等待DOM更新完成,确保chartContainer存在
await nextTick();
if (!chartContainer.value) {
console.warn('图表容器未找到,无法渲染图表');
return;
}
// 清理之前的图表实例
if (chartInstance.value) {
chartInstance.value.dispose();
chartInstance.value = null;
}
const chartConfig = formatData(props.chartData);
try {
const chartConfig = formatData(props.chartData);
// 根据数据特征自动选择图表类型
const chartTypeForLogic = chartConfig.isMultiY && chartConfig.yFields && chartConfig.yFields.length > 1
? 'dualLine'
: 'line';
// 根据数据特征自动选择图表类型
const chartTypeForLogic = chartConfig.isMultiY && chartConfig.yFields && chartConfig.yFields.length > 1
? 'dualLine'
: 'line';
// 创建ECharts实例
chartInstance.value = echarts.init(chartContainer.value);
// 创建ECharts实例
chartInstance.value = echarts.init(chartContainer.value);
// 生成图表配置
const option = chartTypeForLogic === 'line'
? createSingleLineOption(chartConfig)
: createDualLineOption(chartConfig);
// 生成图表配置
const option = chartTypeForLogic === 'line'
? createSingleLineOption(chartConfig)
: createDualLineOption(chartConfig);
// 设置图表选项
chartInstance.value.setOption(option);
error.value = '';
// 设置图表选项
chartInstance.value.setOption(option);
error.value = '';
// 初始化响应式监听
initChartResizeListener(chartConfig, chartTypeForLogic);
// 初始化响应式监听
initChartResizeListener(chartConfig, chartTypeForLogic);
} catch (err) {
console.error('图表创建失败:', err);
error.value = '图表渲染失败,请重试';
}
};
// ========== 生命周期和响应式 ==========
// 监听数据变化
watch(() => props.chartData, createChart);
watch(() => props.chartData, async () => {
// 更新key来强制重新渲染图表容器
chartDataKey.value++;
await createChart();
});
onMounted(() => {
nextTick(createChart);
......
......@@ -6,7 +6,7 @@
<div class="empty-text">暂无数据</div>
<div class="empty-desc">当前查询条件下没有找到相关数据</div>
</div>
<div v-else ref="chartContainer" class="chart-container"></div>
<div v-else :key="chartDataKey" ref="chartContainer" class="chart-container"></div>
<div v-if="error" class="chart-error">{{ error }}</div>
</div>
</template>
......@@ -35,6 +35,8 @@ const chartContainer = ref<HTMLElement>();
const chartInstance = shallowRef<echarts.ECharts | null>(null);
const error = ref<string>('');
const isEmpty = ref<boolean>(false);
// 用于强制重新渲染图表容器的key
const chartDataKey = ref<number>(0);
// ========== 工具函数抽离 ==========
......@@ -344,11 +346,15 @@ const getResponsiveLayout = (isManyItems: boolean) => {
/**
* 创建ECharts图表
*/
const createChart = () => {
if (!chartContainer.value) return;
const createChart = async () => {
// 检查数据是否为空
isEmpty.value = checkDataEmpty(props.chartData);
const newIsEmpty = checkDataEmpty(props.chartData);
// 只有当isEmpty状态真正发生变化时才更新,避免不必要的重新渲染
if (isEmpty.value !== newIsEmpty) {
isEmpty.value = newIsEmpty;
}
if (isEmpty.value) {
// 清理之前的图表实例
if (chartInstance.value) {
......@@ -359,32 +365,49 @@ const createChart = () => {
return;
}
// 清理之前的图表实例
// 等待DOM更新完成,确保chartContainer存在
await nextTick();
if (!chartContainer.value) {
console.warn('图表容器未找到,无法渲染图表');
return;
}
// 清理之前的图表实例,确保每次数据变化时创建全新实例
if (chartInstance.value) {
chartInstance.value.dispose();
chartInstance.value = null;
}
const chartConfig = formatData(props.chartData);
try {
const chartConfig = formatData(props.chartData);
// 创建ECharts实例
chartInstance.value = echarts.init(chartContainer.value);
// 创建ECharts实例
chartInstance.value = echarts.init(chartContainer.value);
// 生成图表配置
const option = createPieOption(chartConfig);
// 生成图表配置
const option = createPieOption(chartConfig);
// 设置图表选项
chartInstance.value.setOption(option);
error.value = '';
// 设置图表选项
chartInstance.value.setOption(option);
error.value = '';
// 初始化响应式监听
initChartResizeListener();
// 初始化响应式监听
initChartResizeListener();
} catch (err) {
console.error('图表创建失败:', err);
error.value = '图表渲染失败,请重试';
}
};
// ========== 生命周期和响应式 ==========
// 监听数据变化
watch(() => props.chartData, createChart);
watch(() => props.chartData, async () => {
// 更新key来强制重新渲染图表容器
chartDataKey.value++;
await createChart();
});
onMounted(() => {
nextTick(createChart);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment