I am trying to make a chart show up in an HTML file that is being generated programatically. What I'm trying to do, is to place a canvas in the HTML early on, and then have a java script actually place the chart data. But it's not working for me, and I'm not sure how to fix it.
The following is a scrubbed and condensed version of the actual HTML showing the problem.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Active chats</title>
<meta charset="utf-8">
<style>
body {
background-attachment: fixed;
}
.twoTables {
margin-left:-5px;
margin-right:-5px;
}
.tableLeft {
float:left ;
padding: 5px ;
}
.tableRight {
float:left ;
padding: 5px ;
}
.twoTables::after {
content: "";
clear: both;
display: table;
}
headingLink {
color: white; text-decoration: none ;
}
.dummyRow {
line-height: 1px;
visibility: hidden;
}
.freeze-table {
border-spacing: 0;
border-collapse: collapse;
padding: 0;
}
thead th {
top: 0;
position: sticky;
background-color: #666 ;
color: #fff ;
z-index: 20 ;
min-height: 30px ;
height: 30px ;
text-align: left ;
}
tr:nth-child(even) {
background-color: #f2f2f2 ;
}
xth, xtd {
padding: 0 5px;
border-collapse: collapse;
font-size: 100% ;
outline: 1px solid #ccc ;
border: none ;
outline-offset: -1px ;
padding-left: 5px ;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
th, td {
padding: 0 0px;
border-collapse: collapse;
font-size: 100% ;
border: none ;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 5px;
}
tr {
min-height: 25px ;
height: 25px ;
background-color: #ffffff
}
pageElement {
display:flex; flex-wrap: nowrap; align-items: center
}
a:link {
color: white ;
text-decoration: none ;
}
* { padding: 0;
margin: 0;
}
.fit { /* set relative picture size */
max-width: 100%;
max-height: 100%;
}
.center {
display: block;
margin: auto;
}
.imgbox {
display: grid;
width: 100%;
}
.center-fit {
max-width: 100%;
max-height: 100vh;
margin: auto;
}
@media screen and (max-width: 100px) {
.tableLeft {
<!-- width: 40%; <-- ->
}
.tableRight {
<!-- width:100%; <!-- ->
}
}
</style>
</head>
<body><form method = 'POST' action = /YouTube/latestChats.php >
<table style='border-collapse:collapse;'>
<tr>
<td><input type = 'checkbox' name='highlightMsg' id='highlightMsg' checked >
<label for='highlightMsg'>Highlight messages</label></td>
<td><input type = 'checkbox' name = 'msgUseRegEx' id = 'msgUseRegEx' checked >
<label for='msgUseRegEx'>Use REGEX</label></td>
<td>Message filter</td>
<td><input type = 'text' name = 'msgFilter' value='[@#]*request' size=30 ></td>
</tr>
<tr>
<td><input type='checkbox' name='invertOrder' id='invertOrder' checked >
<label for='invertOrder'>Latest first</label></td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td>
<input type='radio' name='emoteMgmt' value='text'> Emoticons as text
<input type='radio' name='emoteMgmt' checked value='icon'> Emoticons as image
<input type='radio' name='emoteMgmt' value='strip'> Strip emoticons
</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</table>
<br>
<input type='submit' name='submit' value='Submit'>
<input type='submit' name=backToYouTubeStuff value='Go Back'>
<input type='submit' name=buttonCheckLivestream value='Check for new'>
<br>
</form>
<br><script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class='twoTables'>
<div id='watchers' class='tableLeft'><table>
<tr>
<th colspan=2>Watcher</th><th>Joined</th><th>Latest</th>
</tr>
<tr><td style='text-align:right;'>26</td><td><span>John RC</span></td><td>07:32</td><td style='text-align:right;'>0.0m</td></tr>
<tr><td style='text-align:right;'>25</td><td><span>Carolyn Free</span></td><td>07:31</td><td style='text-align:right;'>4.2m</td></tr>
<tr><td style='text-align:right;'>24</td><td><span>Johnny Flyer</span></td><td>07:31</td><td style='text-align:right;'>3.4m</td></tr>
</table><br><br>
<div style="width: 200px;">
<canvas id="concurrentChart">
<script>
const ctx = document.getElementById('concurrentChart') ;
new Chart(ctx
, type: 'line'
, data: {
labels: ["07:08","07:09","07:10","07:11","07:12","07:13","07:14","07:15","07:16","07:17","07:18","07:19","07:20","07:21","07:22","07:23","07:24","07:25","07:26","07:27","07:28","07:29","07:30","07:31","07:32","07:33","07:34","07:35"]
, datasets: [{
label: 'Concurrent Chat Viewers'
, data: [0,8,8,9,6,8,8,3,5,7,4,4,1,3,8,8,6,6,4,7,11,16,14,9,7,9,6,9]
, fill:false
, borderColor: 'rgb(75, 192, 192)'
, tension: 0.1
}]
}
);
</script>
</canvas>
</div></div><div id='chats' class='tableRight'><table style='border-collapse:collapse;border:0px solid white;'>
<tr style='color:white; border:0px;'>
<th colspan=3 style='text-align:center;background-color:darkblue;color:white;font-size:115%;font-weight:bold;border:solid white;'>2023-09-17</th>
<td style='background-color:darkblue;color:white;font-size:115%;font-weight:bold;border:solid white;word-wrap:break-word;'><a href='https://youtu.be/-unZO__WJuo'>2023-09-17 Atlanta timeline (23-080) <span style="background-color:lightblue;color:black;font-size:100%;font-weight:bold;"> (16 max) </span></a></td>
</tr>
<tr>
<td style='text-align:right;color:Blue;'>1</td>
<td style='text-align:center;color:Blue;'>07:36</td>
<td style='text-align:left;color:Blue;'>John RC</td>
<td style='text-align:left;color:Blue;'>
<a style='color:blue;text-decoration:none;word-wrap:break-word;wicth:100%;' href='https://youtu.be/-unZO__WJuo?t=1690' target='_blank'>_
I think he gave up</a></td>
</tr><tr>
<td style='text-align:right;color:Blue;'>2</td>
<td style='text-align:center;color:Blue;'>07:35</td>
<td style='text-align:left;color:Blue;'>Blessing</td>
<td style='text-align:left;color:Blue;'>
<a style='color:blue;text-decoration:none;word-wrap:break-word;wicth:100%;' href='https://youtu.be/-unZO__WJuo?t=1624' target='_blank'>_
<span style='background-color:red; color:black;'>@request</span> Sorry you’re having technical difficulties Dennis.</a></td>
</tr><tr>
<td style='text-align:right;color:Blue;'>3</td>
<td style='text-align:center;color:Blue;'>07:35</td>
<td style='text-align:left;color:Blue;'>Buying Space</td>
<td style='text-align:left;color:Blue;'>
<a style='color:blue;text-decoration:none;word-wrap:break-word;wicth:100%;' href='https://youtu.be/-unZO__WJuo?t=1623' target='_blank'>_
Warren, the Blood, Sweat and Tears version?</a></td>
</tr><tr>
<td style='text-align:right;color:Blue;'>4</td>
<td style='text-align:center;color:Blue;'>07:35</td>
<td style='text-align:left;color:Blue;'>Sky Flier</td>
<td style='text-align:left;color:Blue;'>
<a style='color:blue;text-decoration:none;word-wrap:break-word;wicth:100%;' href='https://youtu.be/-unZO__WJuo?t=1619' target='_blank'>_
lol @Blessing</a></td>
</tr><tr>
<td style='text-align:right;color:Blue;'>5</td>
<td style='text-align:center;color:Blue;'>07:35</td>
<td style='text-align:left;color:Blue;'>TeeJ Giggles n Drones</td>
<td style='text-align:left;color:Blue;'>
<a style='color:blue;text-decoration:none;word-wrap:break-word;wicth:100%;' href='https://youtu.be/-unZO__WJuo?t=1590' target='_blank'>_
Right Ronnie 😂😂😂</a></td>
</tr>
<tr><th colspan=5 style='background-color: #666 ;color: #fff ;z-index: 20 ;min-height: 30px ;height: 30px ;text-align: left ;'>End of data.</th>
</tr>
</table>
</div>
</div>
</body>
</html>
What should be seen, depending upon window size, is a table on the left and a chart below it, and a separate table on the right. But the chart is missing.
Is the approach incorrect here? Is it not possible to have javascript update the canvas?
Yes, you can absolutely use JavaScript to update a canvas in your HTML. The problem you're encountering is primarily due to the way you've structured your script and HTML.
Here are some issues with the current structure:
<script>
tag is placed inside the
<canvas>
tag. It should be outside.new Chart()
instantiation,
there's an issue with the JavaScript syntax. You need {}
to wrap the
configuration object.Here's how to fix it:
<canvas>
tag.Here's a corrected version of the relevant part of your HTML:
<div style="width: 200px;">
<canvas id="concurrentChart"></canvas>
</div>
<script>
const ctx = document.getElementById('concurrentChart').getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ["07:08","07:09","07:10","07:11","07:12","07:13","07:14","07:15","07:16","07:17","07:18","07:19","07:20","07:21","07:22","07:23","07:24","07:25","07:26","07:27","07:28","07:29","07:30","07:31","07:32","07:33","07:34","07:35"],
datasets: [{
label: 'Concurrent Chat Viewers',
data: [0,8,8,9,6,8,8,3,5,7,4,4,1,3,8,8,6,6,4,7,11,16,14,9,7,9,6,9],
fill: false,
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
}
});
</script>