No Description

respuestas.php 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  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. <!-- CHART -->
  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. // Fill Data Containers
  287. dataSet.forEach(function(point) {
  288. // If given ID not in map, create it and increment number by 1
  289. if(momentIDToNumber[point.momentID] === undefined) {
  290. momentIDToNumber[point.momentID] = number;
  291. number++;
  292. }
  293. dataPoints.push(point.count);
  294. dataLabels.push(`${point.momentTitle} (${point.date})`);
  295. });
  296. // Render Chart
  297. renderStaticChart(dataPoints, dataLabels, maxScore);
  298. }
  299. );
  300. }
  301. function fetchBreakdownData(momentID, momentNumber, breakdownType) {
  302. // Fetch Necessary Data
  303. let experienceID = $('#experienceID').val();
  304. let studentID = $('#studentID').val();
  305. // Set Metadata Maps (breakdownType -> metadata)
  306. let breakdownChart = {
  307. '0': 'questionChart',
  308. '1': 'subcategoryChart',
  309. '2': 'categoryChart'
  310. };
  311. let breakdownText = {
  312. '0': 'Questions',
  313. '1': 'Subcategories',
  314. '2': 'Categories'
  315. };
  316. let breakdownScripts = {
  317. '0': 'questionBreakdown.php',
  318. '1': 'subcategoryBreakdown.php',
  319. '2': 'categoryBreakdown.php'
  320. };
  321. // Change Breakdown Type Text
  322. $('#breakdownModal #breakdown-type').text(breakdownText[breakdownType]);
  323. // Change Moment Number
  324. let metaText = momentNumber.includes('#') ? `(Moment ${momentNumber}` : `(${momentNumber} TEST`;
  325. if(studentID !== 'all') {
  326. metaText += ` of student ${studentID}`; // if a specific student is selected, say so
  327. }
  328. metaText += ')';
  329. $('#breakdownModal #moment-number').text(metaText);
  330. // Set Loading State on modal
  331. $('#breakdownModal canvas').hide();
  332. 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');
  333. // Make Request & Update Selected Chart
  334. $.post(breakdownScripts[breakdownType],
  335. {
  336. experienceID: experienceID,
  337. momentID: momentID,
  338. studentID: studentID
  339. },
  340. function(data, status) {
  341. console.log(data);
  342. // Fetch Data
  343. let payload = data; //JSON.parse(data); // aparently already an object
  344. let datasets = payload.datasets; // array of objects (datasets)
  345. let dataLabels = payload.dataLabels; // array of labels ["ResearchSelfEfficacy", "SourcesSelfEfficacy"]
  346. // Render Chart
  347. updateBreakdownChart(datasets, dataLabels, breakdownChart[breakdownType]);
  348. // Stop Loading State and Show Chart
  349. $(loader).remove();
  350. $('#' + breakdownChart[breakdownType]).show();
  351. }
  352. );
  353. }
  354. window.addEventListener('load', function() {
  355. // 1. Fetch Data for when changing select menus
  356. fetchData(); // can be "#tipo_resumen" too
  357. // 2. Set Event Listeners for menu change
  358. $("#studentID").change(function() {
  359. fetchData("#studentID");
  360. });
  361. $("#tipo_resumen").change(function() {
  362. fetchData("#tipo_resumen");
  363. });
  364. // 3. Set Event Listeners for table clicks
  365. $("th.table-header.clickable").on("click", function() {
  366. let momentID = $(this).data("momentid");
  367. let momentNumber = $(this).data("momentnumber");
  368. let breakdownType = $("#tipo_resumen").val(); // 0 for questions, 1 for subcategories, 2 for categories
  369. fetchBreakdownData(momentID, momentNumber, breakdownType);
  370. });
  371. // 4. Fetch and Render Answer Rate Chart
  372. fetchAnswerRate();
  373. // 5. Create Breakdown Charts
  374. ['categoryChart', 'subcategoryChart', 'questionChart'].forEach(function(chartName) {
  375. createBreakdownChart(chartName);
  376. });
  377. });
  378. function createBreakdownChart(chartName) {
  379. // Set Metadata Maps
  380. let auxiliaries = {
  381. 'categoryChart': {
  382. titleText: 'Distribution of Answers per Category',
  383. xLabel: 'Category',
  384. yLabel: 'Amount of people'
  385. },
  386. 'subcategoryChart': {
  387. titleText: 'Distribution of Answers per Subcategory',
  388. xLabel: 'Subcategory',
  389. yLabel: 'Amount of people'
  390. },
  391. 'questionChart': {
  392. titleText: 'Distribution of Answers per Question (not done yet)',
  393. xLabel: 'Question',
  394. yLabel: 'Amount of people'
  395. },
  396. };
  397. // Initialize Data
  398. let data = {
  399. labels: [],
  400. datasets: []
  401. };
  402. // Initialize Options
  403. let options = {
  404. title: {
  405. display: true,
  406. text: auxiliaries[chartName].titleText
  407. },
  408. legend: false,
  409. tooltips: {
  410. position: 'average',
  411. mode: 'index',
  412. intersect: false
  413. },
  414. scales: {
  415. xAxes: [{
  416. stacked: true, // for vertical bars
  417. display: true,
  418. scaleLabel: {
  419. display: true,
  420. labelString: auxiliaries[chartName].xLabel
  421. }
  422. }],
  423. yAxes: [{
  424. stacked: false, // for vertical bars
  425. display: true,
  426. scaleLabel: {
  427. display: true,
  428. labelString: auxiliaries[chartName].yLabel
  429. },
  430. ticks: {
  431. suggestedMin: 0
  432. }
  433. }]
  434. },
  435. layout: {
  436. padding: 30
  437. }
  438. };
  439. // Set Chart Configuration
  440. let config = {
  441. type: 'bar',
  442. data: data,
  443. options: options
  444. };
  445. // Create Chart
  446. let chart = new Chart(chartName, config);
  447. // Store Chart Reference in global dict
  448. myCharts[chartName] = chart;
  449. }
  450. function updateBreakdownChart(datasets, dataLabels, chartName) {
  451. // Store chart
  452. let chart = myCharts[chartName];
  453. // Remove all labels
  454. while(chart.data.labels.pop());
  455. // Insert new labels
  456. dataLabels.forEach(function(label) {
  457. chart.data.labels.push(label);
  458. });
  459. // Remove all datasets
  460. while(chart.data.datasets.pop());
  461. // Insert new datasets (with their respective data points)
  462. datasets.forEach(function(dataset) {
  463. chart.data.datasets.push(dataset);
  464. });
  465. // Update chart
  466. chart.update();
  467. console.log(chart.config);
  468. }
  469. function renderStaticChart(dataPoints, dataLabels, maxScore, elementID) {
  470. // Map from elementID to corresponding chart metadata
  471. let auxiliaries = {
  472. 'myChart2': {
  473. label: ' # of people who answered',
  474. backgroundColor: '#A4262C',
  475. borderColor: '#A4262C',
  476. titleText: 'Answer Rate',
  477. xAxisLabel: 'Moment Date & Number',
  478. yAxisLabel: 'Answers'
  479. }
  480. };
  481. // Initialize Data
  482. let data = {
  483. labels: dataLabels,
  484. datasets: [{
  485. label: auxiliaries['myChart2'].label,
  486. data: dataPoints,
  487. backgroundColor: auxiliaries['myChart2'].backgroundColor,
  488. borderColor: auxiliaries['myChart2'].borderColor,
  489. fill: false
  490. }]
  491. };
  492. // Initialize Options
  493. let options = {
  494. title: {
  495. display: true,
  496. text: auxiliaries['myChart2'].titleText
  497. },
  498. legend: false,
  499. tooltips: {
  500. position: 'average',
  501. mode: 'index',
  502. intersect: false
  503. },
  504. scales: {
  505. xAxes: [{
  506. stacked: true, // for vertical bars
  507. display: true,
  508. scaleLabel: {
  509. display: true,
  510. labelString: auxiliaries['myChart2'].xAxisLabel
  511. }
  512. }],
  513. yAxes: [{
  514. stacked: false, // for vertical bars
  515. display: true,
  516. scaleLabel: {
  517. display: true,
  518. labelString: auxiliaries['myChart2'].yAxisLabel
  519. },
  520. ticks: {
  521. suggestedMin: 0, // substitute with data.min or something
  522. suggestedMax: maxScore // substitute with data.max or something
  523. }
  524. }]
  525. }
  526. };
  527. // Set Chart Configuration
  528. let config = {
  529. type: 'bar',
  530. data: data,
  531. options: options
  532. };
  533. let myBarChart = new Chart('myChart2', config);
  534. }
  535. // Globals for chart timeline
  536. let pointCount = 1;
  537. function renderMovingChart(dataPoints, dataLabels, maxScore) {
  538. // Initialize Data
  539. let data = {
  540. labels: [], // initially empty, because it will be filled slowly for the timeline
  541. datasets: [{
  542. label: 'Moments answered per day and moment',
  543. data: [], // initially empty, because it will be filled slowly for the timeline
  544. backgroundColor: 'red',
  545. borderColor: 'red',
  546. // borderWidth: 1,
  547. fill: false
  548. }]
  549. };
  550. // Initialize Options
  551. let options = {
  552. legend: false,
  553. tooltips: {
  554. position: 'average',
  555. mode: 'index',
  556. intersect: false
  557. },
  558. scales: {
  559. xAxes: [{
  560. display: true,
  561. scaleLabel: {
  562. display: true,
  563. labelString: 'Moment Date (#ID)'
  564. }
  565. }],
  566. yAxes: [{
  567. display: true,
  568. scaleLabel: {
  569. display: true,
  570. labelString: 'Moments Answered'
  571. },
  572. ticks: {
  573. suggestedMin: 0, // substitute with data.min or something
  574. suggestedMax: maxScore // substitute with data.max or something
  575. }
  576. }]
  577. }
  578. };
  579. // Set Chart Configuration
  580. let config = {
  581. type: 'line',
  582. data: data,
  583. options: options
  584. }
  585. // config2
  586. let config2 = {
  587. type: 'bar',
  588. data: data,
  589. options: options
  590. };
  591. // Render Chart
  592. // let myLineChart = new Chart('myChart', config);
  593. let myBarChart = new Chart('myChart2', config2);
  594. // Set Timeline
  595. setInterval(function() {
  596. // Modularly increment 'index'/'counter'
  597. pointCount = pointCount % dataPoints.length + 1;
  598. if(pointCount !== 1) {
  599. // Create the label for that ith point
  600. config.data.labels.push(dataLabels[pointCount - 1]);
  601. // Overwrite existing
  602. config.data.datasets.forEach(function(dataset) {
  603. dataset.data.push(dataPoints[pointCount - 1]);
  604. });
  605. } else {
  606. // Remove all labels except the first
  607. config.data.labels.splice(0, dataPoints.length);
  608. // Remove all data points except the first (for each dataset)
  609. config.data.datasets.forEach(function(dataset) {
  610. for(let k = 0; k < dataPoints.length; k++) {
  611. dataset.data.pop();
  612. }
  613. });
  614. }
  615. // Render chart
  616. // myLineChart.update();
  617. myBarChart.update();
  618. }, 1500);
  619. }
  620. </script>
  621. </body>
  622. </html>