chart is not rendering properly, canvasjs - javascript

I'm trying to render two dynamic charts using canvasJS, Chart one is rendering properly, in fact second chart is populating properly, please see the inspect element image, but it's not displaying on the page.
This is interface, just one chart is displaying
and here is inspect elem.
#adverts is rendering, but not displayed here.
.chartContainer{
height: 400px;
width: 100%;
}
PS I tried to commented out first chart rendering code, but not working at all, still displaying the first one only.
EDIT
Here is console log about what I'm getting back to render chart
here is snippet
function drawChart(obj, placeholder, From, To){
var legendFrom;
var legendTo;
if(From != 'undefined'){
legendFrom = From;
}
if(To != 'undefined'){
legendTo = To;
}
var dataPoints = [];
var from = [];
var to = [];
var advertFrom = [];
var advertTo = [];
for (var i = 0; i <= obj.length - 1; i++) {
if(obj[i].typeOf != 'undefined' || obj[i].typeOf != ''){
if(obj[i].typeOf == 'from'){
from.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
advertFrom.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:obj[i].adverts});
}else{
to.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
advertTo.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:obj[i].adverts});
}
}
else
from.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
}
var chart = new CanvasJS.Chart("chartContainer",
{
animationEnabled: true,
//theme: "theme1",
zoomEnabled: true,
title:{
text: placeholder
},
data: [
{
type: "spline", //change type to bar, line, area, pie, etc
showInLegend: true,
legendText: "From "+legendFrom,
dataPoints: from
},
{
type: "spline",
showInLegend: true,
legendText: "From "+legendTo,
dataPoints: to
}
],
legend: {
cursor: "pointer",
itemclick: function (e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
var adverts = new CanvasJS.Chart("adverts",
{
animationEnabled: true,
zoomEnabled: true,
title:{
text: placeholder
},
data: [
{
type: "column", //change type to bar, line, area, pie, etc
showInLegend: true,
legendText: "From "+legendFrom,
dataPoints: advertFrom
},
{
type: "column",
showInLegend: true,
legendText: "From "+legendTo,
dataPoints: advertTo
}
]
});
adverts.render();
}

I just replicated a canvasJS enviroment in JSFiddle
http://jsfiddle.net/fLbngdv9/1/
Make sure you are are using a new VAR for each chart.
var chart = new CanvasJS.Chart("chartContainer", {..});
chart.render();
var chart2 = new CanvasJS.Chart("chartContainer2", {..});
chart2.render();
Seems to work fine. If you can provide me with some code examples then perhaps I can help you find an answer.
Probably just a copy paste mistake but you have a syntax error at the very bottom.
...
adverts.render();
}
This should be
...
adverts.render();
Just remove the extra bracket. I updated the JS Fiddle to be more like your example... [here]
Edit:
I was able to replicate in my latest JSFiddle and I know this sounds crazy but when I changed the ID of your second div from adverts to chartContainer2 it worked fine.
Still investigating as to why this is but I would try renaming the ID on the div and also the reference for the graphs creation.
SEE HERE
Edit 2:
This appears to be a Chrome specific bug with the ID adverts. To replicate all you need to do is check out this link http://www.briangebel.com/test.html
(As you can see the div Adverts is hidden in Chrome but visible on FF,Opera,IE)
So what is happening..
Chrome's ADBlocker extension sees this ID and automatically adds an in page stylesheet.
This style sheet has the following Style
This only affects Chrome as it is caused by a specific extension. (I am attempting to contact the developer to see if he can resolve this but until then follow the below solution)
Solution
Simple don't use that ID. (You could simply disable AdBlocker but this extension is so widely used I would still recommend changing the ID)

Related

Highcharts AreaRange Chart issues with xAxis and last data point label

I used area range Highcharts but facing certain issues as:
For X-axis, the chart doesn't start with an initial point rather shows incorrect start tick value(i.e. 2020) instead of 2019.
Need to show label values for last data point only for each series, attached image below for reference
Could someone please help me with what do I do to resolve my issues.
Thanks in advance!
For the 1st issue, I tried changing the 'pointStart' attribute value for plotOptions->series but didn't work.
"plotOptions": {
"series": {
"pointStart": 1546300800000
}
}
Here is JSFiddle link of the chart containing code:
The first issue can be resolved by setting xAxsi.tickInterval = plotOptions.series.pointInterval:
xAxis: {
type: "datetime",
tickInterval: 31536000000
...
}
The second issue can be resolved by providing labels formatter callback function that will return only the last series point value. Also, other dataLabels properties have to be set properly (like align, overflow, etc). Check demo and code posted below.
Code:
dataLabels: {
enabled: true,
align: 'left',
verticalAlign: 'middle',
padding: 8,
allowOverlap: true,
overflow: 'allow',
crop: false,
formatter: function() {
var point = this.point,
series = this.series;
if (series.data.length === point.index + 1) {
return '$' + this.y.toFixed(1);
} else {
return '';
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/2xLevj6y/
API reference:
https://api.highcharts.com/highcharts/xAxis.tickInterval
https://api.highcharts.com/class-reference/Highcharts.DataLabelsOptionsObject#formatter
https://api.highcharts.com/class-reference/Highcharts.DataLabelsOptionsObject#align
https://api.highcharts.com/class-reference/Highcharts.DataLabelsOptionsObject#overflow

How to avoid detached HTMLCanvasElements when updating canvas with JavaScript?

So my problem is that when I'm cyclically updating canvas element in my HTML with line chart created by Chart.js library I'm getting bunch of detached HTMLCanvasElements. I noticed this when I was fixing some memory leaks in my code which earlier lead my webpage to crash(chrome gave "aw snap" error page).
I was able to fix most of the memory leaks but this one is still bothering me and I am helpless because of not knowing why this is happening..
I have canvas elements in my HTML code like this:
<div class="kuvaaja"><canvas id="etaisyyskuvaaja"></canvas></div>
<div class="kuvaaja"><canvas id="etaisyyskuvaaja2"></canvas></div>
<div class="kuvaaja"><canvas id="etaisyyskuvaaja3"></canvas></div>
<div class="kuvaaja"><canvas id="etaisyyskuvaaja4"></canvas></div>
And this is how I fetch those elements in my JavaScript (in window.onload function):
pohjacanvas = document.getElementById("etaisyyskuvaaja");
pohjacanvas2 = document.getElementById("etaisyyskuvaaja2");
pohjacanvas3 = document.getElementById("etaisyyskuvaaja3");
pohjacanvas4 = document.getElementById("etaisyyskuvaaja4");
Then I start cyclic updating of those canvases with(also inside window.onload):
paivitysvali = setInterval(haeetaisyysmittaukset, 1000);
painepaivitys = setInterval(haepainemittaukset, 1000);
And in these functions I first fetch data from database like this (haepainemittaukset() is similar to this one just different data is fetched):
function haeetaisyysmittaukset() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
etaisyys = [];
ajat = [];
var mittaukset = JSON.parse(xmlhttp.response);
for (var i = 0; i < mittaukset.length; i++) {
etaisyys.push(mittaukset[i]["etaisyys"]);
ajat.push(mittaukset[i]["timestamp"]);
}
if (paivitysbitti == 1) {
etaisyys.reverse();
ajat.reverse();
luokuvaaja2(pohjacanvas, etaisyys, ajat);
luokuvaaja2(pohjacanvas4, etaisyys, ajat);
}
}
}
xmlhttp.open("POST", "haeetaisyysmittaukset.php", true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send("limit=" + mittausmaara);
}
After data is fetched in global arrays (etaisyys[] and ajat[]) I call luokuvaaja2() function with the canvas I want to update and these data arrays. And this is the phase where problem starts at least I think so.. Here is how I am trying to implement this update of canvas:
function luokuvaaja2(pohja, data, ajat) {
pohja.height = 400;
pohja.width = 700;
myChart = new Chart(pohja, {
type: 'line',
data: {
labels: ajat,
datasets: [{
data: data,
label: "Etaisyys",
borderColor: "blue",
fill: false
}
]
},
options: {
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
title: {
display: true,
text: 'Etaisyysmittaus'
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 6000
}
}]
}
}
});
}
So what I think that I'm doing here is setting canvas height and width, after that I create new chart in the same canvas where old one was(or am I?). However it looks like that there is something wrong and my current code is creating bunch of detached canvas elements but I can't understand why and where this is exactly happening? So now memory footprint of my page is slowly increasing after every cycle (canvas update).
Here is also snapshot of memory distribution:
memory distribution
In this memory distribution there are many detached canvas elements all pointing to those canvases(pohjacanvas, pohjacanvas2, pohjacanvas3, pohjacanvas4).
You should keep track (in an array, for example) of your charts previously created, then when the new data is fetched from the server, you need to retrieve the chart to update, update its data and/or options, and then call
chart.update();
to refresh the chart. In this case you won't create new charts at each update.
You may find more details in the Chart.js docs.

