Changing width and height in angular-chart.js module - javascript

I'm using the angular module angular-chart.js. It is simple to work with and very smart. But I've noticed that I can't change the width and height of the charts. Somewhere I've read that I have to define the size of the chart as follows:
var vm = $scope;
vm.labels = [];
vm.data = [];
CrudService.getData(selDate).$promise.then(
function (response) {
angular.forEach(response, function (val) {
val.datum = $filter('date')(val.datum, 'dd.MM.yyyy');
vm.labels.push(val.datum);
vm.data.push(val.grade);
});
vm.dataChart = [vm.data];
/* This is the important part to define the size */
vm.options = [
{
size: {
height: 200,
width: 400
}
}
];
/************************************************/
});
The view:
<canvas id="bar"
class="chart chart-bar"
chart-data="dataChart"
chart-labels="labels"
chart-click="onClick"
chart-options="options">
</canvas>
Do anyone knows how to define the width and height in angular-chart.js ?

Ok I have tried this solution and it works.
<canvas id="bar"
height="100"
width="100"
class="chart chart-bar"
chart-data="dataChart"
chart-labels="labels"
chart-click="onClick"
chart-options="options">
</canvas>
Or defining the size as like a style in a CSS-class.

You can also wrap the <canvas> into a <div>, like so:
<div style="height:300px;width:300px;">
<canvas
class="chart chart-radar"
chart-data="$ctrl.data"
chart-options="options"
chart-labels="$ctrl.labels"></canvas>
</div>
Setting the width and height like in the other answers did not work for me.

To define height of charts according to the screen size, I use this code :
In controllers
$scope.height_chart = window.innerHeight*0.7;
In template
<canvas height="{{height_chart}}" class="chart chart-line" data="weight.data" labels="weight.labels" series="weight.series"></canvas>
I hope these codes will help.

The problem is that the height and width attribute values are stored in the chart and are not updated in the same way that the other attributes are. To fix this you have to add a listener to the create event and manually change the height in the chart object
HTML:
<canvas
id="chart"
class="chart chart-horizontal-bar"
chart-data="chart.data"
chart-labels="chart.data.labels"
chart-series="chart.series"
chart-options="chart.options"
chart-colors="chart.colors"
height="{{ compareChart.height }}"
width="{{ compareChart.width }}"
></canvas>
JS:
$scope.$on('chart-create', function (event, chart) {
chart.chart.height = $scope.chart.height;
});
You would expect $scope.chart.height to change during an AJAX lookup or something that will bring in new data.

Chart uses its parent container to update the canvas render and display sizes. However, this method requires the container to be relatively positioned and dedicated to the chart canvas only. Responsiveness can then be achieved by setting relative values for the container size

Related

How to properly resize the fabricjs without glitches?

I'm using fabricjs, and when I try to resize the whole canvas, I'm having troubles with some things. This is part of my code now:
<div id="cont2" class="cont2">
<div id="cont" class="container-div-canvas">
<canvas id="c" width="500" height="428"></canvas>
<div class="backgroundimage-div" id="bckimg-div"></div>
</div>
</div>
<script>
document.getElementById("resizecanvasbtn").onclick = () => {
document.getElementById("cont").style.width = "1000px";
document.getElementById("cont").style.height = "856px";
document.getElementById("cont2").style.width = "1000px";
document.getElementById("cont2").style.height = "856px";
document.getElementById("c").width = 1000;
document.getElementById("c").height = 856;
document.getElementById("c").style.width = "1000px";
document.getElementById("c").style.height = "856px";
document.getElementById("bckimg-div").style.width = "1000px";
document.getElementById("bckimg-div").style.height = "856px";
}
</script>
This is the canvas:
This is the canvas when I resize it:
And this is the result when I try to move a component that has been aded before the canvas resizing (the whole glitch is the result of when I move one element arround the canvas):
When I add an element after I resize the canvas, it automatically appears on another z-index (I think) and I can't even move it.
I'm not sure where I have the problem, or which thing I'm not having on mind when resizing the canvas.
Any suggestions on where to begin?
Thanks
It results that the document.getElementById("c").width = 1000; does not change the resolution of the canvas at all.
Instead how it needs to be done is with:
canvas.setWidth(1000);
That will change not only the canvas but the canvas-container and the upper-canvass divs that fabricjs generates automatically, which leads on the canvas size.
Hope it helps anybody:)

