-
-
Save phillipsharring/36396b49b3dd612846aa517f9e6d734a to your computer and use it in GitHub Desktop.
| @extends('layouts.app') | |
| @section('content') | |
| <!-- a bunch of other blade/html... --> | |
| <!-- placeholder for the chart --> | |
| <div class="col-xs-6"> | |
| <h3>Technology Focus</h3> | |
| <canvas id="myChart2" style="width: 400px; height: 200px;"></canvas> | |
| </div> | |
| <!-- more blade/html --> | |
| @endsection | |
| @section('js-foot') | |
| <script type="text/javascript"> | |
| // other scripts | |
| var ctx2 = document.getElementById("myChart2"); | |
| // we're using this with chart js | |
| var myChart2 = new Chart(ctx2, { | |
| type: 'pie', | |
| data: { | |
| // the keys for $technologyFocus are here, as the labels | |
| // this becomes [ "Technology", "Another Technology", "Others Below 7%" ], | |
| labels: [ "{!! $technologyFocus->keys()->implode('","') !!}" ], | |
| datasets: [ | |
| { | |
| // the values for $technologyfocus are here, as the data | |
| // this becomes [ 1500, 1489, 400 ], | |
| data: [ {{ $technologyFocus->values()->implode(',')}} ], | |
| backgroundColor: [ | |
| <?php | |
| // a lame random RGB color function I found and modified | |
| $colors = $technologyFocus->map(function(){ | |
| $color = function() { | |
| return str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT); | |
| }; | |
| $rgb = function() use($color) { | |
| return $color() . $color() . $color(); | |
| }; | |
| return '#' . $rgb(); | |
| }); | |
| echo '"' . $colors->implode('","') . '"'; | |
| ?> | |
| ] | |
| }] | |
| }, | |
| options: { | |
| scales: { | |
| yAxes: [{ | |
| ticks: { | |
| beginAtZero: true | |
| } | |
| }] | |
| } | |
| } | |
| }); | |
| </script> | |
| @endsection |
| <?php | |
| namespace App\Http\Controllers; | |
| use Illuminate\Support\Facades\Auth; | |
| use App\Services\ReportService; | |
| use App\Models\User; | |
| class LearnerProfileController extends Controller | |
| { | |
| // route is /learner-profile/{userId} where userId is optional. | |
| // we get auth::user if it's null | |
| public function index($userId = null) | |
| { | |
| $user = (null == $userId) | |
| ? Auth::user() | |
| : User::find($userId); | |
| // get the service in ReportService.php | |
| $reportService = new ReportService(); | |
| // a bunch of other reports grabbed here... | |
| $technologyFocus = $reportService->getTechnologyFocus($user->id); | |
| return view('learner-profile.index', compact( | |
| 'user', | |
| // the other report results. | |
| 'technologyFocus' | |
| )); | |
| } | |
| } |
| <?php | |
| // ReportService.php | |
| namespace App\Services; | |
| // various use statements go here | |
| class ReportService | |
| { | |
| // other methods... | |
| /** | |
| * @param integer $userId | |
| * | |
| * @return Collection; | |
| */ | |
| public function getTechnologyFocus($userId) | |
| { | |
| // get all the reported events from reporting table | |
| $views = Report::where('report', 'content-titles-viewed') | |
| ->where('user_id', $userId) | |
| ->get(); | |
| // reportable_type & reportable_id are a polymorphic relationship | |
| // reportable_id in this case is a Catalog_title id (yes, the model naming is messed up) | |
| $titleIds = $views->pluck('reportable_id')->unique(); | |
| // query for the technology names and counts | |
| $technologies = Catalog_titles_lov_product_technologies::select(DB::raw('COUNT(*) AS `total`'), 'lov_product_technologies.name') | |
| ->join('lov_product_technologies', 'catalog_titles_lov_product_technologies.lov_product_technology_id', '=', 'lov_product_technologies.id') | |
| ->whereIn('catalog_titles_lov_product_technologies.catalog_title_id', $titleIds->toArray()) | |
| ->where('lov_product_technologies.name', '!=', '') | |
| ->whereNotNull('lov_product_technologies.name') | |
| ->groupBy('lov_product_technologies.name') | |
| ->orderBy('total', 'DESC') | |
| ->get(); | |
| $percentage = 7; | |
| $total = $technologies->sum('total'); | |
| $threshold = floor($total * ($percentage * .01)); | |
| // get counts above the threshold | |
| $counts = $technologies->filter(function($item) use ($threshold) | |
| { | |
| return ($threshold < $item['total']); | |
| })->toArray(); | |
| // right above here ^^^ I'm making this into an array because | |
| // a) I don't need all of the Report objects, just selected values | |
| // b) I want to append to it later | |
| // find all the "others" below the threshold, then sum them to a single number | |
| $othersTotal = $technologies->filter(function($item) use ($threshold) | |
| { | |
| return ($threshold >= $item['total']); | |
| })->reduce(function($carry, $item) | |
| { | |
| return $carry + $item['total']; | |
| }); | |
| // append the "others" count to the $counts array | |
| $counts[] = [ | |
| 'total' => $othersTotal, | |
| 'name' => 'Others (Below ' . $percentage . '%)', | |
| ]; | |
| $result = []; | |
| // make the result a key => value array (name => total) | |
| collect($counts)->map(function($item) use (&$result) | |
| { | |
| $result[$item['name']] = $item['total']; | |
| }); | |
| // this too ^^^ seems like something that could be done more smoothly. | |
| // is there a better way to make $counts into a key => value array? | |
| /* | |
| // output | |
| // $result is like this now... | |
| [ | |
| "Technology" => 1500, | |
| "Another Technology" => 1489, | |
| // ... etc. | |
| "Others Below 7%" => 400, | |
| ]; | |
| // */ | |
| return collect($result); | |
| } | |
| // other methods | |
| } |
$technologies query output
Collection {#2916 ▼
#items: array:28 [▼
0 => Catalog_titles_lov_product_technologies {#2915 ▼
#table: "catalog_titles_lov_product_technologies"
#connection: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:2 [▼
"total" => 472
"name" => "Technology 1"
]
#original: array:2 [▶]
#relations: []
#hidden: []
#visible: []
#appends: []
#fillable: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
+exists: true
+wasRecentlyCreated: false
}
1 => Catalog_titles_lov_product_technologies {#2914 ▶}
2 => Catalog_titles_lov_product_technologies {#2913 ▶}
etc.
$result should be something like
Collection {#2947 ▼
#items: array:5 [▼
"Technology 1" => 472
"Technology 2" => 438
"Another Technology" => 249
"Yet Another Technology" => 232
"Others (Below 7%)" => 1407
]
}
This uses Chart.js