Hide Highcharts labels on resize and enlarge the chart

I have a funnel chart that I need to extend through the whole container div when the page gets resized (and becomes thin)
I tried to programmatically hide the label on resize but the chart would still remain in a side of the div
https://jsfiddle.net/MicheleC/9oh3ttss/7/
function toogle_chart_label(chart, series, show){
var opt = chart.series[series].options;
if(typeof show == 'undefined') {
opt.dataLabels.enabled = !opt.dataLabels.enabled;
} else {
opt.dataLabels.enabled = show
}
}
function funnel_labels_adjust(){
if($('#container').width() < 300){
toogle_chart_label(funnel_chart, 0, false)
} else {
toogle_chart_label(funnel_chart, 0, true)
}
}
$( window ).resize(function() {
funnel_labels_adjust()
});
In Highcharts 5 there is a new property responsive. It allows you to specify the chart options which will be applied under some conditions.
In your case, you want to to disable data labels when the chart has width below 300.
responsive: {
rules: [{
condition: {
maxWidth: 300
},
chartOptions: {
plotOptions: {
funnel: {
dataLabels: {
enabled: false
}
}
}
}
}]
}
example: https://jsfiddle.net/9oh3ttss/8/
If you dont want to use that feature, you need to use dynamic methods like series.update()
series[0].update({
dataLabels: {enabled: false / true}
});

