feat(dashboard): 添加后台仪表板功能并优化数据分析

- 新增 dashboard.js 文件实现前端图表展示功能
- 添加彩球渲染和颜色映射功能
- 实现数据加载和渲染逻辑
- 添加多种统计图表包括冷热号码、比例分析、生肖排名等
- 重构区域转移动态数据方法
- 更新区域到区域颜色转移概率计算逻辑
- 优化转移概率数据结构和显示方式
- 添加热力图和各种统计图表的响应式支持
This commit is contained in:
2026-04-26 00:14:50 +08:00
parent c3e430a24b
commit 8d9161eb1a
2 changed files with 39 additions and 41 deletions
+29 -30
View File
@@ -467,7 +467,7 @@ class History extends Model
'heatmap' => $this->getSpecialHeatmap($periods),
'zonetransition' => $this->getZoneTransition($periods),
'colorwavetransition' => $this->getColorWaveTransition($periods),
'zonetocolortransition' => $this->getZoneToColorTransition($periods)
'zonetocolortransition' => $this->getZoneToZoneColor($periods)
];
}
@@ -797,12 +797,12 @@ class History extends Model
}
/**
* 区域→波色交叉转移概率
* 统计上一期特码所在数字区域后,下一期特码波色(红/蓝/绿)的分布概率
* 区域→区域转移矩阵,单元格内显示波色概率
* 统计上一期特码所在区域后,下一期特码在各区域的分布,以及每个区域内的波色占比
* @param int $periods 查询最近多少期
* @return array {zones: [], colors: [], matrix: [], probabilities: [], row_totals: [], total_transitions: int}
* @return array {zones: [], matrix: [[zone_count]], color_probs: [[{red, blue, green}]]}
*/
public function getZoneToColorTransition($periods = 100)
public function getZoneToZoneColor($periods = 100)
{
$history = $this
->field('expect,num7,openTime')
@@ -811,7 +811,7 @@ class History extends Model
->select();
if (empty($history) || count($history) < 2) {
return ['zones' => ['1-10','11-20','21-30','31-40','41-49'], 'colors' => ['红波','蓝波','绿波'], 'matrix' => [], 'probabilities' => [], 'row_totals' => [], 'total_transitions' => 0];
return ['zones' => ['1-10','11-20','21-30','31-40','41-49'], 'matrix' => [], 'color_probs' => []];
}
$history = array_reverse($history);
@@ -819,9 +819,13 @@ class History extends Model
$colorMap = $num_model->column('color', 'num');
$zoneLabels = ['1-10', '11-20', '21-30', '31-40', '41-49'];
$colorLabels = ['红波', '蓝波', '绿波'];
$matrix = array_fill(0, 5, array_fill(0, 3, 0));
$rowTotals = array_fill(0, 5, 0);
$matrix = array_fill(0, 5, array_fill(0, 5, 0));
$colorCounts = [];
for ($i = 0; $i < 5; $i++) {
for ($j = 0; $j < 5; $j++) {
$colorCounts[$i][$j] = ['red' => 0, 'blue' => 0, 'green' => 0];
}
}
$getZone = function ($num) {
if ($num <= 10) return 0;
@@ -831,43 +835,38 @@ class History extends Model
return 4;
};
$getColorIdx = function ($num) use ($colorMap) {
$color = $colorMap[$num] ?? '';
if (strpos($color, '红') !== false) return 0;
if (strpos($color, '蓝') !== false) return 1;
if (strpos($color, '绿') !== false) return 2;
return -1;
};
$totalTransitions = 0;
for ($i = 0; $i < count($history) - 1; $i++) {
$currentNum = (int)$history[$i]['num7'];
$nextNum = (int)$history[$i + 1]['num7'];
$from = $getZone($currentNum);
$to = $getColorIdx($nextNum);
if ($to < 0) continue;
$to = $getZone($nextNum);
$color = $colorMap[$nextNum] ?? '';
$matrix[$from][$to]++;
$rowTotals[$from]++;
$totalTransitions++;
if (strpos($color, '红') !== false) $colorCounts[$from][$to]['red']++;
elseif (strpos($color, '蓝') !== false) $colorCounts[$from][$to]['blue']++;
elseif (strpos($color, '绿') !== false) $colorCounts[$from][$to]['green']++;
}
$probabilities = array_fill(0, 5, array_fill(0, 3, 0));
// 计算每个单元格波色概率
$colorProbs = array_fill(0, 5, array_fill(0, 5, ['red' => 0, 'blue' => 0, 'green' => 0]));
for ($i = 0; $i < 5; $i++) {
if ($rowTotals[$i] > 0) {
for ($j = 0; $j < 3; $j++) {
$probabilities[$i][$j] = round($matrix[$i][$j] / $rowTotals[$i] * 100, 1);
for ($j = 0; $j < 5; $j++) {
$total = $matrix[$i][$j];
if ($total > 0) {
$colorProbs[$i][$j] = [
'red' => round($colorCounts[$i][$j]['red'] / $total * 100, 1),
'blue' => round($colorCounts[$i][$j]['blue'] / $total * 100, 1),
'green' => round($colorCounts[$i][$j]['green'] / $total * 100, 1),
];
}
}
}
return [
'zones' => $zoneLabels,
'colors' => $colorLabels,
'matrix' => $matrix,
'probabilities' => $probabilities,
'row_totals' => $rowTotals,
'total_transitions' => $totalTransitions
'color_probs' => $colorProbs
];
}