fix: 修复统计图表不显示与对比上月Infinity问题
- ChartWrapper: 添加 type 属性修复 uCharts 不渲染 - ChartWrapper: 使用 pixelRatio=1 避免双重缩放导致字体线条过大 - ChartWrapper: 统一 fontSize/fontColor/padding 配置 - ChartWrapper: 挂载时保存实例引用避免异步回调中 getCurrentInstance 返回 undefined - stats: Number() 强制类型转换避免字符串导致 Infinity - stats: !prev 宽松判断覆盖 null/undefined/0 除零情况 - stores: fetchOverview/fetchCategoryStats/fetchTrend 确保数据字段为数字
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<view class="chart-wrap">
|
||||
<canvas
|
||||
type="2d"
|
||||
:canvas-id="canvasId"
|
||||
:id="canvasId"
|
||||
class="chart-canvas"
|
||||
@@ -25,6 +26,8 @@ const props = withDefaults(defineProps<{
|
||||
|
||||
const emit = defineEmits(['tap'])
|
||||
|
||||
// 挂载时保存实例引用,避免异步回调中 getCurrentInstance 返回 undefined
|
||||
const instance = getCurrentInstance()
|
||||
let chartInstance: any = null
|
||||
|
||||
function drawChart() {
|
||||
@@ -39,6 +42,43 @@ function drawChart() {
|
||||
// #endif
|
||||
}
|
||||
|
||||
function buildConfig(ctx: any, canvas2d: boolean, cssWidth: number, cssHeight: number) {
|
||||
// canvas 已通过 ctx.scale(dpr) 处理缩放,uCharts 用 pixelRatio=1 避免双重缩放
|
||||
const base: any = {
|
||||
type: props.type,
|
||||
context: ctx,
|
||||
canvas2d,
|
||||
pixelRatio: 1,
|
||||
width: cssWidth,
|
||||
height: cssHeight,
|
||||
animation: true,
|
||||
background: '#FFFFFF',
|
||||
padding: [20, 20, 20, 20],
|
||||
fontSize: 10,
|
||||
fontColor: '#8B7E7E',
|
||||
title: { show: false },
|
||||
subtitle: { show: false },
|
||||
legend: { show: false },
|
||||
dataLabel: false,
|
||||
enableScroll: false,
|
||||
...props.chartData
|
||||
}
|
||||
|
||||
// 饼图开启数据标签
|
||||
if (props.type === 'pie') {
|
||||
base.dataLabel = true
|
||||
base.padding = [30, 30, 30, 30]
|
||||
}
|
||||
|
||||
// 折线图/柱状图坐标轴字体
|
||||
if (props.type === 'line' || props.type === 'column') {
|
||||
base.xAxis = { fontSize: 10, ...base.xAxis }
|
||||
base.yAxis = { fontSize: 10, ...base.yAxis }
|
||||
}
|
||||
|
||||
return base
|
||||
}
|
||||
|
||||
function drawChartH5() {
|
||||
try {
|
||||
const canvas = document.querySelector(`#${props.canvasId}`) as HTMLCanvasElement
|
||||
@@ -53,19 +93,7 @@ function drawChartH5() {
|
||||
canvas.height = rect.height * dpr
|
||||
ctx.scale(dpr, dpr)
|
||||
|
||||
const config: any = {
|
||||
context: ctx,
|
||||
canvas2d: true,
|
||||
pixelRatio: dpr,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
animation: true,
|
||||
background: '#FFFFFF',
|
||||
padding: [15, 15, 15, 15],
|
||||
...props.chartData
|
||||
}
|
||||
|
||||
chartInstance = new uCharts(config)
|
||||
chartInstance = new uCharts(buildConfig(ctx, true, rect.width, rect.height))
|
||||
} catch (e) {
|
||||
console.error('[Chart] H5 draw error:', e)
|
||||
}
|
||||
@@ -73,11 +101,18 @@ function drawChartH5() {
|
||||
|
||||
function drawChartMP() {
|
||||
try {
|
||||
const query = uni.createSelectorQuery().in(getCurrentInstance()?.proxy)
|
||||
if (!instance?.proxy) return
|
||||
|
||||
const query = uni.createSelectorQuery().in(instance.proxy)
|
||||
query.select(`#${props.canvasId}`)
|
||||
// @ts-ignore
|
||||
.fields({ node: true, size: true })
|
||||
.exec((res) => {
|
||||
if (!res || !res[0]) return
|
||||
.exec((res: any) => {
|
||||
if (!res || !res[0] || !res[0].node) {
|
||||
console.warn('[Chart] Canvas node not found, fallback to old API')
|
||||
drawChartMPLegacy()
|
||||
return
|
||||
}
|
||||
|
||||
const canvas = res[0].node
|
||||
const ctx = canvas.getContext('2d')
|
||||
@@ -87,22 +122,29 @@ function drawChartMP() {
|
||||
canvas.height = res[0].height * dpr
|
||||
ctx.scale(dpr, dpr)
|
||||
|
||||
const config: any = {
|
||||
context: ctx,
|
||||
canvas2d: true,
|
||||
pixelRatio: dpr,
|
||||
width: res[0].width,
|
||||
height: res[0].height,
|
||||
animation: true,
|
||||
background: '#FFFFFF',
|
||||
padding: [15, 15, 15, 15],
|
||||
...props.chartData
|
||||
}
|
||||
|
||||
chartInstance = new uCharts(config)
|
||||
chartInstance = new uCharts(buildConfig(ctx, true, res[0].width, res[0].height))
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('[Chart] MP draw error:', e)
|
||||
drawChartMPLegacy()
|
||||
}
|
||||
}
|
||||
|
||||
// 兼容旧版小程序 canvas API
|
||||
function drawChartMPLegacy() {
|
||||
try {
|
||||
const ctx = uni.createCanvasContext(props.canvasId, instance?.proxy)
|
||||
if (!ctx) return
|
||||
|
||||
const query = uni.createSelectorQuery().in(instance?.proxy)
|
||||
query.select(`#${props.canvasId}`)
|
||||
.boundingClientRect((rect: any) => {
|
||||
if (!rect) return
|
||||
chartInstance = new uCharts(buildConfig(ctx, false, rect.width, rect.height))
|
||||
})
|
||||
.exec()
|
||||
} catch (e) {
|
||||
console.error('[Chart] MP legacy draw error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user