feat: replace sum analysis with special trend line chart, zodiac/tail numbers use bar charts
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', 'sumAnalysis', 'consecutiveNumbers', 'tailNumbers', 'dashboard'];
|
protected $noNeedRight = ['missingNum', 'trendData', 'hotColdNumbers', 'colorWaveAnalysis', 'zodiacAnalysis', 'oddEvenAnalysis', 'bigSmallAnalysis', 'specialTrend', 'consecutiveNumbers', 'tailNumbers', 'dashboard'];
|
||||||
|
|
||||||
public function _initialize()
|
public function _initialize()
|
||||||
{
|
{
|
||||||
@@ -169,16 +169,16 @@ class History extends Backend
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 和值分析
|
* 特码走势
|
||||||
*/
|
*/
|
||||||
public function sumAnalysis()
|
public function specialTrend()
|
||||||
{
|
{
|
||||||
if ($this->request->isAjax()) {
|
if ($this->request->isAjax()) {
|
||||||
$periods = $this->request->get('periods', 30, 'intval');
|
$periods = $this->request->get('periods', 30, 'intval');
|
||||||
if ($periods < 10 || $periods > 100) {
|
if ($periods < 10 || $periods > 100) {
|
||||||
$this->error('期数范围必须在 10-100 之间');
|
$this->error('期数范围必须在 10-100 之间');
|
||||||
}
|
}
|
||||||
$result = $this->model->getSumAnalysis($periods);
|
$result = $this->model->getSpecialTrend($periods);
|
||||||
$this->success('查询成功', null, $result);
|
$this->success('查询成功', null, $result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,22 +366,24 @@ class History extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 和值分析
|
* 特码走势
|
||||||
*/
|
*/
|
||||||
public function getSumAnalysis($periods = 30)
|
public function getSpecialTrend($periods = 30)
|
||||||
{
|
{
|
||||||
$history = $this->field('expect,num1,num2,num3,num4,num5,num6,num7')->order('openTime', 'asc')->limit($periods)->select();
|
$history = $this->field('expect,num7')->order('openTime', 'asc')->limit($periods)->select();
|
||||||
if (empty($history)) return ['expects' => [], 'sums' => []];
|
if (empty($history)) return ['expects' => [], 'specials' => [], 'colors' => []];
|
||||||
|
|
||||||
$expects = []; $sums = [];
|
$num_model = new Num();
|
||||||
|
$colorMap = $num_model->column('color', 'num');
|
||||||
|
|
||||||
|
$expects = []; $specials = []; $colors = [];
|
||||||
foreach ($history as $row) {
|
foreach ($history as $row) {
|
||||||
$expects[] = (string)$row['expect'];
|
$expects[] = (string)$row['expect'];
|
||||||
$sum = (int)$row['num1'] + (int)$row['num2'] + (int)$row['num3'] + (int)$row['num4'] + (int)$row['num5'] + (int)$row['num6'] + (int)$row['num7'];
|
$num = (int)$row['num7'];
|
||||||
$sums[] = $sum;
|
$specials[] = $num;
|
||||||
|
$colors[] = $colorMap[$num] ?? '';
|
||||||
}
|
}
|
||||||
$avg = round(array_sum($sums) / count($sums), 1);
|
return ['expects' => $expects, 'specials' => $specials, 'colors' => $colors];
|
||||||
$max = max($sums); $min = min($sums);
|
|
||||||
return ['expects' => $expects, 'sums' => $sums, 'avg' => $avg, 'max' => $max, 'min' => $min];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -457,7 +459,7 @@ class History extends Model
|
|||||||
'zodiac' => $this->getZodiacAnalysis($periods, $type),
|
'zodiac' => $this->getZodiacAnalysis($periods, $type),
|
||||||
'oddeven' => $this->getOddEvenAnalysis($periods, $type),
|
'oddeven' => $this->getOddEvenAnalysis($periods, $type),
|
||||||
'bigsmall' => $this->getBigSmallAnalysis($periods, $type),
|
'bigsmall' => $this->getBigSmallAnalysis($periods, $type),
|
||||||
'sum' => $this->getSumAnalysis($periods),
|
'special' => $this->getSpecialTrend($periods),
|
||||||
'tailnumbers' => $this->getTailNumbers($periods, $type)
|
'tailnumbers' => $this->getTailNumbers($periods, $type)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ define(['jquery'], function ($) {
|
|||||||
|
|
||||||
function render(data) {
|
function render(data) {
|
||||||
var hc = data.hotcold, cw = data.colorwave, zo = data.zodiac;
|
var hc = data.hotcold, cw = data.colorwave, zo = data.zodiac;
|
||||||
var oe = data.oddeven, bs = data.bigsmall, sm = data.sum, tn = data.tailnumbers;
|
var oe = data.oddeven, bs = data.bigsmall, sp = data.special, tn = data.tailnumbers;
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
@@ -70,42 +70,71 @@ define(['jquery'], function ($) {
|
|||||||
html += '</div></div></div>';
|
html += '</div></div></div>';
|
||||||
html += '</div></div>';
|
html += '</div></div>';
|
||||||
|
|
||||||
html += '<div class="dash-section"><h4>⭐ 生肖排名</h4><div style="display:flex;flex-wrap:wrap;">';
|
html += '<div class="dash-section"><h4>⭐ 生肖排名</h4><div id="zodiac-chart" style="width:100%;height:250px;"></div></div>';
|
||||||
for (var i = 0; i < Math.min(zo.list.length, 12); i++) {
|
|
||||||
var z = zo.list[i];
|
|
||||||
html += '<div class="mini-card"><div class="name">' + z.animal + '</div><div class="val">' + z.count + ' (' + z.percent + '%)</div></div>';
|
|
||||||
}
|
|
||||||
html += '</div></div>';
|
|
||||||
|
|
||||||
html += '<div class="dash-section"><h4>📈 和值统计</h4><div class="row">';
|
html += '<div class="dash-section"><h4>📈 特码走势</h4><div id="special-chart" style="width:100%;height:280px;"></div></div>';
|
||||||
html += '<div class="col-sm-4"><div class="dash-card"><div class="big-num">' + sm.avg + '</div><div class="label-text">平均和值</div></div></div>';
|
|
||||||
html += '<div class="col-sm-4"><div class="dash-card"><div class="big-num" style="color:#e74c3c;">' + sm.max + '</div><div class="label-text">最大和值</div></div></div>';
|
|
||||||
html += '<div class="col-sm-4"><div class="dash-card"><div class="big-num" style="color:#3498db;">' + sm.min + '</div><div class="label-text">最小和值</div></div></div>';
|
|
||||||
html += '</div><div id="dash-chart" style="margin-top:15px;"></div></div>';
|
|
||||||
|
|
||||||
html += '<div class="dash-section"><h4>🔢 尾数频率</h4><div style="display:flex;flex-wrap:wrap;">';
|
html += '<div class="dash-section"><h4>🔢 尾数频率</h4><div id="tail-chart" style="width:100%;height:220px;"></div></div>';
|
||||||
for (var i = 0; i < tn.all.length; i++) {
|
|
||||||
var t = tn.all[i];
|
|
||||||
html += '<div class="mini-card"><div class="name">' + t.tail + '</div><div class="val">' + t.count + ' (' + t.percent + '%)</div></div>';
|
|
||||||
}
|
|
||||||
html += '</div></div>';
|
|
||||||
|
|
||||||
$('#dash-content').html(html);
|
$('#dash-content').html(html);
|
||||||
|
|
||||||
if (typeof echarts !== 'undefined' && sm.expects && sm.expects.length > 0) {
|
// 生肖柱状图
|
||||||
var chartDom = document.getElementById('dash-chart');
|
if (typeof echarts !== 'undefined' && zo.list && zo.list.length > 0) {
|
||||||
|
var zDom = document.getElementById('zodiac-chart');
|
||||||
|
if (zDom) {
|
||||||
|
var zChart = echarts.init(zDom);
|
||||||
|
zChart.setOption({
|
||||||
|
tooltip: {trigger: 'axis', axisPointer: {type: 'shadow'}},
|
||||||
|
grid: {left: 50, right: 20, bottom: 30, top: 10},
|
||||||
|
xAxis: {type: 'category', data: zo.list.map(function(z){return z.animal;})},
|
||||||
|
yAxis: {type: 'value'},
|
||||||
|
series: [{type: 'bar', data: zo.list.map(function(z){return z.count;}), itemStyle: {color: '#626c91'}}]
|
||||||
|
});
|
||||||
|
$(window).on('resize', function(){ zChart.resize(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 特码走势
|
||||||
|
if (typeof echarts !== 'undefined' && sp.expects && sp.expects.length > 0) {
|
||||||
|
var chartDom = document.getElementById('special-chart');
|
||||||
if (chartDom) {
|
if (chartDom) {
|
||||||
var chart = echarts.init(chartDom);
|
var chart = echarts.init(chartDom);
|
||||||
|
var colorMap = {'红': '#e74c3c', '蓝': '#3498db', '绿': '#2ecc71'};
|
||||||
|
var itemColors = sp.colors.map(function(c) {
|
||||||
|
if (c.indexOf('红') !== -1) return colorMap['红'];
|
||||||
|
if (c.indexOf('蓝') !== -1) return colorMap['蓝'];
|
||||||
|
if (c.indexOf('绿') !== -1) return colorMap['绿'];
|
||||||
|
return '#95a5a6';
|
||||||
|
});
|
||||||
chart.setOption({
|
chart.setOption({
|
||||||
tooltip: {trigger: 'axis'},
|
tooltip: {trigger: 'axis', formatter: function(p) {
|
||||||
xAxis: {type: 'category', data: sm.expects, axisLabel: {rotate: 45, fontSize: 10}},
|
return '期号: ' + p[0].axisValue + '<br/>特码: <b style="color:' + itemColors[p[0].dataIndex] + '">' + p[0].data + '</b>';
|
||||||
yAxis: {type: 'value'},
|
}},
|
||||||
series: [{type: 'line', data: sm.sums, smooth: true, itemStyle: {color: '#3498db'}, areaStyle: {color: 'rgba(52,152,219,0.1)'}}],
|
xAxis: {type: 'category', data: sp.expects, axisLabel: {rotate: 45, fontSize: 10}},
|
||||||
|
yAxis: {type: 'value', min: 0, max: 50},
|
||||||
|
series: [{type: 'line', data: sp.specials, smooth: true, symbolSize: 8, itemStyle: {color: function(p) { return itemColors[p.dataIndex]; }}, areaStyle: {color: 'rgba(52,152,219,0.05)'}}],
|
||||||
grid: {left: 50, right: 20, bottom: 50, top: 20}
|
grid: {left: 50, right: 20, bottom: 50, top: 20}
|
||||||
});
|
});
|
||||||
$(window).on('resize', function () { chart.resize(); });
|
$(window).on('resize', function () { chart.resize(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 尾数柱状图
|
||||||
|
if (typeof echarts !== 'undefined' && tn.all && tn.all.length > 0) {
|
||||||
|
var tDom = document.getElementById('tail-chart');
|
||||||
|
if (tDom) {
|
||||||
|
var tChart = echarts.init(tDom);
|
||||||
|
var sorted = tn.all.slice().sort(function(a,b){return a.tail - b.tail;});
|
||||||
|
tChart.setOption({
|
||||||
|
tooltip: {trigger: 'axis', axisPointer: {type: 'shadow'}},
|
||||||
|
grid: {left: 50, right: 20, bottom: 30, top: 10},
|
||||||
|
xAxis: {type: 'category', data: sorted.map(function(t){return t.tail;})},
|
||||||
|
yAxis: {type: 'value'},
|
||||||
|
series: [{type: 'bar', data: sorted.map(function(t){return t.count;}), itemStyle: {color: '#23b7e5'}}]
|
||||||
|
});
|
||||||
|
$(window).on('resize', function(){ tChart.resize(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#btn-dash-refresh').on('click', loadData);
|
$('#btn-dash-refresh').on('click', loadData);
|
||||||
|
|||||||
Reference in New Issue
Block a user