How to export Canva Render has GIF with CSS modification

I'm using p5.js to make a GIF animation but I have an issue when I want to export it.
I did a pixelased effect on my animation by adding these css properties to the Canva (140*140) :
image-rendering: pixelated;
width:500px;
height:500px;
My problem is that I can't export this Canva with the properties I added. (I'm using CCapture)
My gif is in 140x140 without the pixelated effect.
How can I get the rendering I need?
There is a difference between the width & height you can set for a HTML element e.g. <canvas width='140' height='140'> and the CSS width & height properties.
The former defines the actual size of the canvas - 140x 140in this case.
If we now set the CSS width & height to something deviating from the HTML element's width & height e.g. <canvas width='140' height='140' style='width: 500px; height:500px;'> the actual size in pixels of the canvas does not change - it stays 140 x 140 pixels. The CSS properties just control the displayed size of the element inside the browser, meaning the 140 x 140 are simply stretched to 500 x 500.
So if you get actual pixel data of the canvas - for exporting to gif/png - the final image will have the original dimensions of the canvas - not the rendered.
The fix is quite simple though. Instead of directly using the source canvas for exporting, draw it's content on a second canvas, the size of your desired resolution.
To force the 'export' canvas to not use any filtering/smoothing, you need to set the imageSmoothingEnabled property of it's context to false.
Here's an example (you can right-click and save both images to see the difference):
var ctx = document.getElementById('canvas').getContext('2d');
var image = new Image();
image.onload = function() {
ctx.drawImage(image, 0, 0);
let sourceCanvas = document.getElementById("canvas");
let virtualWidth = parseInt(getComputedStyle(sourceCanvas).width);
let virtualHeight = parseInt(getComputedStyle(sourceCanvas).height);
var canvas = document.getElementById("exportCanvas");
canvas.width = virtualWidth;
canvas.height = virtualHeight;
canvas.getContext('2d').imageSmoothingEnabled = false;
canvas.getContext('2d').drawImage(sourceCanvas, 0, 0, virtualWidth, virtualHeight);
}
image.src = 'https://mdn.mozillademos.org/files/12640/cat.png';
canvas {
width: 500px;
height: 500px;
}
<span>Rendered canvas</span><br>
<canvas id="canvas" width="140" height="140"></canvas><br>
<span>Export canvas</span><br>
<canvas id="exportCanvas"></canvas>

fabricjs - loadFromJSON not respecting scaling