Bar chart looks bad before change data

Hi here I set the data to the bar chart:
setDatosBarra: function(data){ //
var self = this;
var horaEstim = 0;
var horaReal = 0;
var horaTotal = 0;
if(data[0].horas_estim != '-'){
horaEstim = data[0].horas_estim;
}
if(data[0].horas_real != '-'){
horaReal = data[0].horas_real;
}
if(data[0].total_horas != '-'){
horaTotal = data[0].total_horas;
}
var datosBarra =[{data: [[0,horaEstim]], color: "#691717"}, {data: [[1,horaReal]], color: "#173D69"},{data: [[2,horaTotal]], color: "#176469"}];
self.flotLinea(datosBarra);
},
When all is ready I send the data to self.flotBar;
This is the flotBar function:
flotBar: function(datos){
var self = this;
if(datos == 0){
var data = [["SIN REGISTROS",0]];
}else{
var data = datos;
}
function getTooltip(label, x, y) {
return "<strong style='font-size:18px;'> " + y + " </strong> horas";
}
var plot = $.plot("#placeholder",data, {
series: {
bars: {
show: true,
barWidth: 0.3,
align: "center",
lineWidth: 0,
fill:.75
}
},
xaxis: {
ticks: [[0,"Horas estimadas"],[1,"Horas reales"],[2,"Total horas"]],
mode: "categories",
tickLength: 0
},
grid: {
hoverable: true,
clickable: true
},
tooltip: true,
tooltipOpts : {
content : getTooltip,
defaultTheme : false
},
});
},
Ok , and this is my problem, example:
I select a option in an dropDown:
And the bar chart looks like this:
If I select other option in the dropDown:
The bar chart looks like this:
And if I select again the first option "Correcion de errores", the bar chart looks like this:
So.. always the first time that I show the bar chart looks like in the first image , with the numbers in the line, but If I select other option looks good.
I need see good the bar chart always and no just when I select other option.
I'm using flot javascript library.
How can I fix this? sorry by my english
The main issue with the question as stated is that we do not have all the code. In essence, you should either provide all the code, or shrink down the problem to something that shows the issue and then, well, provide all the code. As far as I can guess, you have some other code somewhere else that is drawing the initial chart. The second and subsequent times? Drawn properly. To support my assertion, notice that in your initial image the captions for the x-axis tick markers (ditto the bars themselves) are right aligned not centered.
For fun, I wrote a quick jsFiddle that showed how to switch datasets using a button (much as you want to do with the drop-down) and redraw the chart:
drawChart = function(index) {
var chartData = getDataForChart(rawData[index]);
if (chart) {
chart.setData(chartData);
chart.draw();
}
else {
chart = $.plot("#barchart", chartData, chartOptions);
}
},
switchDataset = function() {
datasetIndex = (datasetIndex + 1) % datasetCount;
drawChart(datasetIndex);
};
$("#switchButton").on("click", switchDataset);
Because I decided to load new data into the chart rather than redraw it all from scratch (to be honest I saw no real difference either way), it meant that I had to pre-calculate the maximum value for the y-axis:
calcValueMax = function() {
var max = 0;
rawData.forEach(function(values) {
values.forEach(function(value) {
if (value > max) {
max = value;
}
});
});
return max;
},
// other code
chartOptions.yaxis.max = calcValueMax();
Hope that helps.

Highcharts Column Series Point Object Click Function

Recently I posted a question on Highcharts column charts drilldown. I have found that in click event of point object you can find out which column was clicked. I have implemented the same in my code but I am not getting alert in my code. Please find below my code. First is my chart options variable -
var columnoptions = {
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text: 'Column Chart'
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Exposure'
}
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
alert ('here');
}
}
}
}
},
series: []
};
I am filling the series dynamically with below statements in a loop -
columnoptions.xAxis.categories.push(categoryArray[index]);
seriesOptions.data.push(valueArray[index]);
Finally I display my chart like this -
chart = new Highcharts.Chart(columnoptions);
But I am not getting any alert on column click. I get error javascript error messages in IE. I am using IE8. Kindly help me with this. Highcharts official example with static data works fine and I have seen that. My chart displays correctly without any issues. But I need to know which column was clicked to implement drilldown functionality. Please help.
---Edit
Here is the full function I am using to draw the charts-
function displayColumnChart(){
columnoptions.series = [];
columnoptions.xAxis.categories = [];
var seriesOptions = {
name: 'Column Chart',
data: [],
};
/* category array contains x axis category values
value array contains y axis numeric values */
for(index = 0; index < categoryArray.length; index++){
columnoptions.xAxis.categories.push(categoryArray[index]);
seriesOptions.data.push(valueArray[index]);
}
columnoptions.series.push(seriesOptions);
chart = new Highcharts.Chart(columnoptions);
}
I am reading my data from an XML doc and then creating value and category array. Chart comes fine but not getting alert on point click. Please help. Thanks. :) Sorry for delay in posting the code.
I only added the latest version of the highcharts and point click is working for me. Thanks.

Categories