Diagram interval goes slower and slower (Canvas.JS) - javascript

The problem I am encountering is that when I click to view the diagram via JQuery event click, the diagram works fast and smoothly, but if I double click or perhaps click 10 times, for each click the diagrams runs slower and slower. That is to say the click is dependend on the diagram performance. I believe the $.getscript() is causing this low performance, or poor JQuery code..
JQuery event below is responsible for displaying the diagram. Keep in mind that the user has the oppertunity to navigate between the diagrams, they can only view one diagram once.
$('[data-row]').on('click', function() {
var row = $(this).attr('data-row');
$('.active').removeClass('active'); // Displaye:none
$('#table' + row).addClass('active'); // Display:block
if(row == 1){
$.getScript("diagram1.js"); // Display diagram1
} else {
}
});
This is diagram1.js.
(function (){
$(document).ready(function(){
var dps = []; // data
var chart = new CanvasJS.Chart("diagram1 ",
{
title:{
text: "Exhaust Temperature"
data: [
{
type: "spline",
name: "Temp Cylinder 1",
showInLegend: "true",
legendText: "Temp Cylinder 1",
dataPoints: dps1
}
});
var xVal = 0;
var updateInterval = 50;
var dataLength = 50;
var updateChart = function (count) {
count = count || 1;
for (var j = 0; j < count; j++) {
dps.push({
x: xVal,
y: EXTS[1]
});
xVal++;
};
if (dps.length > dataLength )
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
});
}());

Related

Multiple charts with same data not loading in same page: Highcharts

I am trying to display Highchart having same data in custom no. of times, Say I want to display the chart 2 times in same pagedynamically.
What I have done is that I set the chart in for loop in which I can repeat the chart multiple times dynamically.
Here is the Script That I have tried.
var len = 2 ;
var chartArea = document.getElementById("content");
for(var i=0;i<len;i++)
{
console.log("I", i);
chartArea.innerHTML +=
'<div id="container'+i+'"></div>';
var categories = ["1","2","3","4","5","6","7","8","9","10"];
Highcharts.stockChart('container'+i, {
rangeSelector: {
enabled: false
},
xAxis: {
labels: {
formatter: function() {
return categories[this.value];
}
}
},
navigator: {
xAxis: {
labels: {
formatter: function() {
return categories[this.value];
}
}
}
},
plotOptions: {
series: {
animation: {
duration: 2000
},
marker:{
enabled: false
}
}
},
series: [{
data: [3,5,3,6,2,6,4,9,4,6]
}]
});
But the problem is that only last graph shows the line chart. the other first chart have the x-axis labels bu the line graph is not showing.
Here is the Fiddle That I have tried.
http://jsfiddle.net/abnitchauhan/cenmohbw/
You forgot to append the child to the DOM tree.
When you create a new HTML element dynamically, it needs to be attached to an existing node in the DOM tree.
In Javascript you can do:
var existingNode = document.getElementById("content");
var newElement = document.createElement("div");
newElement.id = "someID";
existingNode.appendChild(newElement);
In jQuery, its more easy:
$("#content").append(`<div id="someID"></div>`);
In your case, the change would look like (only for loop changes) as:
for (var i = 0; i < len; i++) {
console.log("I", i);
$("#content").append(`<div id="container${i}"></div>`);
// rest of your code

dc.js - Chart not rendering (single row bar chart - horizontal row), with the exception of legend, axes and tick marks/values (which do render)

Scenario
I want to see my dc.js horizontal row stacked bar chart (single row chart), but no chart appears, except for legend with names, axes with tick marks which do appear.
Screenshot
Data set below in code snippet
Question
How do I render the ensure chart rendering successfully using dc.js / d3.js?
Code Snippet
$scope.avgCycleTime = function(){
var data = [
{"Project":"Expedition","Stage": "Created", "Days":12},
{"Project":"Expedition","Stage": "Active", "Days":14},
{"Project":"Expedition","Stage": "Closure", "Days":2}
];
var ndx = crossfilter(data);
data.forEach(function(x) {
x.Days = 0;
});
var ndx = crossfilter(data)
var xdim = ndx.dimension(function (d) {return d.Days;});
function root_function(dim,stack_names) {
return dim.group().reduce(
function(p, v) {
stack_names.forEach(stack_name => {
if(v[stack_name] !== undefined)
p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name]
});
return p;},
function(p, v) {
stack_names.forEach(stack_name => {
if(v[stack_name] !== undefined)
p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name]
});
return p;},
function() {
return {};
});}
var stages = ['Created', 'Active', 'Closure'];
var ygroup = root_function(xdim,stages)
function sel_stack(i) {
return function(d) {
return d.value[i];
};}
cycleChart = new dc.barChart("#risk-cycle-chart");
var chart = document.getElementById('risk-cycle-chart');
heightStatusChart = 200;
widthStatusChart = Math.floor(parseFloat(window.getComputedStyle(chart, null).width))
- 2*parseInt(window.getComputedStyle(chart, null).getPropertyValue('padding-top'));
cycleChart
.x(d3.scaleLinear().domain([0,7,14,21,28]))
.dimension(xdim)
.group(ygroup, data[0].Project, sel_stack(data[0].Project))
.xUnits(dc.units.ordinal)
.margins({left:75, top: 0, right: 0, bottom: 20})
.width(widthStatusChart)
.height(heightStatusChart)
.legend(dc.legend());
for(var i = 1; i<stages.length; ++i)
cycleChart.stack(ygroup, stages[i], sel_stack(stages[i]));
}
Sigh, I guess dc.js and crossfilter have a steep learning curve. There isn't any "interesting" problem here, just a bunch of minor glitches:
dc.barChart is not a constructor. Use either new dc.BarChart(...) or dc.barChart(...)
You are zeroing out d.Days, which is the field your dimension uses, so there will only be one bin.
Your x scale should match your xUnits, so d3.scaleOrdinal not d3.scaleLinear.
You have changed your data from having separate fields for Created, Active, Closure to one field named Stage. With this format of data, your reducers could look like
function root_function(dim, stack_field, stack_names) {
return dim.group().reduce(
function(p, v) {
p[v[stack_field]] = p[v[stack_field]] + 1; // 2
return p;},
function(p, v) {
p[v[stack_field]] = p[v[stack_field]] - 1; // 3
return p;},
function() {
return Object.fromEntries(stack_names.map(sn => [sn,0])); // 1
});}
Initialize each bin with a field for each of the stack_names with value 0
When adding a row to a bin, determine which field it affects using stack_field; increment that field
When removing a row from a bin, decrement the same way
You are requesting an x domain of [0,7,14,21,28] but none of your Days fall exactly on those values. If you want to round down, you could do
var xdim = ndx.dimension(function (d) {return Math.floor(d.Days/7)*7;});
.group(ygroup, data[0].Project, sel_stack(data[0].Project)) doesn't make sense since you are stacking by Stage, not by Project; this should be .group(ygroup, stages[0], sel_stack(stages[0]))
With the above changes, we get a chart with one stack in each of the first three bins:
Demo fiddle.
I resorted to not using a vector graphics generator like d3/dc for this grid portion and instead created a table like so.
$scope.avgCycleTime = function(){
var data = [
{"Project":"Expedition","Stage": "Created", "Days":12, "Color": "rgb(166, 206, 227)"},
{"Project":"Expedition","Stage": "Active", "Days":14, "Color": "rgb(253, 180, 98)"},
{"Project":"Expedition","Stage": "Closure", "Days":2, "Color": "rgb(179, 222, 105)"}
];
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
// table row creation
var row = document.createElement("tr");
for (var i = 0; i <= 2; i++) {
// create element <td> and text node
//Make text node the contents of <td> element
// put <td> at end of the table row
var cell = document.createElement("td");
cell.setAttribute('style', 'width: ' + data[i].Days * 100 + "px; background-color: " + data[i].Color);
var cellText = document.createTextNode(data[i].Stage + " " + data[i].Days);
cell.appendChild(cellText);
row.appendChild(cell);
}
//row added to end of table body
tblBody.appendChild(row);
// append the <tbody> inside the <table>
tbl.appendChild(tblBody);
// put <table> in the <body>
document.querySelector("#risk-cycle-chart").appendChild(tbl);
}

Zingchart last element keeps changing color and not matching with legend

My zingchart's last element's color does not match with legend, and keeps on changing unlike the others. Any Ideas? Everything else works good. Though I'm parsing this data through MySQL database, this is how the JavaScript looks like.
My code:
<script>
var myData = ["12","15","7","20","2","22","10","7","7","10","8","15","9"];
var myData = myData.map(parseFloat);
var myLabels = ["General Verbal Insults","General Beatings\/Pushing","Terrorizing\/Threatening Remarks","False Gossip Inflation (Rumors)","Discrimination","Rough Fighting","Sexual Utterance\/Assaults","General Exclusion","Theft","Racist Utterance\/Assaults","Personal Property Damage","Internet Related (Cyber)","Other\/Unspecified"];
window.onload=function(){
var colorCharacters = "ACDEF0123456789";
var globalStylesArray = [];
var myConfig = {
type: "bar",
legend:{},
title: {
"text":"Showing Results For: Canada",
"color":"green"
},
subtitle: {
"text":"Total Bullying Incidents In Country: 144",
"color":"blue"
},
series : [{"values":[ myData[0] ],"text":"General Verbal Insults",},{"values":[ myData[1] ],"text":"General Beatings/Pushing",},{"values":[ myData[2] ],"text":"Terrorizing/Threatening Remarks",},{"values":[ myData[3] ],"text":"False Gossip Inflation (Rumors)",},{"values":[ myData[4] ],"text":"Discrimination",},{"values":[ myData[5] ],"text":"Rough Fighting",},{"values":[ myData[6] ],"text":"Sexual Utterance/Assaults",},{"values":[ myData[7] ],"text":"General Exclusion",},{"values":[ myData[8] ],"text":"Theft",},{"values":[ myData[9] ],"text":"Racist Utterance/Assaults",},{"values":[ myData[10] ],"text":"Personal Property Damage",},{"values":[ myData[11] ],"text":"Internet Related (Cyber)",},{"values":[ myData[12] ],"text":"Other/Unspecified",}]
};
zingchart.render({
id : 'myChart',
data : myConfig,
width:"100%",
height:500,
});
zingchart.gload = function(p) {
console.log(p);
var graphId = p.id;
var graphData = {};
graphData = zingchart.exec(graphId, 'getdata');
graphData = graphData.graphset[0] ? graphData.graphset[0] : graphData;
console.log(graphData);
createColors(graphData.series[0].values.length);
zingchart.exec(graphId, 'modifyplot', {
data: {
styles: globalStylesArray
}
});
}
function createColors(seriesLength) {
console.log('-------createColor seriesLength: ', seriesLength);
globalStylesArray = [];
for (var i = 0; i < seriesLength; i++) {
var colorString = '#';
for (var j = 0; j < 6; j++) {
colorString += colorCharacters.charAt(Math.floor(Math.random() * (colorCharacters.length - 4)));
}
globalStylesArray.push(colorString);
}
console.log('-----globalStylesArray-------', globalStylesArray);
}
};
</script>
Referring to the comment on the OP:
I just want all color to be different, since i dont know how many elements are in MyData - its generated through PHP & MYSQL
If you just want all of the colors to be different, remove the zingchart.gload function and the createColors function. ZingChart will create different colors for each series dynamically.
If you do want to specify each of those colors ahead of time since you do not know how many series your data will produce, you will need to apply a theme to your chart configuration: http://www.zingchart.com/docs/design-and-styling/javascript-chart-themes/

How to transfer Javascript code correctly?

I have two codes, both generate a line chart. However, the first one doesn't use mysql datasource, it uses random math generated datapoints. But it uses a refresh interval and thus is live.
The second code does in fact use a mysql datasource and displays the data in my database in the line-chart. However it is not live, because it does not it has not refresh-interval function.
I was trying to transfer the refresh-Interval / chart-update code parts of the first code to my second code that is not live but uses a real data source.
Here is my live code, with random datapoints:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js">`
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer2",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
</script>
This is my code of the static line chart (not live) but uses real data source:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js">`
</script>
<script type="text/javascript">
$().ready(function () {
$.getJSON("arduino_data.php", function (result) {
var dataPoints = [];
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
}
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
chart.render();
});
});
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
This is what I have tried so far:
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"> </script>
<script type="text/javascript">
$().ready(function () {
$.getJSON("arduino_data.php", function (result) {
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
var dataPoints = [];
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
};
}
if (dataPoints.length > dataLength)
{
dataPoints.shift();
}
chart.render();
)};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width:100%;">
</div>
</body>
</html>
But it keeps saying
Unexpected token ')' at line 42
chart.render();
)};
I am pretty embarrassed but I can't find the solution due to all the bracelets/parenthesizes. I have tried everything. With ) and without } but nothing seems to deliver.
If this is solved, will the chronological positions of the code be alright?
EDIT: FIRST PROBLEM SOLVED, NEW PROBLEM: JS POSITIONING
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"> </script>
<script type="text/javascript">
$().ready(function () {
$.getJSON("arduino_data.php", function (result) {
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
var dataPoints = [];
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
};
}
if (dataPoints.length > dataLength)
{
dataPoints.shift();
}
chart.render();
});
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(updateChart, updateInterval);
});
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width:100%;">
</div>
</body>
</html>
output:
Can't find variable: updateChart
You used )}; instead of });
also at the end of your JS you used only } instead of });
also call your chart like
setInterval(updateChart, updateInterval);
and make sure your updateInterval is in the right function scope.
Here's how it should approximately look like:
jQuery(function ($) {
function updateChart( result ) { // move it here!!!
$.getJSON("arduino_data.php", function( result ){
var dataPoints = [];
var dataLength = 500; // number of dataPoints visible at any point
var updateInterval = 1000;
var chart = new CanvasJS.Chart("chartContainer",{ // new chart Object
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
}
if (dataPoints.length > dataLength){
dataPoints.shift();
}
chart.render();
});
}
// First read - Start
updateChart();
// Update chart after specified time.
setInterval(updateChart, updateInterval);
});

Jquery Highcharts is not loading when using with common function?

I am working with jquery HighCharts. I want to create a common function to develop multiple charts of same type.
To achieve this goad I created a function as follow -
function generateGraph(data) {
var dates = new Array();
var startDate = "";
for (var i = 0; i < data.length; i++) {
dates[i] = data[i].date;
}
var productInsight = _comm.getProductInsightArray();
var productInsight_Array = new Array();
$.each(productInsight, function(key, value) {
productInsight_Array.push(key);
});
if(dates.length > 0) {
startDate = dates[0].split("/");
}
intervals = 24 *3600 * 1000; //one day
var title = $("#DateSearch_analytics_Similar_Stores1").val();
var color = ['#000000', '#FFFFFF', '#000080', '#0000FF', '#808080'];
var containers =['container1', 'container2','container3','container4', 'container5', 'container6', 'container7', 'container8', 'container9'];
for(var j=0; j<containers.length; j++)
{
var chart = new Highcharts.Chart({
chart: {
zoomType: 'x',
renderTo: containers[j],
type: 'line',
},
title: {
text: title
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' :
'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime',
tickInterval: intervals,
},
series: []
});
for(var i=0; i < productInsight_Array.length; i++) {
var fillData = new Array();
var counter = 0;
var productValue = document.getElementById('product-nm').value;
$.each(dates, function() {
fillData[counter] = _comm.randomNumberFromRange(_randomNumberStartRange, _randomNumberEndRange);
counter++;
});
chart.addSeries({
name: productInsight_Array[i],
type: 'line',
color: color[i],
pointStart: Date.UTC(startDate[2], startDate[0] - 1, startDate[1]),
pointInterval: intervals,
data: fillData,
});
}
$("text:contains('Highcharts.com')").css("display", "none");
}
}
Its working fine and developing charts on window load and button click. I am saving these graph in 9 container but this script is not loading graph in 3rd container and when I remove 3rd container than its not loading in fourth and so on. But it works fine when I call this function on button click in place of document load.
I am little surprised why its happing, As a common function creting all graphs.
I need your help! :(
Thanks
The problem is when load the function your markup doesnt exists. For this reason when you click the button works ok. When the button is visible, all markup is already loaded.
Review your load order.
Also aside comment: put this in your chart declaration:
credits: {
enabled: false
}
To not show the credits message: "Highcharts.com".
An example

Categories