So what's happening is that when I load my data from JSON, the scaling of X and Y aren't respected so when the object loads, it maintains its original height/width. Any reason for this and anyway to work around it?
The left rectangle should be larger than the right.
var canvas = new fabric.Canvas('c');
let json = {"objects":[{"type":"rect","originx":"left","originy":"top","left":323,"top":259,"width":50,"height":300,"fill":"#ff5b6d","stroke":null,"strokewidth":0,"strokedasharray":null,"strokelinecap":"butt","strokelinejoin":"miter","strokemiterlimit":10,"scalex":1.54,"scaley":1.54,"angle":0,"flipx":false,"flipy":false,"opacity":1,"shadow":null,"visible":true,"clipto":null,"backgroundcolor":"","fillrule":"nonzero","globalcompositeoperation":"source-over","transformmatrix":null,"skewx":0,"skewy":0,"rx":0,"ry":0},{"type":"rect","originx":"left","originy":"top","left":205,"top":198,"width":50,"height":300,"fill":"#ff5b6d","stroke":null,"strokewidth":1,"strokedasharray":null,"strokelinecap":"butt","strokelinejoin":"miter","strokemiterlimit":10,"scalex":1,"scaley":1,"angle":0,"flipx":false,"flipy":false,"opacity":1,"shadow":null,"visible":true,"clipto":null,"backgroundcolor":"","fillrule":"nonzero","globalcompositeoperation":"source-over","transformmatrix":null,"skewx":0,"skewy":0,"rx":0,"ry":0}]}
canvas.loadFromJSON(json);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.18/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>
var canvas = new fabric.Canvas('c');
let json = {"objects":[{"type":"rect","originX":"left","originY":"top","left":323,"top":259,"width":50,"height":300,"fill":"#ff5b6d","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.54,"scaleY":1.54,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0},{"type":"rect","originX":"left","originY":"top","left":205,"top":198,"width":50,"height":300,"fill":"#ff5b6d","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipy":false,"opacity":1,"shadow":null,"visible":true,"clipto":null,"backgroundcolor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0}]}
canvas.loadFromJSON(json);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.18/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>
fabricjs object property are in camel case. if you provide all with their proper key everything will work fine. I have changed your json data key to camel case. You can get all object property here.
Seems like you can manipulate each object as it's being built or something along that.
var canvas = new fabric.Canvas('c');
let json = {"objects":[{"type":"rect","originx":"left","originy":"top","left":323,"top":259,"width":50,"height":300,"fill":"#ff5b6d","stroke":null,"strokewidth":0,"strokedasharray":null,"strokelinecap":"butt","strokelinejoin":"miter","strokemiterlimit":10,"scalex":1.54,"scaley":1.54,"angle":0,"flipx":false,"flipy":false,"opacity":1,"shadow":null,"visible":true,"clipto":null,"backgroundcolor":"","fillrule":"nonzero","globalcompositeoperation":"source-over","transformmatrix":null,"skewx":0,"skewy":0,"rx":0,"ry":0},{"type":"rect","originx":"left","originy":"top","left":205,"top":198,"width":50,"height":300,"fill":"#ff5b6d","stroke":null,"strokewidth":1,"strokedasharray":null,"strokelinecap":"butt","strokelinejoin":"miter","strokemiterlimit":10,"scalex":1,"scaley":1,"angle":0,"flipx":false,"flipy":false,"opacity":1,"shadow":null,"visible":true,"clipto":null,"backgroundcolor":"","fillrule":"nonzero","globalcompositeoperation":"source-over","transformmatrix":null,"skewx":0,"skewy":0,"rx":0,"ry":0}]}
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), (o, object) => {
object.scale(o.scalex, o.scaley);
});
canvas.renderAll();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.18/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>

How to overlay Canvas with a Canvas dynamically?

i have a canvas dynamically written with no id assigned to it. How can i overlay image on the first canvas (out of multiple canvas) via JS ?
<canvas width="240" height="297">
<canvas id = "image_to_Overlay" width = "800" height = "500"></canvas>
In order to get the 1st canvas of the DOM using plain javascript you can use the good old function document.getElementsByTagName(). Then do what you want with it.
Probably it would be safer matching even on other attributes - such as class name - just to avoid getting the wrong canvas (jquery selectors would work great).
BTW the following should work
<html>
<head>
<script>
var image = new Image();
image.onload = function (){//react on image download completed
//you can get the 1st canvas of the DOM accessing the array of canvas
var canvas = document.getElementsByTagName("canvas")[0];
//then draw on it as needed
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
};
//load image
image.src = "http://i.imgur.com/ITWfejd.png";
</script>
</head>
<body>
<canvas width="240" height="297"></canvas>
<canvas id = "image_to_Overlay" width = "800" height = "500"></canvas>
</body>
</html>

Charts.js graph not scaling to canvas size

I'm trying to make a graph with Charts.js (current one is just a really simple example I'm trying to get working, somewhat taken from the Chart.js documentation) and the graph isn't scaling to the size of the canvas I'm giving it. Here is all the relevant code.
To import it:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.min.js"></script>
Then, I connect it to a javascript file as follows:
<script type="text/javascript" src="js/stats_tab.js"></script>
I have my canvas set up:
<div id="graph_2015" class ="stats_box">
<h4>Graph 2015</h4>
Text
<canvas id="myChart" width="200" height="200"></canvas>
</div>
And then finally in stats_tab.js, I have the following code:
window.onload=function(){
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [1,2,3,4,5,6,7,8,9,10],
datasets: [
{
label: "My First dataset",
data: [1,2,3,2,1,2,3,4,5,4]
}
]
},
options: {
}
});
}
The graph displays nicely, but it refuses to scale to the size of the canvas I gave it. There is also no css relevant to any of the divs involved. The inspect feature on chrome lets me know that the final graph is 676 by 676 instead of the 200 by 200 I specified. Not really sure what's going on.
Thanks!
The width and height property that you set for the canvas only work if the Chartjs' responsive mode is false (which is true by default). Change your stats_tab.js to this and it will work.
window.onload=function(){
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [1,2,3,4,5,6,7,8,9,10],
datasets: [
{
label: "My First dataset",
data: [1,2,3,2,1,2,3,4,5,4]
}
]
},
options: {
responsive: false
}
});
}
The important point is: width and height properties are not the size in px but the ratio.
<canvas id="myChart" width="400" height="400"></canvas>
In this example, it's a 1:1 ratio. So, if your html contenair is 676 px width then your chart will be 676*675px
That can explain some common mistakes.
You can disable this feature by setting maintainAspectRatio to false.
In your options, set the maintainAspectRatio to false, and responsive to true. This will initially try to scale your chart to match the dimensions of your canvas. If the canvas doesn't fit the screen, i.e. on mobiles, your chart will be re-scaled to fit on the page.
window.onload=function(){
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [1,2,3,4,5,6,7,8,9,10],
datasets: [
{
label: "My First dataset",
data: [1,2,3,2,1,2,3,4,5,4]
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
}
});
}
I had this exact same problem where my graph would not resize properly. To get around this issue I did two things.
Set the canvas tag style to a width and height of 100%. This will make sure that it always fits 100% of its containers width and height.
For the options value set responsive: true & maintainAspectRatio: false. This will make sure that the graph responds to updates in size while ignoring the aspect ratio.
below is the code I used:
css
#myGraph {
width: 100%;
height: 100%;
}
html
<canvas id="myGraph" />
When you initialise the chart with the ctx set the options as below:
options: {
responsive: true,
maintainAspectRatio: false
}
now when you resize your screen the graph should resize accordingly.
Note: The graph will fill the size of its container now so what ever you put your canvas into it will fill the size of that container.
A little late to the party, but I struggled with this problem a lot, particularly on a page with multiple charts.
This little tidbit solved it all - my charts all now fit nicely, and resize exactly with the divs they are in.
Add this to your page styles (The 8px is personal preference. Change if needed):
<style type="text/css">
#canvas-holder {
background-color: #FFFFFF;
position: absolute;
top: 8px;
left: 8px;
right: 8px;
bottom: 8px;
}
</style>
For the appropriate Divs:
<div id="canvas-holder">
<canvas id="chart-area"></canvas>
</div>
This should work. Basically, just add the width and height properties to your javascript:
var ctx = document.getElementById("myChart").getContext("2d");
ctx.canvas.width = 200;
ctx.canvas.height = 200;
var myChart = new Chart(ctx,.........
Reference: Chart.js canvas resize
Below code from Chart.js documentation worked for me.
"https://www.chartjs.org/docs/latest/general/responsive.html"
var ctx = document.getElementById('myChart').getContext('2d');
ctx.canvas.parentNode.style.width = "500px";
ctx.canvas.parentNode.style.height = "500px";
var myChart = new Chart(ctx, .....
If your <canvas> element doesn't have a width & a height "attribute" (not the css attribute). Try setting each of them them to 1 (Since its just a ratio)
<canvas id="activeUsersPieChart" width="1" height="1"></canvas>
The following worked for me, and I was able to keep the responsiveness of the chart!
var ctxx = document.getElementById("myChart");
ctxx.height = 80;
The real issue is that the canvas will re-scale responsively to its parent. I wanted to keep the responsiveness. So something like this will solve the issue:
<div style="width:50%">
<canvas id="myChart"></canvas>
</div>
Make a div element and place the chart canvas inside of it, name it as canvas-holder. See below:
<div id="canvas-holder">
<canvas id="myChart"></canvas>
</div>
Using CSS, specify the height and width of the canvas holder
#canvas-holder {
background-color: #FFFFFF;
position: absolute;
width: 400px;
height: 400px;
}
I was having an issue with the chart scaling down without refresh. Per the chart.js documentation, a container with relative positioning and vh/vw assigned height was needed.
My chart was previously in a flex container and I think that was causing a lot of my scaling issues
Detecting when the canvas size changes can not be done directly from
the canvas element. Chart.js uses its parent container to update the
canvas render and display sizes. However, this method requires the
container to be relatively positioned and dedicated to the chart
canvas only. Responsiveness can then be achieved by setting relative
values for the container size
<div class="chart-container" style="position: relative; height:40vh; width:80vw">
<canvas id="chart" style="width:100%; height:100%;"></canvas>
</div>
https://www.chartjs.org/docs/latest/configuration/responsive.html

Categories