Side effects from Chartjs for only *some* clients - javascript

I was working on a couple of Chart.js charts and have found some strange behavior.
In this fiddle: http://jsfiddle.net/h42tv3xv/ people have been getting a variety of side effects when pressing the buttons "Day", "Week", or "Month".
What it should do:
Simply refresh the chart with potentially new information displayed(the pie and doughnut actually don't have anything new)
What it should not do:
As a side effect for some, it is growing the size of the <canvas> on each click. It does it for me. But it doesn't do it for a lot of other people accessing this fiddle. Here is a screen shot:
Why is it doing this for some people and not others? How can I remedy this problem? If you are curious, I initially asked a question about something else about these charts, but this could be somewhat related.
Any clue what could be causing this in my browser and other browsers/computers?
Edit, I realize the fiddle is large, so this is what I am doing essentially:
// Assign and Create all canvas contexts
var ctx = $("#graph1").get(0).getContext("2d");
var ctx2 = $("#graph2").get(0).getContext("2d");
var ctx3 = $("#graph3").get(0).getContext("2d");
// Instantiate new charts and pass in generated data
var myChart = new Chart(ctx).Line(graph1Generator("day"));
var myDoughnutChart = new Chart(ctx2).Doughnut(graph2Generator("day"));
var myPieChart = new Chart(ctx3).Pie(graph3Generator("day"));
then I am adding (for each button) an event listener that destroys each canvas, and creates a new one with new information. Here is an example of the "week" button:
weekButton.addEventListener("click", function(){
myChart.destroy();
myChart = new Chart(ctx).Line(graph2Generator("Week"));
myDoughnutChart.destroy();
myDoughnutChart = new Chart(ctx2).Doughnut(graph2Generator("week"));
myPieChart.destroy();
myPieChart = new Chart(ctx3).Pie(graph3Generator("week"));
});

Wrap the element inside a wrapper and set its max-width to be 80% or as desired.
Turn off responsiveness.
Check out this fiddle and let me know whether you are still getting bloated chart on clicking re-renders.
<div class="wrapper">
<canvas id="graph1" width="300" height="300"></canvas>
<canvas id="graph2" width="250" height="250"></canvas>
<canvas id="graph3" width="250" height="250"></canvas>
</div>
.wrapper {
max-width: 80%;
}

I had the same behaviour defining padding definition to my canvas. I removed padding and I have no resizing now.

Related

document.createElement() without setting width and height

In order to avoid the bug in chart.js where hovering over tooltips is overwritting the graph with old ones, I want delete a canvas and create a new one inside a div when i click on a button, this happens in the click function:
var chartContainer = document.getElementById('ChartContainer_'+channelName);
var chart = document.getElementById('Chart_'+channelName);
chartContainer.removeChild(chart);
var graph = document.createElement("CANVAS");
graph.setAttribute("id", "Chart_"+channelName);
chartContainer.appendChild(graph);
My initial canvas looks like this:
<canvas id="Chart_Channel0"></canvas>
But if the click function is called it is creating a canvas looking like this:
<canvas id="Chart_Channel0" height="187" width="375"
style="display:block; height: 150px; width:300px;">
The canvas is inside of a modal, so the initial canvas seems to fit the size of the modal, but the new one stays too small.
Is it possible to create a canvas without all these parameters?

JS building up a city map

Alright so I got this issue.
I am currently making a City Map (village) for my game, but the problem is building placing. How do I achieve this?
Now im taking for example Ikariams map as an example, testing grounds. Now this is the map itself
http://www.mmoreviews.com/imgs/Ikariam-shot-1.jpg
Now how do I place the buildings in? Getting coordinates of where the building should be and then just fit in the building.png into it or?
A good solution for that is using the HTML5 Canvas element. That allows you to have a background image and draw other images on it. Drawing lines, circles is quite simple as well (that can be animated with javaScript).
You need the canvas itself:
<canvas id="canvas" width="800" height="600">
</canvas>
Some CSS:
canvas{
background-image: url('village.jpg');
}
And some lines in your <script>
var canvas = document.getElementById("canvas");
var map = canvas.getContext("2d"); //main object to draw
var house=new Image();
house.src='house.jpg';
house.onload=function(){
map.drawImage(house, 80,80); //actually drawing and giving coordinates
}
Hope it is helpful.

Clear HTML Canvas when new chart is displayed

So I am building an AngularJs chart that utilizes an Angular Library to create the chart on a Canvas tag. However when I drag and drop a new data set onto the canvas to redraw it continues to hold the old data. What I am trying to accomplish is If (there is new data){ clear the canvas}. I know I have to use:
canvasReset.clearRect(0, 0, canvas.width, canvas.height);
somewhere but what I am really looking for is an event handler to use to assist me in determining if anything is on the canvas, and if so clearing it. However, I am not looking for mouseover mouse-click,etc. But something that is just generally looking to see if the canvas is being utilized.
The short answer, you can't. But you can catch mouseevnets, or you can wrap canvas ctx drawing functions,like
var fill = ctx.fill;
ctx.fill = function(){
fill.apply(this, arguments);
setDirty();
};

ChartJs line chart repaint glitch while hovering over

I have the following code leveraging the ChartJS library.
/*assume the tags in the right place */
<canvas id="graph1" width="300" height="300"></canvas>
var ctx = $("#graph1").get(0).getContext("2d");
var myChart = new Chart(ctx).Line(graph1Generator("day"));
... everything works fine, but after adding the following event handler to clear and repaint the same chart with different data, a glitch occurs.
weekButton.addEventListener("click", function(){
ctx.clearRect (0, 0, 300, 300);
ctx.canvas.width = 300;
ctx.canvas.height = 300;
myChart = new Chart(ctx).Line(graph1Generator("week"));
This code does successfully redraw the chart with the new data, but when I hover over it, it does some very strange "flashbacks" to the old chart that it was supposed to clear. This makes me believe that it didn't clear the old one.
Here is an update to your fiddle. The primary change (other than fixing the function name typo) is to add
myChart.destroy();
before lines like
myChart = new Chart(ctx).Line(...);
The .destroy() method gets rid of the event handler registrations etc, so you shouldn't see those weird "ghost charts" when you mouse over the graphics.

Trying to change dynamically a context.clip(); in a HTML5 canvas

I'm trying to to change dynamically a context.clip(); in a HTML5 canvas, drawing a shape with different values from an array. The idea is to get different parts of a board-game illuminated one after the other, clipping a darker version of the board to see just a square of the clearer version.
That's the code I'm struggling with, based in other questions from this very site, but I really cannot find the error:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HTML5 Trivial</title>
<script type="text/javascript">
var strings = new Array();
strings[0] = "context.moveTo(134,487);context.lineTo(169,435);context.lineTo(200,449);context.lineTo(172,508);";
strings[1] = "context.moveTo(102,461);context.lineTo(142,414);context.lineTo(169,434);context.lineTo(133,485);";
strings[2] = "context.moveTo(71,434);context.lineTo(120,394);context.lineTo(143,414);context.lineTo(99,461);";
strings[3] = "context.moveTo(49,403);context.lineTo(101,370);context.lineTo(121,394);context.lineTo(70,435);";
strings[4] = "context.moveTo(19,340);context.lineTo(78,320);context.lineTo(99,370);context.lineTo(48,404);context.lineTo(31,375);";
strings[5] = "context.moveTo(172,507);context.lineTo(198,449);context.lineTo(231,458);context.lineTo(211,522);";
strings[6] = "context.moveTo(259,531);context.lineTo(267,466);context.lineTo(230,460);context.lineTo(213,521);";
strings[7] = "context.moveTo(257,531);context.lineTo(266,468);context.lineTo(300,470);context.lineTo(334,466);context.lineTo(347,531);context.lineTo(302,534);";
var images = new Array();
function draw(i){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var img = new Image();
img.src = 'board_dark.jpg';
img.onload = function() {
context.drawImage(img,0,0);
}
images[i] = new Image();
images[i].onload = function() {
eval(strings[Math.floor(Math.random()*6)]);
context.closePath();
context.clip();
context.drawImage(images[i],0,0);
i = i + 1;
window.setTimeout(function(){draw(i)},100);
}
images[i].src = 'board.jpg';
}
</script>
</head>
<body onLoad="draw(0);">
<canvas id="myCanvas" width="1024" height="1024"></canvas>
</body>
</html>
Am I coding terribly? I've been changing ways of writing, trying not to use the eval(), etc., without success...
Thank you for your help, as always!
Ramon
PD- Sorry for my English!
Your code is really really strange. I've redone some of it to give you a better idea of how to go about coding this (without using eval, for one!)
http://jsfiddle.net/p6tXv/
Now there is a general function that will draw from a list of points that you give it (they are the same points you supplied).
You almost certainly don't want to use clip and a dark image, instead you should be drawing over the board with semi-transparent black.
I wrote the code in such a way that it will black out the spots. If you want to black out everything except the spots then you will have to write a pat that is a little more complex, but it shouldn't be that hard.
Just a comment on the coding style; the use of eval() to call your context.moveTo logic is all kinds of bad. Check Google for various reasons on "why eval is bad"; it's been mentioned elsewhere numerous times.
Instead of storing commands, store the coordinates as polygon-style objects, and iterate through the points in order to achieve the desired result.
I realize that this could be a simple demo written to illustrate a specific purpose, but if you're sharing the code at all, then you'll be sharing bad code. Consider revising.

Categories

Resources