php/laravel: 创建图表数据,return 0 如果没有数据被提交到数据库
php/laravel: Creating chartdata, return 0 if no data is being submitted to database
我正在尝试根据数据库 return 编辑的数据创建图表。数据存储在数据库中,此 table 中可以有多个图表。由唯一值标识。 (钻机名称)
array:102 [▼
0 => array:6 [▼
"id" => 2002
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.364,"pool":"eu1.ethermine.org:4444","shares":{"valid":"2","invalid":"0"},"gpus":[{"temperature":"56","fanSpeed":"56","hashrates":12.364}]}"
"created_at" => "2018-02-23 10:24:50"
"updated_at" => "2018-02-23 10:24:50"
],
1 => array:6 [▼
"id" => 2019
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.612,"pool":"eu1.ethermine.org:4444","shares":{"valid":"736","invalid":"2"},"gpus":[{"temperature":"65","fanSpeed":"67","hashrates":19.804},{"temp ▶"
"created_at" => "2018-02-23 10:25:56"
"updated_at" => "2018-02-23 10:25:56"
]
如您所见,根据 rigname 有两种可能的图表。我想在图表上显示两个钻机的哈希值。这可行,但是,当一个钻机停止时,没有数据从该钻机提交到数据库。
图表显示该装备没有 0 值,正在使用最后已知的数据。 (呃)
我通过修改我的查询解决了这个问题:
$res[$value] = json_decode(MinerStatistics::where('rigname', $value)
->where('created_at','>=', \Carbon\Carbon::now()->subMinutes(20))
->orderBy('created_at', 'desc')
->get()
->toJson(), true
);
现在,当钻机停止并查询数据库时,我只能得到过去 x 分钟的数据。这是在 foreach 中完成的,它构建了一个新的多维数组,其中的数据按钻井名称排序。
这引发了一个新问题,当我重新启动钻机并开始向数据库报告时。图表上的值不在当前时间戳继续,它们在钻机停止的地方继续。通常我会在每次 运行 钻机报告时将上次报告数据和之前报告数据的时间戳与仍然是 运行 和 return 0 的钻机数据进行比较,但是他们报告不同的时间戳(都在 8 秒内)
如何修改 returned mysql 数据,最终得到如下结果:
array:2 [▼
"home" => array:150 [
0 => array:6 [▼
"id" => 2300
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.359,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.359}]}"
"created_at" => "2018-02-23 10:44:42"
"updated_at" => "2018-02-23 10:44:42"
]
1 => array:6 [▼
"id" => 2298
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.367,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.367}]}"
"created_at" => "2018-02-23 10:44:34"
"updated_at" => "2018-02-23 10:44:34"
]
2 => array:6 [▼
"id" => 2296
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.367,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.367}]}"
"created_at" => "2018-02-23 10:44:26"
"updated_at" => "2018-02-23 10:44:26"
]
...
Server stops, no data, should continue like this
3 => [false] ,
4 => [false] ,
5 => [false]
...
rig reports again to the database
36 => array:6 [▼
"id" => 2296
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.367,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.367}]}"
"created_at" => "2018-02-23 10:44:26"
"updated_at" => "2018-02-23 10:44:26"
],
],
"server" => array:150 [▼ // This keeps running, or visa versa
0 => array:6 [▼
"id" => 2301
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.62,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"67","hashrates":19.778},{"tempe ▶"
"created_at" => "2018-02-23 10:44:44"
"updated_at" => "2018-02-23 10:44:44"
]
1 => array:6 [▼
"id" => 2299
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.68,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.815},{"tempe ▶"
"created_at" => "2018-02-23 10:44:36"
"updated_at" => "2018-02-23 10:44:36"
]
2 => array:6 [▼
"id" => 2297
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.644,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.793},{"temp ▶"
"created_at" => "2018-02-23 10:44:28"
"updated_at" => "2018-02-23 10:44:28"
]
3 => array:6 [▼
"id" => 2295
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.105,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.793},{"temp ▶"
"created_at" => "2018-02-23 10:44:20"
"updated_at" => "2018-02-23 10:44:20"
]
4 => array:6 [▼
"id" => 2293
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.557,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.78},{"tempe ▶"
"created_at" => "2018-02-23 10:44:12"
"updated_at" => "2018-02-23 10:44:12"
]
5 => array:6 [▼
"id" => 2291
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.562,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.794},{"temp ▶"
"created_at" => "2018-02-23 10:44:04"
"updated_at" => "2018-02-23 10:44:04"
]
]
]
目前我写的代码:
public function index()
{
// Get the statistics from the database reported by the miner
// Group them by the rig name
$stats = MinerStatistics::where('user_id', Auth::user()->id)
->where('created_at','>=', Carbon::now()->subMinutes(20))
->orderBy('created_at', 'desc')
->take(300)
->get()
->groupBy('rigname');
// Get the rig names
$rigs = (object) [];
foreach($stats as $key => $value) {
$rigs->$key = $key;
}
// For each rig, get the last known stats between now and 10 seconds ago
$table = (object) [];
foreach($rigs as $key => $value) {
$tableData = $stats[$value]
->where('created_at','>=', Carbon::now()->subSeconds(10));
if (isset($tableData[0]) && $tableData !== []) {
$table->$key = (object) $tableData[0];
$table->$key->data = json_decode($tableData[0]['data'], true);
}
}
return view('rigs', [
'rigs' => $table,
'chart' => $this->chart($stats)
]);
}
public function chart($data)
{
$p = [];
foreach($data as $key => $value) {
$x = [];
$time = [];
foreach($value as $k => $v) {
$time[] = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $v['created_at'])->format('H:i:s');
$x[] = json_decode($v['data'], true);
}
$hashrate = [];
foreach($x as $k => $v){
$hashrate[] = $v['hashrate'];
}
$p[$key] = [ 'time' => $time, 'hashrate' => $hashrate ];
}
$datasets = [];
$n = 0;
foreach($p as $key => $value) {
$colors = [
"0, 188, 212",
"244, 67, 54",
"255, 152, 0"
];
$datasets[] = $this->chartData('Hashrate: ' . $key, array_reverse($value['hashrate']), $colors[$n++]);
}
dd($time);
$chart = app()->chartjs
->name('lineChartTest')
->type('line')
->size(['width' => '100%', 'height' => '20%'])
->labels(array_reverse($time))
->datasets($datasets)
->optionsRaw("{
scales: {
yAxes: [{
display: true,
ticks: {
suggestedMin: 0, // minimum will be 0, unless there is a lower value.
beginAtZero: true // minimum value will be 0.
}
}]
}
}");
return $chart;
}
public function chartData($label, $data, $color)
{
return [
"label" => $label,
'backgroundColor' => "rgba(" . $color . ", 0)",
'borderColor' => "rgba(" . $color . ", 0.7)",
"pointBorderColor" => "rgba(" . $color . ", 0, 0.7)",
"pointBackgroundColor" => "rgba(" . $color . ", 0.7)",
"pointHoverBackgroundColor" => "#fff",
"pointHoverBorderColor" => "rgba(220,220,220,1)",
'data' => $data,
];
}
编辑:我找到了答案,请查看下方。
我制作了一个数组 $timeLabels
这个数组包含从当前时间到 x minutes/hours 之前的时间戳,间隔为 x 分钟。
然后我遍历我的装备并将 created_at 与 timeLabel 中的值进行比较。如果它在同一范围内(+/-10 秒),则集合中的数据将进入一个以 timeLabel 作为键的数组。当 timeLabel 没有值时,它会被分配为 0 作为数据。这确实有效,但需要一些调整。
完整示例:
<?php
namespace App\Http\Controllers\Rigs;
use Auth;
use Carbon\Carbon;
use App\MinerStatistics;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class RigController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the rigs dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
// Get the statistics from the database reported by the miner
// Group them by the rig name
$stats = MinerStatistics::where('user_id', Auth::user()->id)
->where('created_at','>=', Carbon::now()->subMinutes(60))
->orderBy('created_at', 'desc')
->take(300)
->get()
->groupBy('rigname');
// Get the rig names
$rigs = (object) [];
foreach($stats as $key => $value) {
$rigs->$key = $key;
}
// For each rig, get the last known stats between now and 10 seconds ago
$table = (object) [];
foreach($rigs as $key => $value) {
$tableData = $stats[$value]
->where('created_at','>=', Carbon::now()->subSeconds(10));
if (isset($tableData[0]) && $tableData !== []) {
$table->$key = (object) $tableData[0];
$table->$key->data = json_decode($tableData[0]['data'], true);
}
}
return view('rigs', [
'rigs' => $table,
'chart' => $this->chart($stats)
]);
}
public function chart($data)
{
$start = Carbon::now('Europe/Brussels');
$end = Carbon::now('Europe/Brussels')->subMinutes(60);
$timeLabels = $this->createTimeRange($end, $start);
$chartData = (object) [];
// Go over each returned rig
foreach($data as $key => $value) {
$arr = array(); // Create an empty array to store our results
// Go over all our timeLabels
foreach(array_reverse($timeLabels) as $t => $time) {
// Create a range to match the incomming created_at and timeLabels
// Needs finetuning!!
$start = Carbon::createFromFormat('H:i', $time)->subSeconds(30)->format('H:i:s');
$end = Carbon::createFromFormat('H:i', $time)->addSeconds(30)->format('H:i:s');
foreach ($value as $k => $v) {
// Transform created_at to the same format as $start and $end
$created = Carbon::createFromFormat('Y-m-d H:i:s', $v['created_at'])->format('H:i:s');
if($created >= $start && $created <= $end) {
if(!isset($v->data['hashrate'])){
$hashrate_ = json_decode($v->data,true)['hashrate'];
} else {
$hashrate_ = $v->data['hashrate'];
}
$arr[$time] = $hashrate_;
}
}
// If the set timeLabel has no value set to 0
// Rig is not running...
if (!isset($arr[$time])) {
$arr[$time] = '0';
}
}
$chartData->$key = $arr;
}
$datasets = [];
$n = 0;
foreach($chartData as $key => $value) {
$data = [];
foreach ($value as $k => $v) {
$data[] = $v;
}
$colors = [
"0, 188, 212",
"244, 67, 54",
"255, 152, 0"
];
$datasets[] = $this->chartData('Hashrate: ' . $key, array_reverse($data), $colors[$n++]);
}
$chart = app()->chartjs
->name('lineChartTest')
->type('line')
->size(['width' => '100%', 'height' => '20%'])
->labels($timeLabels)
->datasets($datasets)
->optionsRaw("{
scales: {
yAxes: [{
display: true,
ticks: {
suggestedMin: 0, // minimum will be 0, unless there is a lower value.
beginAtZero: true // minimum value will be 0.
}
}]
}
}");
return $chart;
}
public function chartData($label, $data, $color)
{
return [
"label" => $label,
'backgroundColor' => "rgba(" . $color . ", 0)",
'borderColor' => "rgba(" . $color . ", 0.7)",
"pointBorderColor" => "rgba(" . $color . ", 0, 0.7)",
"pointBackgroundColor" => "rgba(" . $color . ", 0.7)",
"pointHoverBackgroundColor" => "#fff",
"pointHoverBorderColor" => "rgba(220,220,220,1)",
'data' => $data,
];
}
private function createTimeRange($start, $end, $interval = '5 mins', $format = '24') {
$startTime = strtotime($start);
$endTime = strtotime($end);
$returnTimeFormat = ($format == '12')?'g:i A':'G:i';
$current = time();
$addTime = strtotime('+'.$interval, $current);
$diff = $addTime - $current;
$times = array();
while ($startTime < $endTime) {
$times[] = date($returnTimeFormat, $startTime);
$startTime += $diff;
}
$times[] = date($returnTimeFormat, $startTime);
return $times;
}
}
如果我这样做,我可以创建一个专用的 class,这样我就可以重用这个逻辑。我返回并传递给图表的数据现在格式如下:(正是我需要的)
{#3436 ▼
+"home": array:13 [▼
"17:47" => 13.44
"17:42" => 13.417
"17:37" => 13.439
"17:32" => 13.436
"17:27" => 13.438
"17:22" => "0"
"17:17" => "0"
"17:12" => "0"
"17:07" => "0"
"17:02" => "0"
"16:57" => "0"
"16:52" => "0"
"16:47" => "0"
]
+"server": array:13 [▼
"17:47" => "0"
"17:42" => 76.373
"17:37" => 76.514
"17:32" => 76.565
"17:27" => 76.486
"17:22" => "0"
"17:17" => "0"
"17:12" => "0"
"17:07" => "0"
"17:02" => "0"
"16:57" => "0"
"16:52" => "0"
"16:47" => "0"
]
}
我正在尝试根据数据库 return 编辑的数据创建图表。数据存储在数据库中,此 table 中可以有多个图表。由唯一值标识。 (钻机名称)
array:102 [▼
0 => array:6 [▼
"id" => 2002
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.364,"pool":"eu1.ethermine.org:4444","shares":{"valid":"2","invalid":"0"},"gpus":[{"temperature":"56","fanSpeed":"56","hashrates":12.364}]}"
"created_at" => "2018-02-23 10:24:50"
"updated_at" => "2018-02-23 10:24:50"
],
1 => array:6 [▼
"id" => 2019
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.612,"pool":"eu1.ethermine.org:4444","shares":{"valid":"736","invalid":"2"},"gpus":[{"temperature":"65","fanSpeed":"67","hashrates":19.804},{"temp ▶"
"created_at" => "2018-02-23 10:25:56"
"updated_at" => "2018-02-23 10:25:56"
]
如您所见,根据 rigname 有两种可能的图表。我想在图表上显示两个钻机的哈希值。这可行,但是,当一个钻机停止时,没有数据从该钻机提交到数据库。 图表显示该装备没有 0 值,正在使用最后已知的数据。 (呃)
我通过修改我的查询解决了这个问题:
$res[$value] = json_decode(MinerStatistics::where('rigname', $value)
->where('created_at','>=', \Carbon\Carbon::now()->subMinutes(20))
->orderBy('created_at', 'desc')
->get()
->toJson(), true
);
现在,当钻机停止并查询数据库时,我只能得到过去 x 分钟的数据。这是在 foreach 中完成的,它构建了一个新的多维数组,其中的数据按钻井名称排序。
这引发了一个新问题,当我重新启动钻机并开始向数据库报告时。图表上的值不在当前时间戳继续,它们在钻机停止的地方继续。通常我会在每次 运行 钻机报告时将上次报告数据和之前报告数据的时间戳与仍然是 运行 和 return 0 的钻机数据进行比较,但是他们报告不同的时间戳(都在 8 秒内)
如何修改 returned mysql 数据,最终得到如下结果:
array:2 [▼
"home" => array:150 [
0 => array:6 [▼
"id" => 2300
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.359,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.359}]}"
"created_at" => "2018-02-23 10:44:42"
"updated_at" => "2018-02-23 10:44:42"
]
1 => array:6 [▼
"id" => 2298
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.367,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.367}]}"
"created_at" => "2018-02-23 10:44:34"
"updated_at" => "2018-02-23 10:44:34"
]
2 => array:6 [▼
"id" => 2296
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.367,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.367}]}"
"created_at" => "2018-02-23 10:44:26"
"updated_at" => "2018-02-23 10:44:26"
]
...
Server stops, no data, should continue like this
3 => [false] ,
4 => [false] ,
5 => [false]
...
rig reports again to the database
36 => array:6 [▼
"id" => 2296
"user_id" => "1"
"rigname" => "home"
"data" => "{"hashrate":12.367,"pool":"eu1.ethermine.org:4444","shares":{"valid":"5","invalid":"0"},"gpus":[{"temperature":"57","fanSpeed":"57","hashrates":12.367}]}"
"created_at" => "2018-02-23 10:44:26"
"updated_at" => "2018-02-23 10:44:26"
],
],
"server" => array:150 [▼ // This keeps running, or visa versa
0 => array:6 [▼
"id" => 2301
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.62,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"67","hashrates":19.778},{"tempe ▶"
"created_at" => "2018-02-23 10:44:44"
"updated_at" => "2018-02-23 10:44:44"
]
1 => array:6 [▼
"id" => 2299
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.68,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.815},{"tempe ▶"
"created_at" => "2018-02-23 10:44:36"
"updated_at" => "2018-02-23 10:44:36"
]
2 => array:6 [▼
"id" => 2297
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.644,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.793},{"temp ▶"
"created_at" => "2018-02-23 10:44:28"
"updated_at" => "2018-02-23 10:44:28"
]
3 => array:6 [▼
"id" => 2295
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.105,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.793},{"temp ▶"
"created_at" => "2018-02-23 10:44:20"
"updated_at" => "2018-02-23 10:44:20"
]
4 => array:6 [▼
"id" => 2293
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.557,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.78},{"tempe ▶"
"created_at" => "2018-02-23 10:44:12"
"updated_at" => "2018-02-23 10:44:12"
]
5 => array:6 [▼
"id" => 2291
"user_id" => "1"
"rigname" => "server"
"data" => "{"hashrate":76.562,"pool":"eu1.ethermine.org:4444","shares":{"valid":"749","invalid":"2"},"gpus":[{"temperature":"64","fanSpeed":"65","hashrates":19.794},{"temp ▶"
"created_at" => "2018-02-23 10:44:04"
"updated_at" => "2018-02-23 10:44:04"
]
]
]
目前我写的代码:
public function index()
{
// Get the statistics from the database reported by the miner
// Group them by the rig name
$stats = MinerStatistics::where('user_id', Auth::user()->id)
->where('created_at','>=', Carbon::now()->subMinutes(20))
->orderBy('created_at', 'desc')
->take(300)
->get()
->groupBy('rigname');
// Get the rig names
$rigs = (object) [];
foreach($stats as $key => $value) {
$rigs->$key = $key;
}
// For each rig, get the last known stats between now and 10 seconds ago
$table = (object) [];
foreach($rigs as $key => $value) {
$tableData = $stats[$value]
->where('created_at','>=', Carbon::now()->subSeconds(10));
if (isset($tableData[0]) && $tableData !== []) {
$table->$key = (object) $tableData[0];
$table->$key->data = json_decode($tableData[0]['data'], true);
}
}
return view('rigs', [
'rigs' => $table,
'chart' => $this->chart($stats)
]);
}
public function chart($data)
{
$p = [];
foreach($data as $key => $value) {
$x = [];
$time = [];
foreach($value as $k => $v) {
$time[] = \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $v['created_at'])->format('H:i:s');
$x[] = json_decode($v['data'], true);
}
$hashrate = [];
foreach($x as $k => $v){
$hashrate[] = $v['hashrate'];
}
$p[$key] = [ 'time' => $time, 'hashrate' => $hashrate ];
}
$datasets = [];
$n = 0;
foreach($p as $key => $value) {
$colors = [
"0, 188, 212",
"244, 67, 54",
"255, 152, 0"
];
$datasets[] = $this->chartData('Hashrate: ' . $key, array_reverse($value['hashrate']), $colors[$n++]);
}
dd($time);
$chart = app()->chartjs
->name('lineChartTest')
->type('line')
->size(['width' => '100%', 'height' => '20%'])
->labels(array_reverse($time))
->datasets($datasets)
->optionsRaw("{
scales: {
yAxes: [{
display: true,
ticks: {
suggestedMin: 0, // minimum will be 0, unless there is a lower value.
beginAtZero: true // minimum value will be 0.
}
}]
}
}");
return $chart;
}
public function chartData($label, $data, $color)
{
return [
"label" => $label,
'backgroundColor' => "rgba(" . $color . ", 0)",
'borderColor' => "rgba(" . $color . ", 0.7)",
"pointBorderColor" => "rgba(" . $color . ", 0, 0.7)",
"pointBackgroundColor" => "rgba(" . $color . ", 0.7)",
"pointHoverBackgroundColor" => "#fff",
"pointHoverBorderColor" => "rgba(220,220,220,1)",
'data' => $data,
];
}
编辑:我找到了答案,请查看下方。
我制作了一个数组 $timeLabels
这个数组包含从当前时间到 x minutes/hours 之前的时间戳,间隔为 x 分钟。
然后我遍历我的装备并将 created_at 与 timeLabel 中的值进行比较。如果它在同一范围内(+/-10 秒),则集合中的数据将进入一个以 timeLabel 作为键的数组。当 timeLabel 没有值时,它会被分配为 0 作为数据。这确实有效,但需要一些调整。
完整示例:
<?php
namespace App\Http\Controllers\Rigs;
use Auth;
use Carbon\Carbon;
use App\MinerStatistics;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class RigController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the rigs dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
// Get the statistics from the database reported by the miner
// Group them by the rig name
$stats = MinerStatistics::where('user_id', Auth::user()->id)
->where('created_at','>=', Carbon::now()->subMinutes(60))
->orderBy('created_at', 'desc')
->take(300)
->get()
->groupBy('rigname');
// Get the rig names
$rigs = (object) [];
foreach($stats as $key => $value) {
$rigs->$key = $key;
}
// For each rig, get the last known stats between now and 10 seconds ago
$table = (object) [];
foreach($rigs as $key => $value) {
$tableData = $stats[$value]
->where('created_at','>=', Carbon::now()->subSeconds(10));
if (isset($tableData[0]) && $tableData !== []) {
$table->$key = (object) $tableData[0];
$table->$key->data = json_decode($tableData[0]['data'], true);
}
}
return view('rigs', [
'rigs' => $table,
'chart' => $this->chart($stats)
]);
}
public function chart($data)
{
$start = Carbon::now('Europe/Brussels');
$end = Carbon::now('Europe/Brussels')->subMinutes(60);
$timeLabels = $this->createTimeRange($end, $start);
$chartData = (object) [];
// Go over each returned rig
foreach($data as $key => $value) {
$arr = array(); // Create an empty array to store our results
// Go over all our timeLabels
foreach(array_reverse($timeLabels) as $t => $time) {
// Create a range to match the incomming created_at and timeLabels
// Needs finetuning!!
$start = Carbon::createFromFormat('H:i', $time)->subSeconds(30)->format('H:i:s');
$end = Carbon::createFromFormat('H:i', $time)->addSeconds(30)->format('H:i:s');
foreach ($value as $k => $v) {
// Transform created_at to the same format as $start and $end
$created = Carbon::createFromFormat('Y-m-d H:i:s', $v['created_at'])->format('H:i:s');
if($created >= $start && $created <= $end) {
if(!isset($v->data['hashrate'])){
$hashrate_ = json_decode($v->data,true)['hashrate'];
} else {
$hashrate_ = $v->data['hashrate'];
}
$arr[$time] = $hashrate_;
}
}
// If the set timeLabel has no value set to 0
// Rig is not running...
if (!isset($arr[$time])) {
$arr[$time] = '0';
}
}
$chartData->$key = $arr;
}
$datasets = [];
$n = 0;
foreach($chartData as $key => $value) {
$data = [];
foreach ($value as $k => $v) {
$data[] = $v;
}
$colors = [
"0, 188, 212",
"244, 67, 54",
"255, 152, 0"
];
$datasets[] = $this->chartData('Hashrate: ' . $key, array_reverse($data), $colors[$n++]);
}
$chart = app()->chartjs
->name('lineChartTest')
->type('line')
->size(['width' => '100%', 'height' => '20%'])
->labels($timeLabels)
->datasets($datasets)
->optionsRaw("{
scales: {
yAxes: [{
display: true,
ticks: {
suggestedMin: 0, // minimum will be 0, unless there is a lower value.
beginAtZero: true // minimum value will be 0.
}
}]
}
}");
return $chart;
}
public function chartData($label, $data, $color)
{
return [
"label" => $label,
'backgroundColor' => "rgba(" . $color . ", 0)",
'borderColor' => "rgba(" . $color . ", 0.7)",
"pointBorderColor" => "rgba(" . $color . ", 0, 0.7)",
"pointBackgroundColor" => "rgba(" . $color . ", 0.7)",
"pointHoverBackgroundColor" => "#fff",
"pointHoverBorderColor" => "rgba(220,220,220,1)",
'data' => $data,
];
}
private function createTimeRange($start, $end, $interval = '5 mins', $format = '24') {
$startTime = strtotime($start);
$endTime = strtotime($end);
$returnTimeFormat = ($format == '12')?'g:i A':'G:i';
$current = time();
$addTime = strtotime('+'.$interval, $current);
$diff = $addTime - $current;
$times = array();
while ($startTime < $endTime) {
$times[] = date($returnTimeFormat, $startTime);
$startTime += $diff;
}
$times[] = date($returnTimeFormat, $startTime);
return $times;
}
}
如果我这样做,我可以创建一个专用的 class,这样我就可以重用这个逻辑。我返回并传递给图表的数据现在格式如下:(正是我需要的)
{#3436 ▼
+"home": array:13 [▼
"17:47" => 13.44
"17:42" => 13.417
"17:37" => 13.439
"17:32" => 13.436
"17:27" => 13.438
"17:22" => "0"
"17:17" => "0"
"17:12" => "0"
"17:07" => "0"
"17:02" => "0"
"16:57" => "0"
"16:52" => "0"
"16:47" => "0"
]
+"server": array:13 [▼
"17:47" => "0"
"17:42" => 76.373
"17:37" => 76.514
"17:32" => 76.565
"17:27" => 76.486
"17:22" => "0"
"17:17" => "0"
"17:12" => "0"
"17:07" => "0"
"17:02" => "0"
"16:57" => "0"
"16:52" => "0"
"16:47" => "0"
]
}