Major update
This commit is contained in:
parent
794b91088a
commit
b4b06eacf8
44
app/Console/Commands/GenerateNuke.php
Normal file
44
app/Console/Commands/GenerateNuke.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\MatsuriHime\Election;
|
||||||
|
|
||||||
|
class GenerateNuke extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'tcvis:generatenuke';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Create Nuke Data';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
Election::generateNukeData();
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,6 @@ class Kernel extends ConsoleKernel
|
|||||||
$schedule->call(function() {
|
$schedule->call(function() {
|
||||||
\App\MatsuriHime\Election::createSnapshot();
|
\App\MatsuriHime\Election::createSnapshot();
|
||||||
})->everyMinute();
|
})->everyMinute();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,23 +16,57 @@ class HomeController extends Controller
|
|||||||
public function getIdolDB() {
|
public function getIdolDB() {
|
||||||
return json_decode(Storage::get('idols.json'));
|
return json_decode(Storage::get('idols.json'));
|
||||||
}
|
}
|
||||||
|
public function getIdolColor($idol) {
|
||||||
|
$idolColors = $this->getIdolColors();
|
||||||
|
return $idolColors[explode("\n",$idol)[0]];
|
||||||
|
}
|
||||||
public function getIdolColors(){
|
public function getIdolColors(){
|
||||||
|
if(!Cache::get('idol_colors')) {
|
||||||
$colors = [];
|
$colors = [];
|
||||||
$idolDB = collect($this->getIdolDB()->idols);
|
$idolDB = collect($this->getIdolDB()->idols);
|
||||||
foreach($idolDB as $idol) {
|
foreach($idolDB as $idol) {
|
||||||
$colors[$idol->name->kanji->value] = $idol->color;
|
$colors[$idol->name->kanji->value] = $idol->color;
|
||||||
}
|
}
|
||||||
// dd($colors);
|
Cache::forever('idol_colors',$colors);
|
||||||
|
}
|
||||||
return $colors;
|
// return $colors;
|
||||||
|
return Cache::get('idol_colors');
|
||||||
}
|
}
|
||||||
public function statistics(Request $request) {
|
public function statistics(Request $request) {
|
||||||
$dataPoints = Rank::count();
|
$dataPoints = Rank::count();
|
||||||
return view('statistics',['data_points' => $dataPoints]);
|
return view('statistics',['data_points' => $dataPoints]);
|
||||||
|
}
|
||||||
|
public function nukes(Request $request) {
|
||||||
|
$nukes = Cache::get('nukes');
|
||||||
|
return view('nukes',["nukes" => $nukes]);
|
||||||
|
}
|
||||||
|
public function newChart($timelabels,$roleName,$request,$amount,$dramaNames,$colors,$enlarge = false) {
|
||||||
|
$chart = new RankChart;
|
||||||
|
$height = 400;
|
||||||
|
if($enlarge) $height = 1000;
|
||||||
|
$options = [
|
||||||
|
'axisOptions' => [
|
||||||
|
'xIsSeries' => true,
|
||||||
|
'xAxisMode' => 'tick'
|
||||||
|
],
|
||||||
|
'lineOptions' => [
|
||||||
|
'regionFill' => true,
|
||||||
|
],
|
||||||
|
'title' => $roleName.' ('.($roleName == 'global' ? 'Global' : $dramaNames[$roleName]).')',
|
||||||
|
'colors' => $colors,
|
||||||
|
'height' => $height,
|
||||||
|
];
|
||||||
|
$chart->options($options);
|
||||||
|
$chart->isNavigable(true);
|
||||||
|
$chart->labels($timelabels->toArray());
|
||||||
|
$chart->hideDots(true);
|
||||||
|
$api = url('/api/chart/'.$roleName."?date_since=".$request->date_since.'&since='.$request->since.'&take='.$request->take);
|
||||||
|
$chart->load($api);
|
||||||
|
return $chart;
|
||||||
}
|
}
|
||||||
public function home(Request $request) {
|
public function home(Request $request) {
|
||||||
$minutes = $request->since ?? 60*24*90;
|
$idolColors = $this->getIdolColors();
|
||||||
|
$minutes = $request->since ?? 60*24;
|
||||||
$timepoints = Cache::get('timepoints');
|
$timepoints = Cache::get('timepoints');
|
||||||
$requested_date = $request->date_since;
|
$requested_date = $request->date_since;
|
||||||
if($requested_date) {
|
if($requested_date) {
|
||||||
@ -45,51 +79,100 @@ class HomeController extends Controller
|
|||||||
return $item->gte(Carbon::now()->addHours(9)->subMinutes($minutes+5));
|
return $item->gte(Carbon::now()->addHours(9)->subMinutes($minutes+5));
|
||||||
});
|
});
|
||||||
$take = $timepoints->count();
|
$take = $timepoints->count();
|
||||||
$idolColors = $this->getIdolColors();
|
|
||||||
$dramaNames = Election::getDramaNames();
|
$dramaNames = Election::getDramaNames();
|
||||||
$ranks = Rank::all()->groupBy('role');
|
$ranks = collect($dramaNames)->keys();
|
||||||
$charts = [];
|
$charts = [];
|
||||||
$timelabels = [];
|
$timelabels = Cache::get('timelabels');
|
||||||
foreach($timepoints as $timepoint) {
|
$timelabels = $timelabels->take(-$take)->values();
|
||||||
$timelabels[] = $timepoint->toDateTimeString();
|
|
||||||
}
|
|
||||||
$timelabels = collect($timelabels);
|
|
||||||
$timelabels = $timelabels->splice(count($timelabels) - $take);
|
|
||||||
if($request->take) $timelabels = $timelabels->take($request->take);
|
if($request->take) $timelabels = $timelabels->take($request->take);
|
||||||
foreach($ranks as $roleName => $roleRank) {
|
foreach($ranks as $roleName) {
|
||||||
$chartPoint = Cache::get('data_'.$roleName);
|
$chartPoint = null;
|
||||||
// dd($chartPoint);
|
$chartPoint = collect(Cache::get('data_'.$roleName))->keys();
|
||||||
if(!isset($chartPoint)) {
|
$colors = [];
|
||||||
\App\MatsuriHime\Election::createSnapshot();
|
foreach($chartPoint as $point) {
|
||||||
$chartPoint = Cache::get('data_'.$roleName);
|
$colors[] = $this->getIdolColor($point);
|
||||||
}
|
|
||||||
$chart = new RankChart;
|
|
||||||
$chart->options([
|
|
||||||
'axisOptions' => [
|
|
||||||
'xIsSeries' => true,
|
|
||||||
'xAxisMode' => 'tick'
|
|
||||||
],
|
|
||||||
'lineOptions' => [
|
|
||||||
'regionFill' => true
|
|
||||||
],
|
|
||||||
'title' => $roleName.' ('.$dramaNames[$roleName].')'
|
|
||||||
]);
|
|
||||||
$chart->isNavigable(true);
|
|
||||||
$chart->labels($timelabels->toArray());
|
|
||||||
$chart->hideDots(true);
|
|
||||||
foreach($chartPoint as $idol => $dataPoints) {
|
|
||||||
$values = collect($dataPoints);
|
|
||||||
$values = $values->splice(count($values) - $take);
|
|
||||||
if($request->take) $values = $values->take($request->take);
|
|
||||||
$idol_color = $idolColors[$idol];
|
|
||||||
$chart->dataSet($idol,'line',$values->toArray())->color($idol_color);
|
|
||||||
}
|
}
|
||||||
|
$chart =$this->newChart($timelabels,$roleName,$request,$request->take,$dramaNames,$colors,$request->enlarge);
|
||||||
$chartData["drama"] = $dramaNames[$roleName];
|
$chartData["drama"] = $dramaNames[$roleName];
|
||||||
$chartData["name"] = $roleName;
|
$chartData["name"] = $roleName;
|
||||||
$chartData["chart"] = $chart;
|
$chartData["chart"] = $chart;
|
||||||
$charts[] = $chartData;
|
$charts[] = $chartData;
|
||||||
}
|
}
|
||||||
return view('home', [ 'chart_groups' => collect($charts)->groupBy("drama"), 'since' => $request->since ]);
|
return view('home', [ 'chart_groups' => collect($charts)->groupBy("drama"), 'since' => $request->since, 'enlarge' => $request->enlarge , 'date_since' => $request->date_since, 'take' => $request->take]);
|
||||||
|
}
|
||||||
|
public function homeNew(Request $request) {
|
||||||
|
$idolColors = $this->getIdolColors();
|
||||||
|
$minutes = $request->since ?? 60*24;
|
||||||
|
$snap_time = Cache::get('snap_time');
|
||||||
|
$end_date = $snap_time->toDateTimeString();
|
||||||
|
$start_date = ( $request->date_since != "" ? $request->date_since : $snap_time->subMinutes($request->since ?? 24*60)->toDateTimeString());
|
||||||
|
$timerange = \App\MatsuriHime\Election::generateChartPointsDate($start_date,$end_date);
|
||||||
|
$timepoints = Cache::get('timepoints_'.$timerange);
|
||||||
|
$take = $timepoints->count();
|
||||||
|
$dramaNames = Election::getDramaNames();
|
||||||
|
$ranks = collect($dramaNames)->keys();
|
||||||
|
$charts = [];
|
||||||
|
$timelabels = Cache::get('timelabels_'.$timerange);
|
||||||
|
$timelabels = $timelabels->take(-$take)->values();
|
||||||
|
if($request->take) $timelabels = $timelabels->take($request->take);
|
||||||
|
foreach($ranks as $roleName) {
|
||||||
|
$chartPoint = null;
|
||||||
|
$chartPoint = collect(Cache::get('data_'.$roleName.'_'.$timerange))->keys();
|
||||||
|
$colors = [];
|
||||||
|
foreach($chartPoint as $point) {
|
||||||
|
$colors[] = $this->getIdolColor($point);
|
||||||
|
}
|
||||||
|
$chart =$this->newChart($timelabels,$roleName,$request,$request->take,$dramaNames,$colors,$request->enlarge);
|
||||||
|
$chartData["drama"] = $dramaNames[$roleName];
|
||||||
|
$chartData["name"] = $roleName;
|
||||||
|
$chartData["chart"] = $chart;
|
||||||
|
$charts[] = $chartData;
|
||||||
|
}
|
||||||
|
return view('home', [ 'chart_groups' => collect($charts)->groupBy("drama"), 'since' => $request->since, 'enlarge' => $request->enlarge , 'date_since' => $request->date_since, 'take' => $request->take]);
|
||||||
|
}
|
||||||
|
public function viewChart($chart_name, Request $request) {
|
||||||
|
$minutes = $request->since ?? 60*24;
|
||||||
|
$minutes = $request->since ?? 60*24;
|
||||||
|
$snap_time = Cache::get('snap_time');
|
||||||
|
$end_date = $snap_time->toDateTimeString(); $start_date = ( $request->date_since != "" ? $request->date_since : $snap_time->subMinutes($request->since ?? 24*60)->toDateTimeString());
|
||||||
|
$timerange = \App\MatsuriHime\Election::generateChartPointsDate($start_date,$end_date);
|
||||||
|
$timepoints = Cache::get('timepoints_'.$timerange);
|
||||||
|
$take = $timepoints->count();
|
||||||
|
$idolColors = $this->getIdolColors();
|
||||||
|
$dramaNames = Election::getDramaNames();
|
||||||
|
$charts = [];
|
||||||
|
$timelabels = Cache::get('timelabels_'.$timerange);
|
||||||
|
$timelabels = $timelabels->take(-$take)->values();
|
||||||
|
if($request->take) $timelabels = $timelabels->take($request->take);
|
||||||
|
$roleName = $chart_name;
|
||||||
|
$roleRank = "Global";
|
||||||
|
$chartPoint = collect(Cache::get('data_'.$roleName.'_'.$timerange))->keys();
|
||||||
|
$colors = [];
|
||||||
|
foreach($chartPoint as $point) {
|
||||||
|
$colors[] = $this->getIdolColor($point);
|
||||||
|
}
|
||||||
|
$chart =$this->newChart($timelabels,$roleName,$request,$request->take,$dramaNames,$colors,$request->enlarge);
|
||||||
|
$chartData["drama"] = ($roleName == 'global' ? 'Global' : $dramaNames[$roleName]);
|
||||||
|
$chartData["name"] = $roleName;
|
||||||
|
$chartData["chart"] = $chart;
|
||||||
|
$charts[] = $chartData;
|
||||||
|
return view('home', [ 'chart_groups' => collect($charts)->groupBy("drama"), 'since' => $request->since, 'enlarge' => $request->enlarge , 'date_since' => $request->date_since, 'take' => $request->take, 'chart_name' => $chart_name]);
|
||||||
|
}
|
||||||
|
public function viewChartApi($chart_name, Request $request) {
|
||||||
|
$snap_time = Cache::get('snap_time');
|
||||||
|
$end_date = $snap_time->toDateTimeString();
|
||||||
|
$start_date = ( $request->date_since != "" ? $request->date_since : $snap_time->subMinutes($request->since ?? 24*60)->toDateTimeString());
|
||||||
|
$timerange = \App\MatsuriHime\Election::generateChartPointsDate($start_date,$end_date);
|
||||||
|
$take = $request->since;
|
||||||
|
$roleName = $chart_name;
|
||||||
|
$chartPoint = Cache::get('data_'.$roleName.'_'.$timerange);
|
||||||
|
$chart = new RankChart;
|
||||||
|
foreach($chartPoint as $idol => $dataPoints) {
|
||||||
|
$values = $dataPoints;
|
||||||
|
if($request->take) $values = $dataPoints->take($request->take)->values();
|
||||||
|
$chart->dataSet($idol,'line',$values->toArray());
|
||||||
|
}
|
||||||
|
return $chart->api();
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use App\Rank;
|
|||||||
|
|
||||||
class Election
|
class Election
|
||||||
{
|
{
|
||||||
|
public const nuke_threshold = 2500;
|
||||||
public static function getDramaNames() {
|
public static function getDramaNames() {
|
||||||
if(!Cache::has('drama_names')) {
|
if(!Cache::has('drama_names')) {
|
||||||
$response = Guzzle::get("https://api.matsurihi.me/mltd/v1/election")->getBody()->getContents();
|
$response = Guzzle::get("https://api.matsurihi.me/mltd/v1/election")->getBody()->getContents();
|
||||||
@ -35,8 +36,9 @@ class Election
|
|||||||
$hasSnapshot = true;
|
$hasSnapshot = true;
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
foreach($rankings as $ladder) {
|
foreach($rankings as $ladder) {
|
||||||
$existingSnapshot = Rank::where('role',$ladder->name)->where('summary_time',Carbon::parse($ladder->summaryTime))->count();
|
$existingSnapshot = Cache::get('snap_time_'.$ladder->name);
|
||||||
if($existingSnapshot == 0) {
|
if(!isset($existingSnapshot) || $existingSnapshot->lt(Carbon::parse($ladder->summaryTime)) ) {
|
||||||
|
$hasSnapshot = false;
|
||||||
$idols = [];
|
$idols = [];
|
||||||
foreach($ladder->data[0] as $data) {
|
foreach($ladder->data[0] as $data) {
|
||||||
$rank = new Rank();
|
$rank = new Rank();
|
||||||
@ -55,49 +57,169 @@ class Election
|
|||||||
$rank->score = $remnant->first()->score;
|
$rank->score = $remnant->first()->score;
|
||||||
$rank->summary_time = Carbon::parse($ladder->summaryTime);
|
$rank->summary_time = Carbon::parse($ladder->summaryTime);
|
||||||
$rank->save();
|
$rank->save();
|
||||||
\Log::error($remnant_char.' '.$remnant->first()->score);
|
|
||||||
}
|
}
|
||||||
|
Cache::forever('snap_time_'.$ladder->name,Carbon::parse($ladder->summaryTime));
|
||||||
|
Cache::forever('snap_time',Carbon::parse($ladder->summaryTime));
|
||||||
} else {
|
} else {
|
||||||
\Log::info("snapshot has been taken for " . (string)$ladder->summaryTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DB::commit();
|
DB::commit();
|
||||||
Election::generateChartPointsNew();
|
if(!$hasSnapshot) {
|
||||||
|
$snap_time = Cache::get('snap_time');
|
||||||
|
$end_date = $snap_time->toDateTimeString();
|
||||||
|
$start_date = $snap_time->subMinutes(24*60)->toDateTimeString();
|
||||||
|
Election::generateChartPointsDate($start_date,$end_date);
|
||||||
|
Election::incrementNukeData();
|
||||||
}
|
}
|
||||||
public static function generateChartPointsNew() {
|
}
|
||||||
$ranks = Rank::orderBy('summary_time')->get()->groupBy('role');
|
public static function generateChartPointsDate($start_date,$end_date) {
|
||||||
$timepoints = Rank::distinct('summary_time')->orderBy('summary_time')->pluck('summary_time');
|
if(Cache::has('timepoints_'.$start_date.'-'.$end_date)) return $start_date.'-'.$end_date;
|
||||||
Cache::forever('timepoints',$timepoints);
|
$ranks = Rank::where('summary_time','>=',$start_date)->where('summary_time','<=',$end_date)->orderBy('summary_time')->get();
|
||||||
|
$timepoints = $ranks->pluck('summary_time')->unique();
|
||||||
|
$ranks = $ranks->groupBy('role');
|
||||||
|
Cache::forever('timepoints_'.$start_date.'-'.$end_date,$timepoints);
|
||||||
|
$timelabels = [];
|
||||||
|
foreach($timepoints as $timepoint) {
|
||||||
|
$timelabels[] = $timepoint->toDateTimeString();
|
||||||
|
}
|
||||||
|
$timelabels = collect($timelabels);
|
||||||
|
Cache::forever('timelabels_'.$start_date.'-'.$end_date,$timelabels);
|
||||||
|
$timepoints_count = $timepoints->count();
|
||||||
|
$globalDataPoints = [];
|
||||||
foreach($ranks as $roleName => $roleRank) {
|
foreach($ranks as $roleName => $roleRank) {
|
||||||
$dataPoints = [];
|
$dataPoints = [];
|
||||||
$ladder = $roleRank->sortBy('summary_time')->groupBy('character')->sortByDesc(function($rank,$key) {
|
$ladder = $roleRank->groupBy('character')->sortByDesc(function($rank,$key) {
|
||||||
return $rank->last()->score;
|
return $rank->last()->score;
|
||||||
});
|
});
|
||||||
foreach($ladder as $character => $rank) {
|
foreach($ladder as $character => $rank) {
|
||||||
$standing = $rank;
|
$standing = $rank->pluck('score')->take($timepoints_count)->values();
|
||||||
|
$standing = $standing->pad(-$timepoints_count,(int)0)->values();
|
||||||
$standing = $standing->pad(-$timepoints->count(),(int)0);
|
$dataPoints[$character] = $standing;
|
||||||
$dataPoints[$character] = $standing->pluck('score');
|
if(!array_key_exists($character,$globalDataPoints)) $globalDataPoints[$character] = $standing->values();
|
||||||
|
else {
|
||||||
|
$scores = $standing->values();
|
||||||
|
\Log::error($globalDataPoints[$character]->count().' vs '.$standing->count().' the jury is '.$timepoints_count);
|
||||||
|
$globalDataPoints[$character]->transform(function($item,$index) use ($scores) {
|
||||||
|
return $item+$scores[$index];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
$dataPoints = collect($dataPoints)->take(10);
|
||||||
|
Cache::forever('data_'.$roleName.'_'.$start_date.'-'.$end_date,$dataPoints);
|
||||||
|
}
|
||||||
|
$globalDataPoints = collect($globalDataPoints);
|
||||||
|
$globalDataPoints = $globalDataPoints->sortByDesc(function($item, $key) {
|
||||||
|
return $item->last();
|
||||||
|
});
|
||||||
|
$globalDataPoints = $globalDataPoints->take(10);
|
||||||
|
Cache::forever('data_global_'.$start_date.'-'.$end_date,$globalDataPoints);
|
||||||
|
return $start_date.'-'.$end_date;
|
||||||
|
}
|
||||||
|
public static function generateChartPointsNew() {
|
||||||
|
$ranks = Rank::orderBy('summary_time')->get();
|
||||||
|
$timepoints = $ranks->pluck('summary_time')->unique();
|
||||||
|
$ranks = $ranks->groupBy('role');
|
||||||
|
Cache::forever('timepoints',$timepoints);
|
||||||
|
$timelabels = [];
|
||||||
|
foreach($timepoints as $timepoint) {
|
||||||
|
$timelabels[] = $timepoint->toDateTimeString();
|
||||||
|
}
|
||||||
|
$timelabels = collect($timelabels);
|
||||||
|
Cache::forever('timelabels',$timelabels);
|
||||||
|
$timepoints_count = $timepoints->count();
|
||||||
|
$globalDataPoints = [];
|
||||||
|
foreach($ranks as $roleName => $roleRank) {
|
||||||
|
$dataPoints = [];
|
||||||
|
$ladder = $roleRank->groupBy('character')->sortByDesc(function($rank,$key) {
|
||||||
|
return $rank->last()->score;
|
||||||
|
});
|
||||||
|
foreach($ladder as $character => $rank) {
|
||||||
|
$standing = $rank->pluck('score');
|
||||||
|
$standing = $standing->pad(-$timepoints_count,(int)0);
|
||||||
|
$dataPoints[$character] = $standing;
|
||||||
|
if(!array_key_exists($character,$globalDataPoints)) $globalDataPoints[$character] = $standing->pluck('score');
|
||||||
|
else {
|
||||||
|
$scores = $standing->pluck('score');
|
||||||
|
$globalDataPoints[$character]->transform(function($item,$index) use ($scores) {
|
||||||
|
return $item+$scores[$index];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dataPoints = collect($dataPoints)->take(10);
|
||||||
Cache::forever('data_'.$roleName,$dataPoints);
|
Cache::forever('data_'.$roleName,$dataPoints);
|
||||||
}
|
}
|
||||||
|
$globalDataPoints = collect($globalDataPoints);
|
||||||
|
$globalDataPoints = $globalDataPoints->sortByDesc(function($item, $key) {
|
||||||
|
return $item->last();
|
||||||
|
});
|
||||||
|
$globalDataPoints = $globalDataPoints->take(10);
|
||||||
|
Cache::forever('data_global',$globalDataPoints);
|
||||||
}
|
}
|
||||||
public static function generateChartPoints() {
|
public static function incrementNukeData() {
|
||||||
$ranks = Rank::all()->groupBy('role');
|
$nukes = Cache::get('nukes');
|
||||||
foreach($ranks as $roleName => $roleRank) {
|
$dramaNames = Election::getDramaNames();
|
||||||
$chartPoint = [];
|
$ranks = collect(Cache::get('drama_names'))->keys();
|
||||||
$idols = $roleRank->unique('character')->pluck('character');
|
$firstPoint = Cache::get('snap_time');
|
||||||
$timepoints = $roleRank->sortBy('summary_time')->unique('summary_time')->pluck('summary_time');
|
foreach($ranks as $role) {
|
||||||
foreach($idols as $idol) {
|
$ladder = Rank::where('role',$role)->orderBy('summary_time','desc')->get()->groupBy('character')->take(2);
|
||||||
foreach($timepoints as $timepoint) {
|
foreach($ladder as $character => $points) {
|
||||||
$chartPoint[$idol][$timepoint->toDateTimeString()] = 0;
|
$future_point = $points[0];
|
||||||
}
|
$point = $points[1] ?? null;
|
||||||
foreach($roleRank->where('character',$idol) as $point) {
|
$future_point_score = $future_point->score;
|
||||||
$chartPoint[$idol][$point->summary_time->toDateTimeString()] = $point->score;
|
$point_score = 0;
|
||||||
|
if($point) {
|
||||||
|
$point_score = $point->score;
|
||||||
|
if($future_point_score - $point_score >= Election::nuke_threshold) {
|
||||||
|
\Log::error($role.$character.$point->summary_time);
|
||||||
|
$nuke = [
|
||||||
|
'code' => $role.$character.$point->summary_time,
|
||||||
|
'drama' => $dramaNames[$role],
|
||||||
|
'role' => $role,
|
||||||
|
'character' => $character,
|
||||||
|
'nuke_time_start' => $point->summary_time,
|
||||||
|
'nuke_time_end' => $future_point->summary_time,
|
||||||
|
'nuke_pts' => $future_point_score - $point_score,
|
||||||
|
];
|
||||||
|
$nukes[] = $nuke;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Cache::forever('chart_point_'.$roleName,$chartPoint);
|
}
|
||||||
}
|
}
|
||||||
|
$collect = collect($nukes)->sortBy('nuke_time_start')->reverse();
|
||||||
|
Cache::forever('nukes',$collect);
|
||||||
|
}
|
||||||
|
public static function generateNukeData() {
|
||||||
|
$dramaNames = Election::getDramaNames();
|
||||||
|
$nukes = [];
|
||||||
|
$ranks = Rank::orderBy('summary_time')->get()->groupBy('role');
|
||||||
|
$firstPoint = $ranks->first()->first()->summary_time;
|
||||||
|
foreach($ranks as $role => $ladder) {
|
||||||
|
$ladder = $ladder->groupBy('character');
|
||||||
|
foreach($ladder as $character => $points) {
|
||||||
|
$count = $points->count();
|
||||||
|
foreach($points as $index => $future_point) {
|
||||||
|
$point = null;
|
||||||
|
if(($index-1) >= 0) $point = $points[$index-1];
|
||||||
|
if(isset($future_point)) {
|
||||||
|
$future_point_score = $future_point->score;
|
||||||
|
$point_score = $point->score ?? 0;
|
||||||
|
if($future_point_score - $point_score >= Election::nuke_threshold && !$future_point->summary_time->eq($firstPoint)) {
|
||||||
|
\Log::error($role.$character.($point ? $point->summary_time : $future_point->summary_time->subMinutes(5)));
|
||||||
|
$nuke = [
|
||||||
|
'code' => $role.$character.$future_point->summary_time,
|
||||||
|
'role' => $role,
|
||||||
|
'drama' => $dramaNames[$role],
|
||||||
|
'character' => $character,
|
||||||
|
'nuke_time_start' => ($point ? $point->summary_time : $future_point->summary_time->subMinutes(5)),
|
||||||
|
'nuke_time_end' => $future_point->summary_time,
|
||||||
|
'nuke_pts' => $future_point_score - $point_score,
|
||||||
|
];
|
||||||
|
$nukes[] = $nuke;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cache::forever('nukes',collect($nukes)->sortBy('nuke_time_start')->reverse());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,16 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">Settings</div>
|
<div class="card-header">Settings</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form action="{{ url()->current() }}" method="GET">
|
<form action="{{ url()->current() }}" method="GET" id="settings-form">
|
||||||
|
@if(isset($since) || isset($date_since))
|
||||||
|
<div class="form-group">
|
||||||
|
<a href="{{ url()->current() }}">Reset</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if(!isset($date_since))
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="show-last">Show last:</label>
|
<label for="show-last">Show last:</label>
|
||||||
<select name="since" id="show-last" onchange="this.form.submit()">
|
<select name="since" id="show-last" onchange="this.form.submit()" class="form-control">
|
||||||
<option value="">Show last..</option>
|
<option value="">Show last..</option>
|
||||||
<option value="30" {{ $since == 30 ? "selected" : "" }} >30 minutes</option>
|
<option value="30" {{ $since == 30 ? "selected" : "" }} >30 minutes</option>
|
||||||
<option value="60" {{ $since == 60 ? "selected" : "" }} >1 hour</option>
|
<option value="60" {{ $since == 60 ? "selected" : "" }} >1 hour</option>
|
||||||
@ -35,27 +41,20 @@
|
|||||||
<option value="1440" {{ $since == 1440 ? "selected" : "" }} >24 hours</option>
|
<option value="1440" {{ $since == 1440 ? "selected" : "" }} >24 hours</option>
|
||||||
<option value="4320" {{ $since == 4320 ? "selected" : "" }} >3 days</option>
|
<option value="4320" {{ $since == 4320 ? "selected" : "" }} >3 days</option>
|
||||||
<option value="10080" {{ $since == 10080 ? "selected" : "" }} >1 week</option>
|
<option value="10080" {{ $since == 10080 ? "selected" : "" }} >1 week</option>
|
||||||
<option value="full" {{ $since == "full" ? "selected" : "" }} >Entire history</option>
|
<option value="86400" {{ $since == 86400 ? "selected" : "" }} >Entire history</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
@endif
|
||||||
<form action="{{ url()->current() }}" method="GET">
|
@if(!isset($since))
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="datetimepicker1">Date since:</label>
|
<label for="datetimepicker1">Date since:</label>
|
||||||
<div class="input-group date" id="datetimepicker1" data-target-input="nearest">
|
<input name="date_since" type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1" value="{{ $date_since }}" onchange="this.form.submit()" />
|
||||||
<input name="date_since" type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1" />
|
|
||||||
<div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
|
|
||||||
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endif
|
||||||
<script type="text/javascript">
|
<input type="hidden" name="take" value="{{ $take }}" />
|
||||||
$(function () {
|
<div class='form-group'>
|
||||||
$('#datetimepicker1').datetimepicker();
|
<input id="enlarge-1" type=checkbox name='enlarge' {{ $enlarge == 'on' ? 'checked' : '' }} onchange="this.form.submit()"/>
|
||||||
$('#datetimepicker1').on('change.datetimepicker', function() {
|
<label for="enlarge-1">Enlarge chart</label>
|
||||||
this.form.submit();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -67,7 +66,7 @@
|
|||||||
<div>
|
<div>
|
||||||
@foreach($charts as $chart)
|
@foreach($charts as $chart)
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">{{ $chart["name"] }}</div>
|
<div class="card-header"><a href="{{ url('chart/'.$chart['name']) }}">{{ $chart["name"] }}</a></div>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
{!! $chart["chart"]->container() !!}
|
{!! $chart["chart"]->container() !!}
|
||||||
<button class="btn btn-primary" onclick="exportPNG('{{ $chart["name"] }} ({{ $drama_name }})',window.{{ $chart["chart"]->id }})">Export as PNG</button>
|
<button class="btn btn-primary" onclick="exportPNG('{{ $chart["name"] }} ({{ $drama_name }})',window.{{ $chart["chart"]->id }})">Export as PNG</button>
|
||||||
|
@ -53,6 +53,8 @@
|
|||||||
<!-- Right Side Of Navbar -->
|
<!-- Right Side Of Navbar -->
|
||||||
<ul class="navbar-nav ml-auto">
|
<ul class="navbar-nav ml-auto">
|
||||||
<li><a class="nav-link" href="{{ url('/') }}">{{ __('Home') }}</a></li>
|
<li><a class="nav-link" href="{{ url('/') }}">{{ __('Home') }}</a></li>
|
||||||
|
<li><a class="nav-link" href="{{ url('/chart/global') }}">{{ __('Global Chart') }}</a></li>
|
||||||
|
<li><a class="nav-link" href="{{ url('/nukes') }}">{{ __('Nukes') }}</a></li>
|
||||||
<li><a class="nav-link" href="{{ url('/statistics') }}">{{ __('Statistics') }}</a></li>
|
<li><a class="nav-link" href="{{ url('/statistics') }}">{{ __('Statistics') }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<!-- CSRF Token -->
|
|
||||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
||||||
|
|
||||||
<title>{{ config('app.name', 'Laravel') }}</title>
|
|
||||||
|
|
||||||
<!-- Scripts -->
|
|
||||||
<script src="{{ asset('js/app.js') }}" defer></script>
|
|
||||||
|
|
||||||
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
|
|
||||||
<link rel="stylesheet" href="{{ url('jquery.fancybox.min.css') }}" />
|
|
||||||
<script src="{{ url('jquery.fancybox.js') }}"></script>
|
|
||||||
|
|
||||||
<!-- Fonts -->
|
|
||||||
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
|
|
||||||
|
|
||||||
<!-- Styles -->
|
|
||||||
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
|
|
||||||
<link rel="stylesheet" href="{{ url('magnific-popup.css') }}" type="text/css" media="screen" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="app">
|
|
||||||
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
|
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand" href="{{ url('/') }}">
|
|
||||||
{{ config('app.name', 'Laravel') }}
|
|
||||||
</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
||||||
<!-- Left Side Of Navbar -->
|
|
||||||
<ul class="navbar-nav mr-auto">
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- Right Side Of Navbar -->
|
|
||||||
<ul class="navbar-nav ml-auto">
|
|
||||||
<!-- Authentication Links -->
|
|
||||||
@guest
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
|
||||||
</li>
|
|
||||||
@if (Route::has('register'))
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
|
||||||
{{ Auth::user()->name }} <span class="caret"></span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
|
||||||
@if(Auth::user()->is_admin)
|
|
||||||
@endif
|
|
||||||
<a class="dropdown-item" href="{{ route('submit') }}">Submit Score</a>
|
|
||||||
<a class="dropdown-item" href="{{ route('approval') }}">Approve Submission</a>
|
|
||||||
onclick="event.preventDefault();
|
|
||||||
document.getElementById('logout-form').submit();">
|
|
||||||
{{ __('Logout') }}
|
|
||||||
</a>
|
|
||||||
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
|
||||||
@csrf
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
@endguest
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
|
|
||||||
<main class="py-4">
|
|
||||||
@yield('content')
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
21
resources/views/nukes.blade.php
Normal file
21
resources/views/nukes.blade.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">Nukes</div>
|
||||||
|
<div class="card-body text-left">
|
||||||
|
<ul>
|
||||||
|
@foreach($nukes as $nuke)
|
||||||
|
<li><strong>{{ $nuke["nuke_time_start"] }}</strong>: ~{{ round($nuke["nuke_pts"],-3) }} nuke by <a href="{{ url('/chart/'.$nuke['role'].'?date_since='.$nuke['nuke_time_start']->subMinutes(30).'&take=13')}}">{{ $nuke["character"] }} as {{ $nuke["role"] }}</a></li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
@ -16,3 +16,6 @@ use Illuminate\Http\Request;
|
|||||||
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
Route::middleware('auth:api')->get('/user', function (Request $request) {
|
||||||
return $request->user();
|
return $request->user();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::get('/chart/{chart}', 'HomeController@viewChartApi');
|
||||||
|
|
||||||
|
@ -11,5 +11,7 @@
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::get('/', 'HomeController@home');
|
Route::get('/', 'HomeController@homeNew');
|
||||||
|
Route::get('/chart/{chart}', 'HomeController@viewChart');
|
||||||
Route::get('/statistics', 'HomeController@statistics');
|
Route::get('/statistics', 'HomeController@statistics');
|
||||||
|
Route::get('/nukes','HomeController@nukes');
|
||||||
|
Loading…
Reference in New Issue
Block a user