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

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

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