diff --git a/src/components/RingBarChart.vue b/src/components/RingBarChart.vue index b5a30e6..ab09b71 100644 --- a/src/components/RingBarChart.vue +++ b/src/components/RingBarChart.vue @@ -47,7 +47,7 @@ const ringText = (ring) => { :key="index" :style="{ background: barColor(b.rate), - height: b.rate * 100 + '%', + height: b.rate * 120 + 'rpx', }" > @@ -68,7 +68,7 @@ const ringText = (ring) => { display: flex; align-items: flex-end; justify-content: space-around; - height: 120rpx; + min-height: 50rpx; } .container > view:first-child > view { transition: all 0.3s ease; diff --git a/src/pages/point-book.vue b/src/pages/point-book.vue index 06c7f91..36cb478 100644 --- a/src/pages/point-book.vue +++ b/src/pages/point-book.vue @@ -31,6 +31,7 @@ const data = ref({ }); const list = ref([]); +const bowTargetSrc = ref(""); const toListPage = () => { uni.navigateTo({ @@ -38,11 +39,73 @@ const toListPage = () => { }); }; +// 热力图数据 +const heatMapData = ref([ + { x: 150, y: 150, ring: 10, count: 5 }, + { x: 140, y: 160, ring: 9, count: 3 }, + { x: 160, y: 140, ring: 8, count: 2 }, + { x: 130, y: 170, ring: 7, count: 4 }, + { x: 170, y: 130, ring: 6, count: 1 }, + { x: 120, y: 180, ring: 5, count: 2 }, + { x: 180, y: 120, ring: 8, count: 3 }, + { x: 110, y: 190, ring: 4, count: 1 }, + { x: 190, y: 110, ring: 9, count: 2 }, + { x: 145, y: 145, ring: 10, count: 3 }, + { x: 155, y: 155, ring: 9, count: 1 }, + { x: 125, y: 165, ring: 6, count: 2 }, +]); + +// 绘制热力图 +const drawHeatMap = () => { + try { + const ctx = uni.createCanvasContext("heatMapCanvas"); + const canvasWidth = 300; + const canvasHeight = 300; + + // 绘制热力点 + heatMapData.value.forEach((point) => { + const radius = point.count * 8 + 15; + + // 根据频次设置颜色 + let color; + if (point.count >= 4) { + color = "rgba(255, 0, 0, 0.7)"; // 红色 - 高频 + } else if (point.count >= 2) { + color = "rgba(255, 255, 0, 0.6)"; // 黄色 - 中频 + } else { + color = "rgba(0, 255, 0, 0.5)"; // 绿色 - 低频 + } + + // 绘制圆形热力点 + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.arc(point.x, point.y, radius, 0, 2 * Math.PI); + ctx.fill(); + + // 绘制环数标签 + ctx.setFillStyle("#fff"); + ctx.setFontSize(14); + ctx.setTextAlign("center"); + ctx.fillText(point.ring.toString(), point.x, point.y + 5); + }); + + ctx.draw(); + console.log("热力图绘制完成"); + } catch (error) { + console.error("绘制热力图失败:", error); + } +}; + onShow(async () => { const result = await getPointBookListAPI(1); list.value = result; const result2 = await getPointBookStatisticsAPI(); data.value = result2; + + // 延迟绘制热力图确保Canvas准备就绪 + setTimeout(() => { + drawHeatMap(); + }, 500); }); const onSignin = () => { @@ -70,6 +133,9 @@ onMounted(async () => { } const config = await getPointBookConfigAPI(); uni.setStorageSync("point-book-config", config); + if (config.targetOption && config.targetOption[0]) { + bowTargetSrc.value = config.targetOption[0].icon; + } }); onBeforeUnmount(() => { @@ -195,6 +261,13 @@ onShareTimeline(() => { + + + + @@ -233,7 +306,7 @@ onShareTimeline(() => { display: flex; flex-wrap: wrap; padding: 25rpx; - margin-bottom: 25rpx; + margin-bottom: 10rpx; } .statistics > view { width: 33.33%; @@ -309,9 +382,26 @@ onShareTimeline(() => { width: 100%; display: flex; justify-content: center; - margin-bottom: 20rpx; + margin: 25rpx 0; } .title > image { width: 566rpx; } +.heat-map { + position: relative; + margin: 10rpx; + width: calc(100vw - 70rpx); + height: calc(100vw - 70rpx); +} +.heat-map > image { + width: 100%; +} +.heat-map > canvas { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 2; +}