Added ability to generate a basic chart using chart.js
This commit is contained in:
		
							
								
								
									
										76
									
								
								assets/scripts/reports.coffee
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								assets/scripts/reports.coffee
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| $ -> | ||||
|   $('#reports-download').on 'click', -> | ||||
|     canvas = $('#benchmark-chart')[0] | ||||
|     a = document.createElement 'a' | ||||
|     a.href = canvas.toDataURL 'image/png' | ||||
|     a.download = 'chart.png' | ||||
|     a.click() | ||||
|  | ||||
|   $('#reports-button').on 'click', (e) -> | ||||
|     benchmarkId = $('#report-benchmarks').val() | ||||
|     testIds = $('#report-tests').val() | ||||
|  | ||||
|     benchmarkSearchParams = new URLSearchParams | ||||
|       benchmark_id: benchmarkId | ||||
|     benchmarkRes = await fetch("/api/v1/benchmark/details?#{benchmarkSearchParams}") | ||||
|     benchmarkData = await benchmarkRes.json() | ||||
|  | ||||
|     data = | ||||
|       labels: [] | ||||
|       datasets: [ | ||||
|         { | ||||
|           label: 'Average Score' | ||||
|           data: [] | ||||
|         } | ||||
|       ] | ||||
|  | ||||
|     for testId in testIds | ||||
|       try | ||||
|         testSearchParams = new URLSearchParams | ||||
|           test_id: testId | ||||
|         testRes = await fetch("/api/v1/test/details?#{testSearchParams}") | ||||
|         testData = await testRes.json() | ||||
|  | ||||
|         resultSearchParams = new URLSearchParams | ||||
|           test_id: testId | ||||
|           benchmark_id: benchmarkId | ||||
|         resultRes = await fetch("/api/v1/result/list?#{resultSearchParams}") | ||||
|         resultData = await resultRes.json() | ||||
|  | ||||
|         avg_total = 0 | ||||
|         min_total = 0 | ||||
|         max_total = 0 | ||||
|  | ||||
|         for result in resultData | ||||
|           avg_total += result.average | ||||
|           min_total += result.minimum if result.minimum | ||||
|           max_total += result.maximum if result.maximum | ||||
|  | ||||
|         data.labels.push(testData.title) | ||||
|         data.datasets[0].data.push(avg_total / resultData.length) | ||||
|       catch error | ||||
|         console.error 'An error occurred while fetching benchmark results.', error | ||||
|  | ||||
|     ctx = $('#benchmark-chart')[0].getContext('2d') | ||||
|  | ||||
|     options = | ||||
|       indexAxis: 'y' | ||||
|       plugins: | ||||
|         datalabels: | ||||
|           anchor: 'end' | ||||
|           align: 'left' | ||||
|           color: 'black' | ||||
|           font: | ||||
|             weight: 'bold' | ||||
|           formatter: (value) -> value | ||||
|       scales: | ||||
|         y: | ||||
|           beginAtZero: true | ||||
|  | ||||
|     new Chart ctx, | ||||
|       type: 'bar' | ||||
|       data: data | ||||
|       options: options | ||||
|       plugins: [ChartDataLabels] | ||||
|  | ||||
|     $('#reports-download').attr('disabled', false) | ||||
| @@ -7,6 +7,7 @@ use Psr\Http\Message\ServerRequestInterface as Request; | ||||
| use Slim\Routing\RouteContext; | ||||
| use BitGoblin\Colossus\Models\Benchmark; | ||||
| use BitGoblin\Colossus\Models\Result; | ||||
| use BitGoblin\Colossus\Models\Test; | ||||
|  | ||||
| class ApiController extends Controller { | ||||
|  | ||||
| @@ -65,4 +66,15 @@ class ApiController extends Controller { | ||||
|       ->withHeader('Content-Type', 'application/json'); | ||||
|   } | ||||
|  | ||||
|   public function getTestDetails(Request $request, Response $response, array $args): Response { | ||||
|     $urlParams = $request->getQueryParams(); | ||||
|     $test = Test::where('id', $urlParams['test_id'])->first(); | ||||
|  | ||||
|     $payload = json_encode($test); | ||||
|  | ||||
|     $response->getBody()->write($payload); | ||||
|     return $response | ||||
|       ->withHeader('Content-Type', 'application/json'); | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -50,5 +50,7 @@ $app->group('/api', function(RouteCollectorProxy $group) { | ||||
|  | ||||
|     $apiv1->get('/result/list', '\\BitGoblin\\Colossus\\Controllers\\ApiController:getResultList')->setName('api.resultList'); | ||||
|     $apiv1->post('/result/add', '\\BitGoblin\\Colossus\\Controllers\\ApiController:postResultAdd')->setName('api.resultAdd'); | ||||
|  | ||||
|     $apiv1->get('/test/details', '\\BitGoblin\\Colossus\\Controllers\\ApiController:getTestDetails')->setName('api.testDetails'); | ||||
|   }); | ||||
| }); | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
|   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> | ||||
|   <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.7/js/bootstrap.min.js"></script> | ||||
|   <script src="/js/bedabin.js"></script> | ||||
|   {% block scripts %}{% endblock %} | ||||
| </head> | ||||
| <body> | ||||
|   {% include 'partials/navbar.twig' %} | ||||
|   | ||||
| @@ -2,6 +2,12 @@ | ||||
|  | ||||
| {% block title %}Dashboard{% endblock %} | ||||
|  | ||||
| {% block scripts %} | ||||
|   <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js" charset="utf-8"></script> | ||||
|   <script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.2.0/chartjs-plugin-datalabels.min.js" charset="utf-8"></script> | ||||
|   <script src="/js/reports.js" charset="utf-8"></script> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block content %} | ||||
|  | ||||
|   <div class="row"> | ||||
| @@ -13,16 +19,16 @@ | ||||
|   <hr> | ||||
|  | ||||
|   <div class="row"> | ||||
|     <div class="five columns"> | ||||
|       <select id="report-benchmarks" class="u-full-width"> | ||||
|     <div class="col-5"> | ||||
|       <select id="report-benchmarks" class="form-select"> | ||||
|         {% for b in benchmarks %} | ||||
|           <option value="{{ b.id }}">{{ b.name }}</option> | ||||
|         {% endfor %} | ||||
|       </select> | ||||
|     </div> | ||||
|  | ||||
|     <div class="seven columns"> | ||||
|       <select id="report-tests" class="u-full-width" multiple> | ||||
|     <div class="col-7"> | ||||
|       <select id="report-tests" class="form-select" multiple> | ||||
|         {% for t in benchmarks[0].tests %} | ||||
|           <option value="{{ t.id }}">{{ t.title }}</option> | ||||
|         {% endfor %} | ||||
| @@ -30,4 +36,18 @@ | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <div class="row"> | ||||
|     <div class="col-12"> | ||||
|       <button id="reports-button" class="btn btn-primary" type="button" name="button">Generate Chart</button> | ||||
|       <button id="reports-download" class="btn btn-primary" type="button" name="button" disabled>Download Chart</button> | ||||
|  | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
|   <div class="row"> | ||||
|     <div class="col-5"> | ||||
|       <canvas id="benchmark-chart" width="800" height="400"></canvas> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
| {% endblock %} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user