Files
xiaocai/client/src/components/ChartWrapper/ChartWrapper.vue
wangxiaogang d5e5655b88 feat: 交互优化与代码质量改进
- SvgIcon 改为 PNG 图标方案,组件重命名为 Icon
- 修复 TransactionItem tap 事件名冲突,改为 item-tap
- 修复 Stats 页面切换 tab 时 overview 不更新
- 修复 CategoryIcon bgColor 必填问题
- 修复 ChartWrapper import 顺序
- 修复 budget onDelete 空字符串问题
- 清理 profile 页面未使用 CSS
- 统一所有页面 header 为 sticky 定位
- 修复导航栏返回按钮不统一
- 添加导出功能 loading 状态
- 优化 scroll-into-view 延迟
2026-06-02 16:04:17 +08:00

92 lines
1.8 KiB
Vue

<template>
<view class="chart-wrap">
<canvas
:canvas-id="canvasId"
:id="canvasId"
class="chart-canvas"
:style="{ width: width + 'rpx', height: height + 'rpx' }"
@tap="onTap"
></canvas>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, nextTick, getCurrentInstance } from 'vue'
// @ts-ignore
import uCharts from '@qiun/ucharts/u-charts.min.js'
const props = defineProps<{
canvasId: string
type: 'pie' | 'line' | 'column'
chartData: any
width?: number
height?: number
}>()
const emit = defineEmits(['tap'])
let chartInstance: any = null
function drawChart() {
if (!props.chartData) return
const query = uni.createSelectorQuery().in(getCurrentInstance()?.proxy)
query.select(`#${props.canvasId}`)
.fields({ node: true, size: true })
.exec((res) => {
if (!res[0]) return
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = uni.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
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)
})
}
function onTap(e: any) {
chartInstance?.touchLegend(e)
emit('tap', e)
}
onMounted(() => {
nextTick(() => {
setTimeout(drawChart, 100)
})
})
watch(() => props.chartData, () => {
nextTick(() => {
setTimeout(drawChart, 100)
})
}, { deep: true })
</script>
<style lang="scss" scoped>
.chart-wrap {
width: 100%;
display: flex;
justify-content: center;
}
.chart-canvas {
display: block;
}
</style>