فهرست منبع

feat(tianpan): 增强五行雷达图可视化

- 五行元素独立配色: 木绿/火粉/土橙/金紫/水琥珀
- 数据驱动多边形填充(familyWuxing.aggregatePercentages)
- 百分比标签 + 数据节点圆点
- 中心显示家庭名+最强/最弱元素
Xiaogang Liao 2 ماه پیش
والد
کامیت
47b3289f8a
1فایلهای تغییر یافته به همراه102 افزوده شده و 21 حذف شده
  1. 102 21
      cfc-frontend/pages/tianpan/index.vue

+ 102 - 21
cfc-frontend/pages/tianpan/index.vue

@@ -253,47 +253,128 @@ export default {
     
     drawRadar: function(ctx, cx, cy, r, members) {
       var axes = ['木', '火', '土', '金', '水']
+      var elementKeys = ['wood', 'fire', 'earth', 'metal', 'water']
+      var elementColors = ['#10B981', '#FF6B9D', '#FF8C42', '#6366F1', '#F59E0B']
       var angleStep = (Math.PI * 2) / 5
-      
-      // 绘制五边形背景
+
+      // 获取五行数据
+      var wuxing = this.familyWuxing || {}
+      var percentages = (wuxing.aggregatePercentages) || {}
+      var strongest = wuxing.strongestElement || ''
+      var weakest = wuxing.weakestElement || ''
+      var familyLabel = this.familyName || '家庭五行'
+
+      // 绘制背景五边形
       ctx.beginPath()
       for (var i = 0; i < 5; i++) {
         var angle = i * angleStep - Math.PI / 2
-        var x = cx + r * Math.cos(angle)
-        var y = cy + r * Math.sin(angle)
+        var bx = cx + r * Math.cos(angle)
+        var by = cy + r * Math.sin(angle)
         if (i === 0) {
-          ctx.moveTo(x, y)
+          ctx.moveTo(bx, by)
         } else {
-          ctx.lineTo(x, y)
+          ctx.lineTo(bx, by)
         }
       }
       ctx.closePath()
-      ctx.fillStyle = 'rgba(249, 114, 22, 0.1)'
+      ctx.fillStyle = 'rgba(249, 114, 22, 0.08)'
       ctx.fill()
-      ctx.strokeStyle = '#F97316'
+      ctx.strokeStyle = 'rgba(249, 114, 22, 0.25)'
       ctx.lineWidth = 1
       ctx.stroke()
-      
-      // 绘制轴线
+
+      // 绘制彩色轴线 + 轴标签
       for (var j = 0; j < 5; j++) {
-        var angle = j * angleStep - Math.PI / 2
-        var x = cx + r * Math.cos(angle)
-        var y = cy + r * Math.sin(angle)
+        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(x, y)
-        ctx.strokeStyle = 'rgba(249, 114, 22, 0.3)'
+        ctx.lineTo(lx, ly)
+        ctx.strokeStyle = elementColors[j] + '44'
+        ctx.lineWidth = 1
         ctx.stroke()
-        
-        // 绘制轴标签
-        var labelX = cx + (r + 15) * Math.cos(angle)
-        var labelY = cy + (r + 15) * Math.sin(angle)
-        ctx.fillStyle = '#F97316'
-        ctx.font = '12px sans-serif'
+
+        // 轴标签(元素名)
+        var labelX = cx + (r + 16) * Math.cos(a2)
+        var labelY = cy + (r + 16) * Math.sin(a2)
+        ctx.fillStyle = elementColors[j]
+        ctx.font = 'bold 12px sans-serif'
         ctx.textAlign = 'center'
         ctx.textBaseline = 'middle'
         ctx.fillText(axes[j], labelX, labelY)
       }
+
+      // 绘制数据驱动多边形(按百分比缩放)
+      var hasData = false
+      for (var k = 0; k < elementKeys.length; k++) {
+        if (percentages[elementKeys[k]] && percentages[elementKeys[k]] > 0) {
+          hasData = true
+          break
+        }
+      }
+
+      if (hasData) {
+        ctx.beginPath()
+        for (var m = 0; m < 5; m++) {
+          var ang = m * angleStep - Math.PI / 2
+          var pct = (percentages[elementKeys[m]] || 0) / 100
+          var dataR = r * pct
+          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 pct2 = (percentages[elementKeys[n]] || 0) / 100
+          var dataR2 = r * pct2
+          var px = cx + dataR2 * Math.cos(ang2)
+          var py = cy + dataR2 * Math.sin(ang2)
+
+          // 圆点
+          ctx.beginPath()
+          ctx.arc(px, py, 3, 0, Math.PI * 2)
+          ctx.fillStyle = elementColors[n]
+          ctx.fill()
+
+          // 百分比标签(在圆点外侧)
+          var pctLabelR = dataR2 + (pct2 > 0.3 ? -14 : 14)
+          var pLabelX = cx + pctLabelR * Math.cos(ang2)
+          var pLabelY = cy + pctLabelR * Math.sin(ang2)
+          ctx.fillStyle = elementColors[n]
+          ctx.font = '10px sans-serif'
+          ctx.textAlign = 'center'
+          ctx.textBaseline = 'middle'
+          ctx.fillText((percentages[elementKeys[n]] || 0) + '%', pLabelX, pLabelY)
+        }
+      }
+
+      // 中心文字:家庭名 + 最强/最弱
+      ctx.fillStyle = '#1F2937'
+      ctx.font = 'bold 11px sans-serif'
+      ctx.textAlign = 'center'
+      ctx.textBaseline = 'middle'
+      ctx.fillText(familyLabel, cx, cy - 6)
+
+      if (strongest || weakest) {
+        ctx.fillStyle = '#6B7280'
+        ctx.font = '9px sans-serif'
+        var strongestZh = strongest === 'wood' ? '木' : strongest === 'fire' ? '火' : strongest === 'earth' ? '土' : strongest === 'metal' ? '金' : strongest === 'water' ? '水' : strongest
+        var weakestZh = weakest === 'wood' ? '木' : weakest === 'fire' ? '火' : weakest === 'earth' ? '土' : weakest === 'metal' ? '金' : weakest === 'water' ? '水' : weakest
+        ctx.fillText('强:' + strongestZh + ' 弱:' + weakestZh, cx, cy + 7)
+      }
     },
     
     drawMemberNodes: function(ctx, cx, cy, r, members) {