No Description

respuestas.php 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. <?php
  2. require_once 'processes/config.php';
  3. require_once 'processes/dbh.inc.php';
  4. require_once 'processes/checkLogin.php';
  5. include_once 'header.php';
  6. include("funciones.php");
  7. //SELECT a.id_question, q.premise, a.id_subquestionnair , q.id_category,q.id_subcategory FROM `answer` a, question q WHERE a.`id_student` = 1860 and a.id_question=q.id ORDER BY `a`.`id_question` ASC
  8. $experienceID = mysqli_real_escape_string($connection, trim($_GET['exp']));
  9. //$id_student = 1860;
  10. ///////Busca cantidad de sub cuestionarios - Empieza////////////////
  11. $sqlSelect = sprintf("SELECT * FROM experience_questionnair AS EQ JOIN subquestionnair AS SQ WHERE EQ.id_questionnair = SQ.id_questionnair AND EQ.id_experience = %s ORDER BY SQ.date_to_administer ASC",
  12. GetSQLValueString($experienceID, "int")
  13. );
  14. $dbresultSel = mysqli_query($connection, $sqlSelect);
  15. $moments = [];
  16. while($row = mysqli_fetch_array($dbresultSel)) {
  17. $moments[] = $row; // warning: includes first (pre) and last (post)
  18. }
  19. // print("<pre>");
  20. // var_dump($moments);
  21. // exit();
  22. //print(count($moments));
  23. ///////Termina - Busca cantidad de sub cuestionarios - ////////////////
  24. ///////Busca Preguntas - Empieza////////////////
  25. $sqlSelect = sprintf("SELECT DISTINCT Q.* FROM `experience_questionnair` AS EQ JOIN questionnair_question AS QQ JOIN question AS Q WHERE EQ.id_questionnair = QQ.`id_questionnair` AND QQ.id_question = Q.id AND EQ.id_experience = %s ORDER BY Q.id",
  26. GetSQLValueString($experienceID, "int")
  27. );
  28. $dbresultSel = mysqli_query($connection, $sqlSelect);
  29. $resultados = array();
  30. $j = 1;
  31. while($row = mysqli_fetch_array($dbresultSel)) {
  32. //$preguntas[] = array($i, $row['premise']);
  33. $emas = array();
  34. $emas[] = $j;
  35. $emas[] = $row['premise'];
  36. $emas[] = " "; // PRE test
  37. // SUBQUESTIONNAIRES
  38. for($i = 1; $i <= count($moments) - 2; $i++) {
  39. $emas[] = " ";
  40. }
  41. $emas[] = " "; // POST test
  42. $emas[] = " "; // Average
  43. $emas[] = " "; // Standard Deviation
  44. $emas[] = " "; // Percent Change between EMA and PRE
  45. $emas[] = " "; // Percent Change between POST and EMA
  46. $emas[] = " "; // Percent Change between POST and PRE
  47. $resultados[] = $emas;
  48. $j++;
  49. }
  50. ///////Termina - Busca Preguntas - ////////////////
  51. ///////Busca Estudiantes - Empieza////////////////
  52. $sqlSelectEst = sprintf("SELECT s.id id_stu FROM student s, student_participate_experience se WHERE s.id=se.id_student and se.id_experience = %s order by id_stu",
  53. GetSQLValueString($experienceID, "int")
  54. );
  55. $dbresultEst = mysqli_query($connection,$sqlSelectEst);
  56. ///////Termina - Busca Estudiantes - ////////////////
  57. $queryExperience = "SELECT * FROM experience WHERE id = '$experienceID'";
  58. $resultExperience = mysqli_query($connection, $queryExperience);
  59. $experience = mysqli_fetch_assoc($resultExperience);
  60. ?>
  61. <style>
  62. .table-header {
  63. width: 30px;
  64. vertical-align: middle;
  65. text-align: center;
  66. }
  67. .table-header.clickable {
  68. cursor: pointer;
  69. }
  70. </style>
  71. <!--START OF respuestas.php-->
  72. <body>
  73. <header id="main-header">
  74. <a id="logo" href=".">
  75. TANIA
  76. <img src="./img/pen_800x800.png" alt="tania logo pen" width="25" height="25">
  77. </a>
  78. <div id="account">
  79. <a class="nav-link" style="margin-right: 1rem;" href="<?= $_SERVER['HTTP_REFERER'] ?>"><i class="fas fa-arrow-left"></i> Back</a>
  80. <a class="sign-out" href="./processes/logout.php">Sign Out</a>
  81. </div>
  82. </header>
  83. <?php if($experienceID === 1): ?>
  84. <div class="container" style="margin-top: 8rem;">
  85. <div class="row">
  86. <div class="col">
  87. <h4>Warning: Este script no funciona para esta experiencia en particular (la parte de escoger los resultados por cada estudiante).</h4>
  88. </div>
  89. </div>
  90. </div>
  91. <?php endif; ?>
  92. <div class="container" style="margin-top: 8rem;">
  93. <!-- TITLE + EXPORT RAW -->
  94. <div class="row">
  95. <div class="col-sm-10">
  96. <h2>
  97. Results – <span class="text-muted"><?php echo $experience['title'] ?></span>
  98. <button type="button" class="btn btn-link btn-lg" data-toggle="popover" title="Table Tips" data-content="Toggle between one student or all students. Also, you can view results with respect to categories and subcategories. Click on each moment to get a breakdown of their details." data-placement="bottom">
  99. <span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span>
  100. </button>
  101. </h2>
  102. </div>
  103. <div class="col-sm-2">
  104. <br>
  105. <form id="exportForm" method="POST" action="processes/export.php">
  106. <input type="hidden" name="studentID" value="all">
  107. <input type="hidden" name="id_exp" value="<?php echo $experienceID; ?>">
  108. <input type="hidden" name="res_type" value="0">
  109. <button type="submit" name="export" class="btn btn-primary">Export Raw</button>
  110. </form>
  111. </div>
  112. </div>
  113. <!-- CHART 2 -->
  114. <div class="row">
  115. <div class="col-md-12">
  116. <canvas onclick="alert('holis brodel')" id="myChart2" style="margin: 2rem auto;">
  117. <p>Your browser does not support the canvas element.</p>
  118. </canvas>
  119. </div>
  120. </div>
  121. <div class="row">
  122. <div class="col">
  123. <div class="table-responsive">
  124. <table class="table table-bordered">
  125. <thead>
  126. <tr>
  127. <th scope="col" style="vertical-align: middle; text-align: center;" rowspan="2" style="width:30px">#</th>
  128. <th scope="col">
  129. <form>
  130. <select class="form-control" id="studentID" style="text-align-last: center;">
  131. <option disabled selected>Select Student</option>
  132. <option selected value="all">All Students</option>
  133. <?php while($rowEst = mysqli_fetch_array($dbresultEst)): ?>
  134. <option value='<?php echo $rowEst['id_stu']; ?>'><?php echo $rowEst['id_stu']; ?></option>
  135. <?php endwhile; ?>
  136. </select>
  137. <input type="hidden" value="<?php echo $experienceID;?>" id="experienceID">
  138. </form>
  139. </th>
  140. <th
  141. scope="col"
  142. rowspan="2"
  143. class="table-header clickable"
  144. data-momentid="<?= $moments[0]['id'] ?>"
  145. onclick="$('#breakdownModal').modal('show')"
  146. data-momentnumber="PRE"
  147. >
  148. Pre
  149. </th>
  150. <th colspan="<?php echo count($moments) - 2; ?>" style="vertical-align: middle; text-align: center;">Moments</th>
  151. <th
  152. scope="col"
  153. rowspan="2"
  154. class="table-header clickable"
  155. data-momentid="<?= $moments[count($moments) - 1]['id'] ?>"
  156. onclick="$('#breakdownModal').modal('show')"
  157. data-momentnumber="POST"
  158. >
  159. Post
  160. </th>
  161. <th scope="col" rowspan="2" class="table-header">&mu;</th><!--x&#772-->
  162. <th scope="col" rowspan="2" class="table-header">&sigma;</th>
  163. <th scope="col" rowspan="2" class="table-header">%&Delta;<br><small>Moments - Pre</small></th>
  164. <th scope="col" rowspan="2" class="table-header">%&Delta;<br><small>Post - Moments</small></th>
  165. <th scope="col" rowspan="2" class="table-header">%&Delta;<br><small>Post - Pre</small></th>
  166. </tr>
  167. <tr>
  168. <th>
  169. <form>
  170. <select class="form-control" id="tipo_resumen" style="text-align-last: center;">
  171. <option value="0" selected>Questions</option>
  172. <option value="1">Subcategories</option>
  173. <option value="2">Categories</option>
  174. </select>
  175. <input type="hidden" value="<?php echo $experienceID;?>" id="experienceID">
  176. </form>
  177. </th>
  178. <?php for($i = 1; $i <= count($moments) - 2; $i++): ?>
  179. <th
  180. class="table-header clickable"
  181. scope="col"
  182. data-momentid="<?= $moments[$i]['id'] ?>"
  183. onclick="$('#breakdownModal').modal('show')"
  184. data-momentnumber="<?= '#' . $i ?>"
  185. >
  186. <?php echo $i; ?>
  187. </th>
  188. <?php endfor; ?>
  189. </tr>
  190. </thead>
  191. <tbody id="loqueseve">
  192. <?php foreach($resultados as $pregunta): ?>
  193. <tr>
  194. <?php foreach($pregunta as $item): ?>
  195. <td style="vertical-align: middle; text-align: center;"><?php echo $item ?></td>
  196. <?php endforeach; ?>
  197. </tr>
  198. <?php endforeach; ?>
  199. </tbody>
  200. </table>
  201. </div><!--table-responsive-->
  202. </div><!--col-->
  203. </div><!--row-->
  204. </div><!--container-->
  205. <!-- CATEGORY CHART MODAL -->
  206. <div class='modal' id='breakdownModal' tabindex='-1' role='dialog' aria-labelledby='breakdownModalLabel' aria-hidden='true'>
  207. <div class='modal-dialog modal-lg' role='document'>
  208. <div class='modal-content'>
  209. <div class='modal-header'>
  210. <button type='button' class='close' data-dismiss='modal' aria-label='Close'>
  211. <span aria-hidden='true'>&times;</span>
  212. </button>
  213. <h3 class='modal-title' id='breakdownModalLabel'>Breakdown by <span id="breakdown-type">Category</span> <small id="moment-number">(Moment #)</small></h3>
  214. </div>
  215. <div class='modal-body'>
  216. <div class="row">
  217. <div class="col-md-12">
  218. <canvas id="categoryChart">
  219. <p>Your browser does not support the canvas element.</p>
  220. </canvas>
  221. <canvas id="subcategoryChart">
  222. <p>Your browser does not support the canvas element.</p>
  223. </canvas>
  224. <canvas id="questionChart">
  225. <p>Your browser does not support the canvas element.</p>
  226. </canvas>
  227. </div>
  228. </div>
  229. </div><!--modal-body-->
  230. <div class='modal-footer'>
  231. <button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
  232. </div>
  233. </div><!--modal-content-->
  234. </div><!--modal-dialog-->
  235. </div><!--modal-->
  236. <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
  237. <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.bundle.min.js"></script> -->
  238. <script>
  239. // Enable popovers
  240. $(function () {
  241. $('[data-toggle="popover"]').popover();
  242. });
  243. // Global Map of charts
  244. let myCharts = {};
  245. function fetchData(elementID = '#studentID') {
  246. // Define a map from elementID to element index
  247. let idToIndex = {
  248. '#studentID': 0,
  249. '#tipo_resumen': 2
  250. };
  251. // Fetch corresponding element index
  252. let index = idToIndex[elementID];
  253. // Manually change the studentID and respuestaType for the export form
  254. let inputs = document.querySelector('#exportForm').children;
  255. inputs[index].value = $(elementID).val();
  256. // Fetch data from database
  257. $.post('respuestasData.php',
  258. {
  259. id_student: $('#studentID').val(),
  260. id_exp: $('#experienceID').val(),
  261. res_type: $('#tipo_resumen').val()
  262. },
  263. function(data, status) {
  264. $('#loqueseve').html(data);
  265. }
  266. );
  267. }
  268. function fetchAnswerRate() {
  269. let experienceID = $("#experienceID").val()
  270. $.post("special5.php",
  271. {
  272. experienceID: experienceID
  273. },
  274. function(data, status) {
  275. console.log(data);
  276. // Fetch Data
  277. let payload = JSON.parse(data);
  278. let dataSet = payload.data; // array of {count, momentID, date} objects
  279. let maxScore = payload.maxScore // the maximum 'count' value from the data array
  280. // Initialize Data Containers
  281. let dataPoints = []; // [10, 20, 50, 70, 30];
  282. let dataLabels = []; // ['1', '2', '3', '4', '5'];
  283. // Create momentID -> momentNumber map for styling purposes
  284. let momentIDToNumber = {};
  285. let number = 1; // start at 1
  286. // If no moments have been sent yet, remove chart
  287. if(dataSet === null) {
  288. document.getElementById('myChart2').remove();
  289. return;
  290. }
  291. // Fill Data Containers
  292. dataSet.forEach(function(point) {
  293. // If given ID not in map, create it and increment number by 1
  294. if(momentIDToNumber[point.momentID] === undefined) {
  295. momentIDToNumber[point.momentID] = number;
  296. number++;
  297. }
  298. dataPoints.push(point.count);
  299. dataLabels.push(`${point.momentTitle} (${point.date})`);
  300. });
  301. // Render Chart
  302. renderStaticChart(dataPoints, dataLabels, maxScore);
  303. }
  304. );
  305. }
  306. function fetchBreakdownData(momentID, momentNumber, breakdownType) {
  307. // Fetch Necessary Data
  308. let experienceID = $('#experienceID').val();
  309. let studentID = $('#studentID').val();
  310. // Set Metadata Maps (breakdownType -> metadata)
  311. let breakdownChart = {
  312. '0': 'questionChart',
  313. '1': 'subcategoryChart',
  314. '2': 'categoryChart'
  315. };
  316. let breakdownText = {
  317. '0': 'Questions',
  318. '1': 'Subcategories',
  319. '2': 'Categories'
  320. };
  321. let breakdownScripts = {
  322. '0': 'questionBreakdown.php',
  323. '1': 'subcategoryBreakdown.php',
  324. '2': 'categoryBreakdown.php'
  325. };
  326. // Change Breakdown Type Text
  327. $('#breakdownModal #breakdown-type').text(breakdownText[breakdownType]);
  328. // Change Moment Number
  329. let metaText = momentNumber.includes('#') ? `(Moment ${momentNumber}` : `(${momentNumber} TEST`;
  330. if(studentID !== 'all') {
  331. metaText += ` of student ${studentID}`; // if a specific student is selected, say so
  332. }
  333. metaText += ')';
  334. $('#breakdownModal #moment-number').text(metaText);
  335. // Set Loading State on modal
  336. $('#breakdownModal canvas').hide();
  337. let loader = $('<div class="text-center" style="margin: 5rem 0"><h3>Loading Chart...</h3><span class="loader loader-lg"></span></div>').insertAfter('#breakdownModal canvas:last-child');
  338. // Make Request & Update Selected Chart
  339. $.post(breakdownScripts[breakdownType],
  340. {
  341. experienceID: experienceID,
  342. momentID: momentID,
  343. studentID: studentID
  344. },
  345. function(data, status) {
  346. console.log(data);
  347. // Fetch Data
  348. let payload = data; //JSON.parse(data); // aparently already an object
  349. let datasets = payload.datasets; // array of objects (datasets)
  350. let dataLabels = payload.dataLabels; // array of labels ["ResearchSelfEfficacy", "SourcesSelfEfficacy"]
  351. // Render Chart
  352. updateBreakdownChart(datasets, dataLabels, breakdownChart[breakdownType]);
  353. // Stop Loading State and Show Chart
  354. $(loader).remove();
  355. $('#' + breakdownChart[breakdownType]).show();
  356. }
  357. );
  358. }
  359. window.addEventListener('load', function() {
  360. // 1. Fetch Data for when changing select menus
  361. fetchData(); // can be "#tipo_resumen" too
  362. // 2. Set Event Listeners for menu change
  363. $("#studentID").change(function() {
  364. fetchData("#studentID");
  365. });
  366. $("#tipo_resumen").change(function() {
  367. fetchData("#tipo_resumen");
  368. });
  369. // 3. Set Event Listeners for table clicks
  370. $("th.table-header.clickable").on("click", function() {
  371. let momentID = $(this).data("momentid");
  372. let momentNumber = $(this).data("momentnumber");
  373. let breakdownType = $("#tipo_resumen").val(); // 0 for questions, 1 for subcategories, 2 for categories
  374. fetchBreakdownData(momentID, momentNumber, breakdownType);
  375. });
  376. // 4. Fetch and Render Answer Rate Chart
  377. fetchAnswerRate();
  378. // 5. Create Breakdown Charts
  379. ['categoryChart', 'subcategoryChart', 'questionChart'].forEach(function(chartName) {
  380. createBreakdownChart(chartName);
  381. });
  382. });
  383. function createBreakdownChart(chartName) {
  384. // Set Metadata Maps
  385. let auxiliaries = {
  386. 'categoryChart': {
  387. titleText: 'Distribution of Answers per Category',
  388. xLabel: 'Category',
  389. yLabel: 'Amount of people'
  390. },
  391. 'subcategoryChart': {
  392. titleText: 'Distribution of Answers per Subcategory',
  393. xLabel: 'Subcategory',
  394. yLabel: 'Amount of people'
  395. },
  396. 'questionChart': {
  397. titleText: 'Distribution of Answers per Question (not done yet)',
  398. xLabel: 'Question',
  399. yLabel: 'Amount of people'
  400. },
  401. };
  402. // Initialize Data
  403. let data = {
  404. labels: [],
  405. datasets: []
  406. };
  407. // Initialize Options
  408. let options = {
  409. title: {
  410. display: true,
  411. text: auxiliaries[chartName].titleText
  412. },
  413. legend: false,
  414. tooltips: {
  415. position: 'average',
  416. mode: 'index',
  417. intersect: false
  418. },
  419. scales: {
  420. xAxes: [{
  421. stacked: true, // for vertical bars
  422. display: true,
  423. scaleLabel: {
  424. display: true,
  425. labelString: auxiliaries[chartName].xLabel
  426. }
  427. }],
  428. yAxes: [{
  429. stacked: false, // for vertical bars
  430. display: true,
  431. scaleLabel: {
  432. display: true,
  433. labelString: auxiliaries[chartName].yLabel
  434. },
  435. ticks: {
  436. suggestedMin: 0
  437. }
  438. }]
  439. },
  440. layout: {
  441. padding: 30
  442. }
  443. };
  444. // Set Chart Configuration
  445. let config = {
  446. type: 'bar',
  447. data: data,
  448. options: options
  449. };
  450. // Create Chart
  451. let chart = new Chart(chartName, config);
  452. // Store Chart Reference in global dict
  453. myCharts[chartName] = chart;
  454. }
  455. function updateBreakdownChart(datasets, dataLabels, chartName) {
  456. // Store chart
  457. let chart = myCharts[chartName];
  458. // Remove all labels
  459. while(chart.data.labels.pop());
  460. // Insert new labels
  461. dataLabels.forEach(function(label) {
  462. chart.data.labels.push(label);
  463. });
  464. // Remove all datasets
  465. while(chart.data.datasets.pop());
  466. // Insert new datasets (with their respective data points)
  467. datasets.forEach(function(dataset) {
  468. chart.data.datasets.push(dataset);
  469. });
  470. // Update chart
  471. chart.update();
  472. console.log(chart.config);
  473. }
  474. function renderStaticChart(dataPoints, dataLabels, maxScore, elementID) {
  475. // Map from elementID to corresponding chart metadata
  476. let auxiliaries = {
  477. 'myChart2': {
  478. label: ' # of people who answered',
  479. backgroundColor: '#A4262C',
  480. borderColor: '#A4262C',
  481. titleText: 'Answer Rate',
  482. xAxisLabel: 'Moment Date & Number',
  483. yAxisLabel: 'Answers'
  484. }
  485. };
  486. // Initialize Data
  487. let data = {
  488. labels: dataLabels,
  489. datasets: [{
  490. label: auxiliaries['myChart2'].label,
  491. data: dataPoints,
  492. backgroundColor: auxiliaries['myChart2'].backgroundColor,
  493. borderColor: auxiliaries['myChart2'].borderColor,
  494. fill: false
  495. }]
  496. };
  497. // Initialize Options
  498. let options = {
  499. title: {
  500. display: true,
  501. text: auxiliaries['myChart2'].titleText
  502. },
  503. legend: false,
  504. tooltips: {
  505. position: 'average',
  506. mode: 'index',
  507. intersect: false
  508. },
  509. scales: {
  510. xAxes: [{
  511. stacked: true, // for vertical bars
  512. display: true,
  513. scaleLabel: {
  514. display: true,
  515. labelString: auxiliaries['myChart2'].xAxisLabel
  516. }
  517. }],
  518. yAxes: [{
  519. stacked: false, // for vertical bars
  520. display: true,
  521. scaleLabel: {
  522. display: true,
  523. labelString: auxiliaries['myChart2'].yAxisLabel
  524. },
  525. ticks: {
  526. suggestedMin: 0, // substitute with data.min or something
  527. suggestedMax: maxScore // substitute with data.max or something
  528. }
  529. }]
  530. }
  531. };
  532. // Set Chart Configuration
  533. let config = {
  534. type: 'bar',
  535. data: data,
  536. options: options
  537. };
  538. let myBarChart = new Chart('myChart2', config);
  539. }
  540. // Globals for chart timeline
  541. let pointCount = 1;
  542. function renderMovingChart(dataPoints, dataLabels, maxScore) {
  543. // Initialize Data
  544. let data = {
  545. labels: [], // initially empty, because it will be filled slowly for the timeline
  546. datasets: [{
  547. label: 'Moments answered per day and moment',
  548. data: [], // initially empty, because it will be filled slowly for the timeline
  549. backgroundColor: 'red',
  550. borderColor: 'red',
  551. // borderWidth: 1,
  552. fill: false
  553. }]
  554. };
  555. // Initialize Options
  556. let options = {
  557. legend: false,
  558. tooltips: {
  559. position: 'average',
  560. mode: 'index',
  561. intersect: false
  562. },
  563. scales: {
  564. xAxes: [{
  565. display: true,
  566. scaleLabel: {
  567. display: true,
  568. labelString: 'Moment Date (#ID)'
  569. }
  570. }],
  571. yAxes: [{
  572. display: true,
  573. scaleLabel: {
  574. display: true,
  575. labelString: 'Moments Answered'
  576. },
  577. ticks: {
  578. suggestedMin: 0, // substitute with data.min or something
  579. suggestedMax: maxScore // substitute with data.max or something
  580. }
  581. }]
  582. }
  583. };
  584. // Set Chart Configuration
  585. let config = {
  586. type: 'line',
  587. data: data,
  588. options: options
  589. }
  590. // config2
  591. let config2 = {
  592. type: 'bar',
  593. data: data,
  594. options: options
  595. };
  596. // Render Chart
  597. // let myLineChart = new Chart('myChart', config);
  598. let myBarChart = new Chart('myChart2', config2);
  599. // Set Timeline
  600. setInterval(function() {
  601. // Modularly increment 'index'/'counter'
  602. pointCount = pointCount % dataPoints.length + 1;
  603. if(pointCount !== 1) {
  604. // Create the label for that ith point
  605. config.data.labels.push(dataLabels[pointCount - 1]);
  606. // Overwrite existing
  607. config.data.datasets.forEach(function(dataset) {
  608. dataset.data.push(dataPoints[pointCount - 1]);
  609. });
  610. } else {
  611. // Remove all labels except the first
  612. config.data.labels.splice(0, dataPoints.length);
  613. // Remove all data points except the first (for each dataset)
  614. config.data.datasets.forEach(function(dataset) {
  615. for(let k = 0; k < dataPoints.length; k++) {
  616. dataset.data.pop();
  617. }
  618. });
  619. }
  620. // Render chart
  621. // myLineChart.update();
  622. myBarChart.update();
  623. }, 1500);
  624. }
  625. </script>
  626. </body>
  627. </html>