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 Slim\Routing\RouteContext; | ||||||
| use BitGoblin\Colossus\Models\Benchmark; | use BitGoblin\Colossus\Models\Benchmark; | ||||||
| use BitGoblin\Colossus\Models\Result; | use BitGoblin\Colossus\Models\Result; | ||||||
|  | use BitGoblin\Colossus\Models\Test; | ||||||
|  |  | ||||||
| class ApiController extends Controller { | class ApiController extends Controller { | ||||||
|  |  | ||||||
| @@ -65,4 +66,15 @@ class ApiController extends Controller { | |||||||
|       ->withHeader('Content-Type', 'application/json'); |       ->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->get('/result/list', '\\BitGoblin\\Colossus\\Controllers\\ApiController:getResultList')->setName('api.resultList'); | ||||||
|     $apiv1->post('/result/add', '\\BitGoblin\\Colossus\\Controllers\\ApiController:postResultAdd')->setName('api.resultAdd'); |     $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/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="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.7/js/bootstrap.min.js"></script> | ||||||
|   <script src="/js/bedabin.js"></script> |   <script src="/js/bedabin.js"></script> | ||||||
|  |   {% block scripts %}{% endblock %} | ||||||
| </head> | </head> | ||||||
| <body> | <body> | ||||||
|   {% include 'partials/navbar.twig' %} |   {% include 'partials/navbar.twig' %} | ||||||
|   | |||||||
| @@ -2,6 +2,12 @@ | |||||||
|  |  | ||||||
| {% block title %}Dashboard{% endblock %} | {% 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 %} | {% block content %} | ||||||
|  |  | ||||||
|   <div class="row"> |   <div class="row"> | ||||||
| @@ -13,16 +19,16 @@ | |||||||
|   <hr> |   <hr> | ||||||
|  |  | ||||||
|   <div class="row"> |   <div class="row"> | ||||||
|     <div class="five columns"> |     <div class="col-5"> | ||||||
|       <select id="report-benchmarks" class="u-full-width"> |       <select id="report-benchmarks" class="form-select"> | ||||||
|         {% for b in benchmarks %} |         {% for b in benchmarks %} | ||||||
|           <option value="{{ b.id }}">{{ b.name }}</option> |           <option value="{{ b.id }}">{{ b.name }}</option> | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
|       </select> |       </select> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <div class="seven columns"> |     <div class="col-7"> | ||||||
|       <select id="report-tests" class="u-full-width" multiple> |       <select id="report-tests" class="form-select" multiple> | ||||||
|         {% for t in benchmarks[0].tests %} |         {% for t in benchmarks[0].tests %} | ||||||
|           <option value="{{ t.id }}">{{ t.title }}</option> |           <option value="{{ t.id }}">{{ t.title }}</option> | ||||||
|         {% endfor %} |         {% endfor %} | ||||||
| @@ -30,4 +36,18 @@ | |||||||
|     </div> |     </div> | ||||||
|   </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 %} | {% endblock %} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user