feat(dashboard): 新增波色转移概率表格,与区域转移概率并排展示
This commit is contained in:
@@ -22,7 +22,7 @@ class History extends Backend
|
|||||||
* 无需额外权限检查的方法(但仍在 admin 模块内,需要 admin 登录)
|
* 无需额外权限检查的方法(但仍在 admin 模块内,需要 admin 登录)
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction', 'zoneTransition'];
|
protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard', 'specialHeatmap', 'specialHotColdAction', 'zoneTransition', 'colorWaveTransition'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
@@ -328,5 +328,20 @@ class History extends Backend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 波色转移概率统计
|
||||||
|
*/
|
||||||
|
public function colorWaveTransition()
|
||||||
|
{
|
||||||
|
if ($this->request->isAjax()) {
|
||||||
|
$periods = $this->request->get('periods', 100, 'intval');
|
||||||
|
if ($periods < 10 || $periods > 500) {
|
||||||
|
$this->error('期数范围必须在 10-500 之间');
|
||||||
|
}
|
||||||
|
$result = $this->model->getColorWaveTransition($periods);
|
||||||
|
$this->success('查询成功', null, $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -465,7 +465,8 @@ class History extends Model
|
|||||||
'special' => $this->getSpecialTrend($periods),
|
'special' => $this->getSpecialTrend($periods),
|
||||||
'tailnumbers' => $this->getTailNumbers($periods, 'special'),
|
'tailnumbers' => $this->getTailNumbers($periods, 'special'),
|
||||||
'heatmap' => $this->getSpecialHeatmap($periods),
|
'heatmap' => $this->getSpecialHeatmap($periods),
|
||||||
'zonetransition' => $this->getZoneTransition($periods)
|
'zonetransition' => $this->getZoneTransition($periods),
|
||||||
|
'colorwavetransition' => $this->getColorWaveTransition($periods)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,6 +730,71 @@ class History extends Model
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 波色转移概率统计
|
||||||
|
* 统计特码从一种波色转移到另一种波色的概率(红/蓝/绿)
|
||||||
|
* @param int $periods 查询最近多少期
|
||||||
|
* @return array {colors: [], matrix: [], probabilities: [], row_totals: [], total_transitions: int}
|
||||||
|
*/
|
||||||
|
public function getColorWaveTransition($periods = 100)
|
||||||
|
{
|
||||||
|
$history = $this
|
||||||
|
->field('expect,num7,openTime')
|
||||||
|
->order('openTime', 'desc')
|
||||||
|
->limit($periods)
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if (empty($history) || count($history) < 2) {
|
||||||
|
return ['colors' => ['红波','蓝波','绿波'], 'matrix' => [], 'probabilities' => [], 'row_totals' => [], 'total_transitions' => 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$history = array_reverse($history);
|
||||||
|
$num_model = new Num();
|
||||||
|
$colorMap = $num_model->column('color', 'num');
|
||||||
|
|
||||||
|
$colorLabels = ['红波', '蓝波', '绿波'];
|
||||||
|
$matrix = array_fill(0, 3, array_fill(0, 3, 0));
|
||||||
|
$rowTotals = array_fill(0, 3, 0);
|
||||||
|
|
||||||
|
$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 = $getColorIdx($currentNum);
|
||||||
|
$to = $getColorIdx($nextNum);
|
||||||
|
if ($from < 0 || $to < 0) continue;
|
||||||
|
|
||||||
|
$matrix[$from][$to]++;
|
||||||
|
$rowTotals[$from]++;
|
||||||
|
$totalTransitions++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$probabilities = array_fill(0, 3, array_fill(0, 3, 0));
|
||||||
|
for ($i = 0; $i < 3; $i++) {
|
||||||
|
if ($rowTotals[$i] > 0) {
|
||||||
|
for ($j = 0; $j < 3; $j++) {
|
||||||
|
$probabilities[$i][$j] = round($matrix[$i][$j] / $rowTotals[$i] * 100, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'colors' => $colorLabels,
|
||||||
|
'matrix' => $matrix,
|
||||||
|
'probabilities' => $probabilities,
|
||||||
|
'row_totals' => $rowTotals,
|
||||||
|
'total_transitions' => $totalTransitions
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 特码热力图数据
|
* 特码热力图数据
|
||||||
* @param int $periods 查询最近多少期
|
* @param int $periods 查询最近多少期
|
||||||
|
|||||||
@@ -85,10 +85,13 @@ define(['jquery'], function ($) {
|
|||||||
|
|
||||||
html += '<div class="dash-section"><h4>🔢 尾数频率</h4><div id="tail-chart" style="width:100%;height:220px;"></div></div>';
|
html += '<div class="dash-section"><h4>🔢 尾数频率</h4><div id="tail-chart" style="width:100%;height:220px;"></div></div>';
|
||||||
|
|
||||||
// 区域转移概率
|
// 区域转移概率 + 波色转移概率
|
||||||
if (zt && zt.matrix && zt.matrix.length > 0) {
|
if (zt && zt.matrix && zt.matrix.length > 0) {
|
||||||
html += '<div class="dash-section"><h4>🔄 区域转移概率</h4><div style="font-size:12px;color:#999;margin-bottom:8px;">当前共 ' + zt.total_transitions + ' 次区域转移 | 行=上一期特码所在区域,列=下一期特码所在区域</div>';
|
var cwt = data.colorwavetransition;
|
||||||
html += '<table class="table table-bordered table-condensed text-center" style="max-width:600px;margin:0 auto;"><thead><tr><th style="width:80px;position:relative;"><div style="width:100%;height:35px;border-bottom:1px solid #e5e5e5;position:relative;"><span style="position:absolute;top:2px;right:5px;font-size:12px;">区域</span><span style="position:absolute;bottom:2px;left:5px;font-size:12px;">特码</span></div></th>';
|
html += '<div class="dash-section"><h4>🔄 转移概率</h4><div class="row">';
|
||||||
|
// 左侧:区域转移
|
||||||
|
html += '<div class="col-sm-7"><div style="font-size:12px;color:#999;margin-bottom:8px;">区域转移(共 ' + zt.total_transitions + ' 次)</div>';
|
||||||
|
html += '<table class="table table-bordered table-condensed text-center" style="margin:0 auto;"><thead><tr><th style="width:80px;position:relative;"><div style="width:100%;height:35px;border-bottom:1px solid #e5e5e5;position:relative;"><span style="position:absolute;top:2px;right:5px;font-size:12px;">区域</span><span style="position:absolute;bottom:2px;left:5px;font-size:12px;">特码</span></div></th>';
|
||||||
for (var z = 0; z < zt.zones.length; z++) {
|
for (var z = 0; z < zt.zones.length; z++) {
|
||||||
html += '<th>' + zt.zones[z] + '</th>';
|
html += '<th>' + zt.zones[z] + '</th>';
|
||||||
}
|
}
|
||||||
@@ -105,6 +108,29 @@ define(['jquery'], function ($) {
|
|||||||
html += '</tr>';
|
html += '</tr>';
|
||||||
}
|
}
|
||||||
html += '</tbody></table></div>';
|
html += '</tbody></table></div>';
|
||||||
|
// 右侧:波色转移
|
||||||
|
if (cwt && cwt.matrix && cwt.matrix.length > 0) {
|
||||||
|
html += '<div class="col-sm-5"><div style="font-size:12px;color:#999;margin-bottom:8px;">波色转移(共 ' + cwt.total_transitions + ' 次)</div>';
|
||||||
|
html += '<table class="table table-bordered table-condensed text-center" style="margin:0 auto;"><thead><tr><th style="width:70px;position:relative;"><div style="width:100%;height:35px;border-bottom:1px solid #e5e5e5;position:relative;"><span style="position:absolute;top:2px;right:5px;font-size:12px;">区域</span><span style="position:absolute;bottom:2px;left:5px;font-size:12px;">特码</span></div></th>';
|
||||||
|
for (var z = 0; z < cwt.colors.length; z++) {
|
||||||
|
html += '<th>' + cwt.colors[z] + '</th>';
|
||||||
|
}
|
||||||
|
html += '</tr></thead><tbody>';
|
||||||
|
var cwColors = ['#e74c3c', '#3498db', '#2ecc71'];
|
||||||
|
for (var r = 0; r < 3; r++) {
|
||||||
|
html += '<tr><td style="font-weight:bold;color:' + cwColors[r] + ';">' + cwt.colors[r] + '</td>';
|
||||||
|
for (var c = 0; c < 3; c++) {
|
||||||
|
var pct = cwt.probabilities[r][c];
|
||||||
|
var cnt = cwt.matrix[r][c];
|
||||||
|
var bg = pct > 40 ? cwColors[r] : pct > 20 ? cwColors[c] : pct > 0 ? '#95a5a6' : '#f5f5f5';
|
||||||
|
var txt = pct > 20 ? '#fff' : '#333';
|
||||||
|
html += '<td style="background-color:' + bg + ';color:' + txt + ';">' + cnt + '次<br>' + pct + '%</td>';
|
||||||
|
}
|
||||||
|
html += '</tr>';
|
||||||
|
}
|
||||||
|
html += '</tbody></table></div>';
|
||||||
|
}
|
||||||
|
html += '</div></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 热力图部分
|
// 热力图部分
|
||||||
|
|||||||
Reference in New Issue
Block a user