I am kind of new in Jquery,and still learning. I am using Chart.Js in order to render data and AJAX calls.
I created a script that update a Radar Chart using a dropdown Button. The goal in mind is:
Each user is part of a team and has some data that I render in a chart. So I there is some fixed data on the chart using a fixed_array and then the user can compare the current member with other member in the team using the drop down button
I managed to do it with static data with that code but I do not know how to make it dynamic.
I imported the whole team data in the form {user_id : [data_array]} for example :
{6: [81, 68, 71, 71, 67, -72], 7: [79, 77, 86, 86, 59, -71], 8: [67, 71, 68, 68, 85, -66]}
and the current_user id with current_user = data.current_user that return the integer of the ID in this situation 6.
I made a try in a separate file in order to test the chart which look like the following:
<script type="text/javascript">
$(document).ready(function () {
// Different arrays for the different data
var array = [];
array["raphael"] = [90, 20, 80, 50, 34];
array["fraxool"] = [89, 12, 68, 89, 90];
array["johnny"] = [78, 89, 1, 90, 80];
// Default value
var fixed_array = [20, 12, 78, 50, 90];
// Chart config
var color = Chart.helpers.color;
var config = {
type: 'radar',
data: {
labels: [["label1"], "label2", "label3", "label4", "label5"],
datasets: [{
label: "Bugsy Bug 1",
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
borderColor: window.chartColors.red,
pointBackgroundColor: window.chartColors.red,
data: []
}, {
label: "Bugsy Bug 2",
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
borderColor: window.chartColors.blue,
pointBackgroundColor: window.chartColors.blue,
data: fixed_array
}]
},
options: {
legend: {
position: 'top',
display: false
},
title: {
display: false,
text: 'Fiverr Chart'
},
scale: {
ticks: {
beginAtZero: true
},
pointLabels: {
fontSize: 10,
lineHeight: 2
}
}
}
};
var mainChart = new Chart(document.getElementById("canvas"), config);
// Event for the select
$(".pick-chart").change(function (e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
config.data.datasets[0].data = array[val];
} else {
config.data.datasets[0].data = [];
}
mainChart.update();
});
});
</script>
But my actual application is getting its data using AJAX:
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels comming from wevsite.views//
info_array = data.info_array
current_user = data.current_user
</script>
right now the output of info_array is {6: [81, 68, 71, 71, 67, -72], 7: [79, 77, 86, 86, 59, -71], 8: [67, 71, 68, 68, 85, -66]}
so {user_id: [data]}
and current_user output : 6
I would like to adapt it to use dynamic data that would adapt to any size of team
Could someone help me to figure it out ?
edited code V2:
<div class="col graph-info">
<div class="card">
<h5 class="card-header text-center bg-dark text-white">Information processing</h5>
<div class="card-body">
<div class="dropdown-container">
<form>
<select id="pick-chart" class="form-control pick-chart">
<option value="0">Compare with</option>
{% for i in team_list_pop %}
<option value="{{i.id}}">{{i.first_name}} {{i.last_name}}</option>
{% endfor %}
</select>
</form>
</div>
<canvas id="info_process"></canvas>
</div>
</div>
<script>
var endpoint = 'api/chart/data'
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels comming from wevsite.views//
complete_label = data.complete_label,
processing_information_label = data.processing_information_label,
motivation_label = data.motivation_label,
action_label = data.action_label,
other_data_label = data.other_data_label,
//Data comming from wevsite.views//
team_name_list2 = data.team_name_list2
info_array = data.info_array
current_user = data.current_user
team_list_id = data.team_list_id
fixed_array = info_array[current_user]
function random_color(){
var color = 'rgba(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256))+ ',' + 0.2 + ')';
return color
}
//ctx//
var ctx2 = document.getElementById("info_process").getContext('2d');
//graph 2//
var info_process = new Chart(ctx2,{
type: 'radar',
data: {
labels: processing_information_label,
datasets:[{
data: fixed_array, //processing_information_data,
backgroundColor: random_color()
},
{
backgroundColor: random_color(),
data: []
}]
},
options: {
legend: {
position: 'top',
display: false
},
scale: {
display: true,
ticks: {
beginAtZero: true,
}
},
responsive:true,
maintainAspectRatio: true,
}
});
//end graph 2//
$(".pick-chart").change(function (e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels coming from website.views//
info_array = data.info_array
current_user = data.current_user
config.data.datasets[0].data = info_array[val];
config.data.datasets[1].data = info_array[current_user];
mainChart.update();
}
});
} else {
config.data.datasets[0].data = [];
}
mainChart.update();
});
}
})
</script>
If you format your dropdown box as such: (so the user_id in the value of each option)
<select name="pick-chart" class="pick-chart">
<option value="6">Raphael</option>
...
</select>
You could rewrite your pick-chart.change function to something like:
$(".pick-chart").change(function (e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
//Labels coming from website.views//
info_array = data.info_array
current_user = data.current_user
config.data.datasets[0].data = info_array[val];
config.data.datasets[1].data = info_array[current_user];
mainChart.update();
}
});
} else {
config.data.datasets[0].data = [];
}
mainChart.update();
});
Assuming your data really is dynamic and could change while the user stays at your page. Also assuming that you want to compare current_user (which should also be a user_id) in dataset 1, like your fixed data, to a selected other user in dataset 0.
Related
EDIT: I have narrowed it down to something like this:
for (i = 0; i < data.length; i++) {
const newCanvas = document.createElement("canvas");
newCanvas.id = data[i].design_name;
const currentDiv = document.getElementById("chartSpace");
var parentDiv = document.getElementById("gridHere");
parentDiv.insertBefore(newCanvas, currentDiv);
createChart([data[i].design_name], [data[i].design_start, data[i].design_end]);
}
With the create chart making the chart id = to the array 'labels':
const myChart = new Chart(
document.getElementById(labels),
config
);
I am attempting to create a tool that creates an 'n' number of charts in ChartJS and save each of them as images. Currently, designButtonClick() sends the 'event_fky' value to
getDesigns(event_fky) in my controller. This method returns all designs with that foreign key. In turn, the chart plots each design on the chart. I need to evolve this into
something that can make a group individual charts for each design based on how many designs there are. My current solution, still conceptual, is to have methods in my controller
create chart variables 'chartData [data here]' and 'labels[datahere]' while looping through the designs returned from getDesigns, and sending those back to the JS script createChart
'n' number of times for each design. It would also send html chart/html element ids based on the design_name attribute to send back to createChart. This way, it is create a unique
chart 'n' number of times.
To save the charts as images, I would use the same set of element ids generated by getDesigns to send the charts to images using JS' toBase64Image() function and saving them to the
user's system.
Is this the best way of solving this problem? Or is this spaghetti, and is there a better method for this? My attempts to find better online answers have only resulted in docs on
updating one chart dynamically, not creating a dynamic number of charts. Much help is appreciated, code is below as well as a screenshot of the current chart output.
JavaScript:
var labels = [];
var cData = [];
function designButtonClick() {
var event_fky = 3;
$.ajax({
url: 'Tree/getDesigns',
type: 'POST',
data: { event_fky }
}).done(function (data) {
for (i = 0; i < data.length; i++) {
labels.push(data[i].design_name);
cData.push([data[i].design_start, data[i].design_end])
}
createChart(labels, cData);
});
}
function createChart(labels, cData) {
const data = {
labels: labels,
datasets: [{
barThickness: 2,
categoryPercentage: .5,
label: 'Design Time',
data: cData,
backgroundColor: [
'rgba(255, 26, 104, 0.2)'
],
borderColor: [
'rgba(255, 26, 104, 1)'
],
borderWidth: 1,
borderSkipped: false,
borderRadius: 20
}]
};
const config = {
type: 'bar',
data,
options: {
indexAxis: 'y',
scales: {
y: {
beginAtZero: true
},
x: {
min: 0,
max: 6000,
ticks: {
stepSize: 1000
}
}
}
}
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
}
C# Controller:
public ActionResult getDesigns(int? event_fky)
{
var designs = from e in _context.designs
where (event_fky.HasValue ? e.event_fky == event_fky : e.event_fky == null)
select new
{
design_pky = e.design_pky,
design_name = e.design_name,
design_start = e.design_start,
design_end = e.design_end
};
return this.Json(designs, JsonRequestBehavior.AllowGet);
}
Designs Table:
--------Design--------
design_pky |int
event_fky |int
design_name |varchar
design_start |number
design_end |number
Screenshot of Chart
This is a working answer for the javascript:
var eventList = function () {
var tmp = null;
$.ajax({
'async': false,
url: 'Tree/getEventIDs',
type: 'POST',
data: {},
'success': function (data) {
tmp = data;
}
});
return tmp;
}();
for (var i = 0; i < eventList.length; i++) {
event_fky = eventList[i].event_pky;
event_name = eventList[i].event_name;
event_length = eventList[i].event_end;
var designList = function () {
var tmpi = null;
$.ajax({
'async': false,
url: 'Tree/getDesigns',
type: 'POST',
data: {event_fky},
'success': function (data1) {
tmpi = data1;
}
});
console.log(event_fky);
console.log(tmpi);
return tmpi;
}();
var dLabels = [];
var dLengths = [];
for (var j = 0; j < designList.length; j++) {
dLabels.push(designList[j].design_name);
dLengths.push([designList[j].design_start, designList[j].design_end]);
}
const newCanvas = document.createElement("canvas");
newCanvas.id = event_name;
const currentDiv = document.getElementById("chartSpace");
var parentDiv = document.getElementById("gridHere");
parentDiv.insertBefore(newCanvas, currentDiv);
if (dLabels.length != 0) {
createChart(dLabels, dLengths, event_name, event_length);
}
}
}
function createChart(labels, cData, evName, evLen) {
// setup
const data = {
labels: labels,
datasets: [{
barThickness: 4,
categoryPercentage: .5,
label: evName,
data: cData,
backgroundColor: [
'rgba(' + Math.random() * 85 + ', ' + Math.random() * 170 + ', ' + Math.random() * 255 + ', 1)'
],
borderColor: [
'rgba(255, 26, 104, 1)'
],
borderWidth: 0,
borderSkipped: false,
borderRadius: 20
}]
};
// config
const config = {
type: 'bar',
data,
options: {
indexAxis: 'y',
scales: {
y: {
beginAtZero: true
},
x: {
min: 0,
max: evLen,
ticks: {
stepSize: 100
}
}
}
}
};
// render init block
const myChart = new Chart(
document.getElementById(evName),
config
);
return myChart;
}
// here I am taking another json encoded data from phpfile
$(document).ready(function () {
showGraph();
});
function showGraph()
{
{
$.post("phpfile.php",
function (data)
{
console.log(data);
var name = [];
var marks = [];
var height=[];
//and here as I couldn't encode two json array's separetly I'm declaring it to a variable and then using it
var jsonfile =[{"height":"85","st_name":"Name1"},{"height":"100","st_name":"Name3"},{"height":"92","st_name":"Name4"},{"height":"104","st_name":"Name5"},{"height":"91","st_name":"Name2"},{"height":"99","st_name":"Name6"},{"height":"140","st_name":"AI346"},{"height":"139","st_name":"abc"},{"height":"141","st_name":"def"},{"height":"140","st_name":"ghi"},{"height":"144","st_name":"jkl"},{"height":"130","st_name":"lmn"},{"height":"142","st_name":"opq"},{"height":"132","st_name":"rst"},{"height":"135","st_name":"xyz"},{"height":"135","st_name":"asdfsf"}];
//here I am reading the data from phpfile(1st Json array)
for (var i in data) {
name.push(data[i].st_name);
marks.push(data[i].height);
}
//here i am trying to access data from second json
for (var i=0;i<jsonfile.length;i++){
if(jsonfile[i].height==100)
{ height.push(jsonfile[i].height)}
}
//my graph function ,when I do this I am getting a single point with second json(height variable) but I need to highlight the particular point under a condition... I am not understanding how to do it.
var chartdata = {
labels: name,
datasets: [
{
label: 'height',
fill:false,
lineTension:0.5,
backgroundColor: '#5B2C6F',
borderColor: '#5B2C6F',
pointHoverBackgroundColor: '#5B2C6F',
pointHoverBorderColor: '#5B2C6F',
data: marks
//data:height
},
{
label: 'weight',
fill:false,
lineTension:0.1,
backgroundColor: '#C0392B',
borderColor: '#C0392B',
pointHoverBackgroundColor: '#C0392B',
pointHoverBorderColor: '#C0392B',
data:height,
//data:height
}
]
};
var graphTarget = $("#graphCanvas");
var lineGraph = new Chart(graphTarget, {
type: 'line',
data: chartdata,
options :{
scales:{
xAxes: [{
display: false //this will remove all the x-axis grid lines
}]
}
}
});
});
}
}
</script>
i will try to improve this.
var data =[{"height":"85","st_name":"Name1","color":"rgba(85, 85, 255, 255)"},{"height":"100","st_name":"Name3","color":"rgba(255, 0, 0, 2)"},{"height":"92","st_name":"Name4","color":"rgba(85, 85, 255, 255)"},{"height":"104","st_name":"Name5","color":"rgba(85, 85, 255, 255)"}];
var height = [];
var label = [];
var color = [];
for(i = 0; i<data.length; i++){
height.push(data[i]['height']);
label.push(data[i]['st_name']);
color.push(data[i]['color']);
}
var ctx = document.getElementById('myLine').getContext('2d');
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: label,
datasets: [{
data: height,
pointBorderColor: color,
}]
}
});
I am getting data from mysql using php to populate the array and then using that result to fill chart data. I want to change the color of the bars which are greater than 50. I tried a few examples that are already on the stack-overflow, however I was unable to solve my problem. That is why I am now asking this question.
$(document).ready(function() {
$.ajax({
url: "http://localhost:8080/chartjs/data.php",
method: "GET",
success: function(data) {
console.log(data);
var player = [];
var score = [];
for (var i in data) {
player.push(data[i].y);
score.push(data[i].x);
}
var chartdata = {
labels: player,
datasets: [{
label: 'Records from mysql',
backgroundColor: 'rgb(92, 95, 102)',
borderColor: 'rgba(200, 200, 200, 0.75)',
hoverBackgroundColor: 'rgba(30, 0, 200)',
hoverBorderColor: 'rgba(200, 200, 197)',
data: score
}
]
};
var ctx = $("#mycanvas");
var barGraph = new Chart(ctx, {
type: 'bar',
colors: {
data: function(score) {
return (score.value >= 45) ? '#00ff00' : '#f90411';
}
},
data: chartdata
});
},
error: function(data) {
console.log(data);
}
});
});
#chart-container {
width: 640px;
height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<div id="chart-container">
<canvas id="mycanvas"></canvas>
</div>
From what I could figure out is that your question is mostly related to the usage of chart.js. My solution to your problem would look like the following:
//Load your data (obviously this is a hardcoded example, you could use any backend code like PHP):
let data = [12, 19, 74, 38, 45, 62];
//Insantiate fields you would like to use, such as `colors` for background color and `borderColors` for, you guessed it, the color of the borders:
let colors = [];
let borderColors = [];
//Set the field values based on value (this would be your logic):
$.each(data, function(index, value) {
//When the value is higher than 45, set it to given color, else make them the other color (in the example the bars would appear red-ish):
if(value > 45) {
colors[index] = "rgba(0, 255, 0, 0.2)";
borderColors[index] = "rgba(0, 255, 1)";
}
else {
colors[index] = "rgba(249, 4, 17, 0.2)";
borderColors[index] = "rgba(249, 4, 17, 1)";
}
});
//Any code related to creating the chart with the bars (you could find any documentation regarding this code on the homepage of Chart.js):
let ctx = document.getElementById('myChart');
let myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['1', '2', '3', '4', '5', '6'],
datasets: [{
label: 'Records from mysql',
//Populate your fields here:
data: data,
backgroundColor: colors,
borderColor: borderColors,
hoverBackgroundColor: 'rgba(30, 0, 200)',
hoverBorderColor: 'rgba(200, 200, 197)',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
#chart-container {
width: 640px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<div id="chart-container">
<canvas id="myChart"></canvas>
</div>
JSFiddle
I applied some code I found on the following post on Github:
$.each(data, function(index, value) {
//When the value is higher than 45, set it to given color, else make them the other color (in the example the bars would appear red-ish):
if(value > 45) {
colors[index] = "rgba(0, 255, 0, 0.2)";
borderColors[index] = "rgba(0, 255, 1)";
}
else {
colors[index] = "rgba(249, 4, 17, 0.2)";
borderColors[index] = "rgba(249, 4, 17, 1)";
}
});
If anyone knows a more clean solution, please let me know in the comments.
Wondering if anyone can help me out please.
I'm having trouble getting a Chart.js LineChart (with AJAX data) to refresh every "X" seconds. I've tried to put the code below in a function inside a setInterval and eventhough it does refresh, it redraws itself in a "zoomed-in" manner...
I want the chart to refresh itself every 10 seconds.
Code:
$.ajax({
type: "POST",
url: '#Url.Action("ChartRT")',
contentType: "application/json",
dataType: "json",
success:
function (chartsdata_RT) {
var aData = chartsdata_RT;
var aLabels = aData.map(c => c.Period);
var aDatasets1 = aData.map(c => c.FAILED);
var aDatasets2 = aData.map(c => c.OTHER);
var aDatasets3 = aData.map(c => c.DELIVERED);
var aDatasets4 = aData.map(c => c.PENDING);
var dataT = {
labels: aLabels,
datasets: [
{
label: "FAILED",
data: aDatasets1,
borderColor: '#ff0000',
backgroundColor: "rgba(255, 0, 0, 0.3)",
fill: 'true'
},
{
label: "OTHER",
data: aDatasets2,
borderColor: '#3366ff',
backgroundColor: "rgba(32, 162, 219, 0.3)",
},
{
label: "DELIVERED",
data: aDatasets3,
borderColor: '#009900',
backgroundColor: "rgba(0, 102, 0, 0.3)",
},
{
label: "PENDING",
data: aDatasets4,
borderColor: '#ff9900',
backgroundColor: "rgba(255, 153, 219, 0.3)",
}
]
};
var ctx = $("#chart_last2hours").get(0).getContext("2d");
ctx.canvas.height = "50";
var myNewChart = new Chart(ctx, {
type: 'line',
data: dataT,
options: {
legend: {
display: true,
position: 'right',
fullWidth: false,
labels: {
fontColor: '#484848',
fontsize: 10,
boxWidth: 20,
padding: 5,
lineWideth: 0
}
}
}
});
}
});
ended wrapping the above code in a function (drawChartRT). I then:
1) Call the function drawChartRT() to draw the LineChart.
2) Inside a setInterval remove and add the canvas and call the function drawChartRT().
drawChartRT();
setInterval(function () {
$("canvas#chart_last2hours").remove();
$("#chartdiv_rt").append('<canvas id="chart_last2hours" height="200"></canvas>');
var div = document.getElementById("chart_last2hours");
//console.log(div);
drawChartRT();
}, 10000);
Works like a charm!
Thanks. José
In the code below I am making a chartJS chart using database data, this is being done via a submit button which looks like this:
function showWhatSelected(str) {
$('#select2').hide();
$('#select3').hide();
if (str == "") {
document.getElementById("select1").innerHTML = "";
return;
} else {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("select1").innerHTML = this.responseText;
}
};
xmlhttp.open("GET","../controller/teamleiderController.php?action=whatToShow&value="+ str,true);
xmlhttp.send();
}
}
After that the AJAX runs which makes the new chart when a change has been detected in the submit button:
$.ajax({
url: "../controller/teamleiderController.php?action=select2JSON&value="+ str +"",
method: "GET",
success: function(data) {
console.log(data);
var label = ['aanwezig', 'afwezig'];
var aanwezigheid = [];
for(var i in data) {
aanwezigheid.push(data[i].aanwezig, data[i].afwezig, );
}
var chartdata = {
labels: label,
datasets : [
{
backgroundColor: ['rgba(0, 65, 140, 0.8)', 'rgba(215, 165, 0, 0.8)'],
borderColor: 'rgba(0, 0, 0, 0)',
hoverBackgroundColor: ['rgba(0, 65, 140, 1)', 'rgba(215, 165, 0, 1)'],
hoverBorderColor: 'rgba(200, 200, 200, 0)',
data: aanwezigheid
}
]
};
var option = {
};
var ctx = $("#mycanvas");
var barGraph = new Chart(ctx, {
type: 'pie',
data: chartdata,
options:option
});
},
error: function(data) {
console.log(data);
}
});
}
My problem is that my chart is ghosting, it keeps showing previous data, is there any way I can fix this? I have tried .destroy() and .clear() but they both don't seem to work...
You indeed need to use .destroy() method to remove any previous instance of chart before making a new one.
Perhaps, you were using the .destroy() method in an inappropriate manner, which made it non-effective.
Here's how you could properly remove / destroy any previous instance of chart, before creating a new one ...
var meta = barGraph && barGraph.data && barGraph.data.datasets[0]._meta;
for (let i in meta) {
if (meta[i].controller) meta[i].controller.chart.destroy();
}
affix the above code before initiating your chart
note: barGraph must be a global variable.
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
var barGraph;
function init(str) {
$.ajax({
url: "https://istack.000webhostapp.com/json/" + str + ".json",
method: "GET",
success: function(data) {
console.log(data);
var label = ['aanwezig', 'afwezig'];
var aanwezigheid = [];
for (var i in data) {
aanwezigheid.push(data[i].aanwezig, data[i].afwezig);
}
var chartdata = {
labels: label,
datasets: [{
backgroundColor: ['rgba(0, 65, 140, 0.8)', 'rgba(215, 165, 0, 0.8)'],
borderColor: 'rgba(0, 0, 0, 0)',
hoverBackgroundColor: ['rgba(0, 65, 140, 1)', 'rgba(215, 165, 0, 1)'],
hoverBorderColor: 'rgba(200, 200, 200, 0)',
data: aanwezigheid
}]
};
var option = {responsive: false};
// destroy previous chart
var meta = barGraph && barGraph.data && barGraph.data.datasets[0]._meta;
for (let i in meta) {
if (meta[i].controller) meta[i].controller.chart.destroy();
}
// make new chart
var ctx = $("#mycanvas");
barGraph = new Chart(ctx, {
type: 'pie',
data: chartdata,
options: option
});
},
error: function(data) {
console.log(data);
}
});
}
body{overflow:hidden}button{margin-left: 45px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<button onclick="init('t1')">Dataset 1</button>
<button onclick="init('t2')">Dataset 2</button><br>
<canvas id="mycanvas" height="180"></canvas>