|
@@ -1,4 +1,4 @@
|
|
|
-<template>
|
|
|
|
|
|
|
+<template>
|
|
|
<view class="scr-page">
|
|
<view class="scr-page">
|
|
|
<!-- Loading -->
|
|
<!-- Loading -->
|
|
|
<view class="scr-loading" v-if="loading">
|
|
<view class="scr-loading" v-if="loading">
|
|
@@ -21,22 +21,6 @@
|
|
|
<text class="scr-hero-date" v-if="result.createdAt">自检时间:{{ formatDate(result.createdAt) }}</text>
|
|
<text class="scr-hero-date" v-if="result.createdAt">自检时间:{{ formatDate(result.createdAt) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 雷达图 -->
|
|
|
|
|
- <view class="scr-card">
|
|
|
|
|
- <view class="scr-card-title">
|
|
|
|
|
- <text class="scr-card-title-text">五维能量雷达</text>
|
|
|
|
|
- <text class="scr-card-sub">身·智·富·行·心</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="scr-canvas-wrap">
|
|
|
|
|
- <canvas
|
|
|
|
|
- type="2d"
|
|
|
|
|
- id="selfCheckRadar"
|
|
|
|
|
- class="scr-canvas"
|
|
|
|
|
- @ready="onCanvasReady"
|
|
|
|
|
- ></canvas>
|
|
|
|
|
- </view>
|
|
|
|
|
- </view>
|
|
|
|
|
-
|
|
|
|
|
<!-- 维度得分 -->
|
|
<!-- 维度得分 -->
|
|
|
<view class="scr-card">
|
|
<view class="scr-card">
|
|
|
<view class="scr-card-title">
|
|
<view class="scr-card-title">
|
|
@@ -130,13 +114,6 @@ export default {
|
|
|
loading: true,
|
|
loading: true,
|
|
|
result: null,
|
|
result: null,
|
|
|
selfCheckId: '',
|
|
selfCheckId: '',
|
|
|
- canvasContext: null,
|
|
|
|
|
- canvasWidth: 340,
|
|
|
|
|
- canvasHeight: 340,
|
|
|
|
|
- // 雷达图轴序(对应 tianpan 木火土金水,顺时针)
|
|
|
|
|
- axes: ['木', '火', '土', '金', '水'],
|
|
|
|
|
- elementKeys: ['action', 'mind', 'body', 'wisdom', 'wealth'],
|
|
|
|
|
- elementColors: ['#10B981', '#FF6B9D', '#FF8C42', '#6366F1', '#F59E0B'],
|
|
|
|
|
levelMap: {
|
|
levelMap: {
|
|
|
healthy: '健康',
|
|
healthy: '健康',
|
|
|
attention: '留意',
|
|
attention: '留意',
|
|
@@ -176,14 +153,12 @@ export default {
|
|
|
if (cached && cached.id) {
|
|
if (cached && cached.id) {
|
|
|
this.result = cached
|
|
this.result = cached
|
|
|
this.loading = false
|
|
this.loading = false
|
|
|
- this.drawRadar()
|
|
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
getSelfCheckLatest().then(function(res) {
|
|
getSelfCheckLatest().then(function(res) {
|
|
|
self.loading = false
|
|
self.loading = false
|
|
|
if (res.code === 200 && res.data) {
|
|
if (res.code === 200 && res.data) {
|
|
|
self.result = res.data
|
|
self.result = res.data
|
|
|
- self.drawRadar()
|
|
|
|
|
} else {
|
|
} else {
|
|
|
uni.showToast({ title: (res && res.message) || '暂无自检记录', icon: 'none' })
|
|
uni.showToast({ title: (res && res.message) || '暂无自检记录', icon: 'none' })
|
|
|
}
|
|
}
|
|
@@ -192,126 +167,6 @@ export default {
|
|
|
uni.showToast({ title: '加载失败', icon: 'none' })
|
|
uni.showToast({ title: '加载失败', icon: 'none' })
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
- onCanvasReady: function(res) {
|
|
|
|
|
- if (!res || !res[0] || !res[0].node) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- var ctx = res[0].node.getContext('2d')
|
|
|
|
|
- var dpr = uni.getWindowInfo().pixelRatio
|
|
|
|
|
- this.canvasContext = ctx
|
|
|
|
|
- this.canvasContext.scale(dpr, dpr)
|
|
|
|
|
- this.drawRadar()
|
|
|
|
|
- },
|
|
|
|
|
- drawRadar: function() {
|
|
|
|
|
- if (!this.canvasContext || !this.result) {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- var ctx = this.canvasContext
|
|
|
|
|
- var w = this.canvasWidth
|
|
|
|
|
- var h = this.canvasHeight
|
|
|
|
|
- var cx = w / 2
|
|
|
|
|
- var cy = h / 2
|
|
|
|
|
- var r = w * 0.34
|
|
|
|
|
- var angleStep = (Math.PI * 2) / 5
|
|
|
|
|
-
|
|
|
|
|
- // 清空画布
|
|
|
|
|
- ctx.clearRect(0, 0, w, h)
|
|
|
|
|
- ctx.fillStyle = '#FFF8F0'
|
|
|
|
|
- ctx.fillRect(0, 0, w, h)
|
|
|
|
|
-
|
|
|
|
|
- // 维度分数映射
|
|
|
|
|
- var scores = {}
|
|
|
|
|
- var dims = this.result.dimensions || []
|
|
|
|
|
- for (var i = 0; i < dims.length; i++) {
|
|
|
|
|
- scores[dims[i].dimension] = dims[i].score || 0
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 背景五边形(三层网格)
|
|
|
|
|
- for (var layer = 1; layer <= 3; layer++) {
|
|
|
|
|
- ctx.beginPath()
|
|
|
|
|
- for (var g = 0; g < 5; g++) {
|
|
|
|
|
- var gAngle = g * angleStep - Math.PI / 2
|
|
|
|
|
- var gx = cx + r * (layer / 3) * Math.cos(gAngle)
|
|
|
|
|
- var gy = cy + r * (layer / 3) * Math.sin(gAngle)
|
|
|
|
|
- if (g === 0) {
|
|
|
|
|
- ctx.moveTo(gx, gy)
|
|
|
|
|
- } else {
|
|
|
|
|
- ctx.lineTo(gx, gy)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ctx.closePath()
|
|
|
|
|
- ctx.strokeStyle = 'rgba(249, 114, 22, 0.15)'
|
|
|
|
|
- ctx.lineWidth = 1
|
|
|
|
|
- ctx.stroke()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 轴线 + 标签
|
|
|
|
|
- for (var j = 0; j < 5; j++) {
|
|
|
|
|
- var a2 = j * angleStep - Math.PI / 2
|
|
|
|
|
- var lx = cx + r * Math.cos(a2)
|
|
|
|
|
- var ly = cy + r * Math.sin(a2)
|
|
|
|
|
- ctx.beginPath()
|
|
|
|
|
- ctx.moveTo(cx, cy)
|
|
|
|
|
- ctx.lineTo(lx, ly)
|
|
|
|
|
- ctx.strokeStyle = this.elementColors[j] + '44'
|
|
|
|
|
- ctx.lineWidth = 1
|
|
|
|
|
- ctx.stroke()
|
|
|
|
|
-
|
|
|
|
|
- var labelX = cx + (r + 18) * Math.cos(a2)
|
|
|
|
|
- var labelY = cy + (r + 18) * Math.sin(a2)
|
|
|
|
|
- ctx.fillStyle = this.elementColors[j]
|
|
|
|
|
- ctx.font = 'bold 13px sans-serif'
|
|
|
|
|
- ctx.textAlign = 'center'
|
|
|
|
|
- ctx.textBaseline = 'middle'
|
|
|
|
|
- ctx.fillText(this.axes[j], labelX, labelY)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 数据驱动多边形
|
|
|
|
|
- ctx.beginPath()
|
|
|
|
|
- for (var m = 0; m < 5; m++) {
|
|
|
|
|
- var ang = m * angleStep - Math.PI / 2
|
|
|
|
|
- var key = this.elementKeys[m]
|
|
|
|
|
- var ratio = (scores[key] || 0) / 9
|
|
|
|
|
- var dataR = r * ratio
|
|
|
|
|
- var dx = cx + dataR * Math.cos(ang)
|
|
|
|
|
- var dy = cy + dataR * Math.sin(ang)
|
|
|
|
|
- if (m === 0) {
|
|
|
|
|
- ctx.moveTo(dx, dy)
|
|
|
|
|
- } else {
|
|
|
|
|
- ctx.lineTo(dx, dy)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ctx.closePath()
|
|
|
|
|
- ctx.fillStyle = 'rgba(249, 114, 22, 0.2)'
|
|
|
|
|
- ctx.fill()
|
|
|
|
|
- ctx.strokeStyle = '#F97316'
|
|
|
|
|
- ctx.lineWidth = 2
|
|
|
|
|
- ctx.stroke()
|
|
|
|
|
-
|
|
|
|
|
- // 数据节点圆点 + 分数标签
|
|
|
|
|
- for (var n = 0; n < 5; n++) {
|
|
|
|
|
- var ang2 = n * angleStep - Math.PI / 2
|
|
|
|
|
- var key2 = this.elementKeys[n]
|
|
|
|
|
- var ratio2 = (scores[key2] || 0) / 9
|
|
|
|
|
- var dataR2 = r * ratio2
|
|
|
|
|
- var px = cx + dataR2 * Math.cos(ang2)
|
|
|
|
|
- var py = cy + dataR2 * Math.sin(ang2)
|
|
|
|
|
-
|
|
|
|
|
- ctx.beginPath()
|
|
|
|
|
- ctx.arc(px, py, 4, 0, Math.PI * 2)
|
|
|
|
|
- ctx.fillStyle = this.elementColors[n]
|
|
|
|
|
- ctx.fill()
|
|
|
|
|
-
|
|
|
|
|
- var pctLabelR = dataR2 + (ratio2 > 0.35 ? -16 : 18)
|
|
|
|
|
- var pLabelX = cx + pctLabelR * Math.cos(ang2)
|
|
|
|
|
- var pLabelY = cy + pctLabelR * Math.sin(ang2)
|
|
|
|
|
- ctx.fillStyle = this.elementColors[n]
|
|
|
|
|
- ctx.font = 'bold 11px sans-serif'
|
|
|
|
|
- ctx.textAlign = 'center'
|
|
|
|
|
- ctx.textBaseline = 'middle'
|
|
|
|
|
- ctx.fillText(String(scores[key2] || 0), pLabelX, pLabelY)
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
formatDate: function(dateStr) {
|
|
formatDate: function(dateStr) {
|
|
|
if (!dateStr) {
|
|
if (!dateStr) {
|
|
|
return ''
|
|
return ''
|
|
@@ -504,16 +359,6 @@ export default {
|
|
|
color: #999;
|
|
color: #999;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 雷达图 */
|
|
|
|
|
-.scr-canvas-wrap {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
-}
|
|
|
|
|
-.scr-canvas {
|
|
|
|
|
- width: 340px;
|
|
|
|
|
- height: 340px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
/* 维度得分 */
|
|
/* 维度得分 */
|
|
|
.scr-dim-list {
|
|
.scr-dim-list {
|
|
|
display: flex;
|
|
display: flex;
|