plotly js globals not being available to other function - javascript

This is usually a simple problem to solve with a global var. But nooooo...
All the code works, the csv is read in, the arrays created with the correct values (x,y), a default graph is drawn, but the newPlot function vars are not acting like globals and are empty, so the plot is an empty default of 6x6 with no traces. The newPlot vars are globals. Is plotly.js different? Line 63 is the culprit. This code is pretty much a clone of: plotlyHover
<!DOCTYPE html>
<html lang="en" >
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<div id="myDiv"></div>
<div id="hoverinfo" style="margin-left:80px;"></div>
<!-- cloudcover.csv looks like this.
Time,CloudCover
2022-04-06 10:07:09,0
2022-04-06 11:07:18,100.0
2022-04-06 12:08:17,100.0
2022-04-06 13:09:16,96.0
2022-04-06 14:10:15,66.0
2022-04-06 15:11:14,7.0
-->
<script>
var traces = [];
var layout = {};
var config = {};
const CSV = "cloudcover.csv";
Plotly.d3.csv(CSV, function(rows) {
let x = [];
let y = [];
let row;
let i = 0;
while (i < rows.length) {
row = rows[i];
x.push(row["Time"]);
y.push(row["CloudCover"]);
i += 1;
};
traces = [{
x: x,
y: y,
line: {
color: "#387fba"
},
width: 16,
}];
layout = {
title: 'Cloudcover',
yaxis: {
range: [0, 100]
},
xaxis: {
tickformat: "%H:%M:%S"
}
};
config = {
responsive: true
};
});
Plotly.newPlot('myDiv', traces, layout, config, {
showSendToCloud: true
});
var myPlot = document.getElementById('myDiv')
hoverInfo = document.getElementById('hoverinfo')
myPlot.on('plotly_hover', function(data) {
var infotext = data.points.map(function(d) {
return (d.data.name + ': x= ' + d.x + ', y= ' + d.y.toPrecision(3));
});
hoverInfo.innerHTML = infotext.join('<br/>');
})
myPlot.on('plotly_unhover', function(data) {
hoverInfo.innerHTML = '';
});
</script>
</body>
</html>

Related

Using Chart.Js to plot a scatter plot from an Array

I have written the following code:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = viewport" content ="width=device-width, intial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content = "ie=edge">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<link rel ="stylesheet" href = "https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<title>My Chart.js</title>
</head>
<body>
<div class = "container">
<canvas id="myChart"></canvas>
</div>
<script>
var c = [];
var randomNumber = Math.random()*190;
function getRandomDataPoint(x){
if (x == "x"){
var _return
return Math.random()*20;
}
else if (x == "y"){
return Math.random()*10 + randomNumber;
}
else{
}
}
var xPoints = [];
var yPoints = [];
var storage = [];
for(var i=0;i<100;i++)
{
xPoints[i] = Math.random()*20;
yPoints[i] = Math.random()*10 + randomNumber;
x = xPoints[i];
y = yPoints[i];
var json = {x: x, y: y};
storage.push(json);
}
var concatenatedArray = xPoints.concat(yPoints);
let myChart = document.getElementById('myChart');//.getContext('2d');
Chart.defaults.global.defaultColor = '#000000';
let massPopChart = new Chart(myChart, {
type: 'scatter',
data: {
datasets: [{label: 'Data Set', data: [storage]}],
},
options: {
scales: {
yAxes: [{
ticks: {
max: 200,
min: 0,
beginAtZero:true
},
}]
}
}
});
</script>
</body>
</html>
What I would like for this code to do is take 100 random data points and plot them using the for-loop depicted in the code. The issue is the current set of code does create the axis however no data appears to be plotted.
Thank you for any help.
Best Regards
The problem is in how you pass your data values to Chart.js on this line:
datasets: [{label: 'Data Set', data: [storage]}],
Specifically, data is supposed to be an array of objects. Because you have added the square brackets ([]) you are passing an 'array of array of objects'.
The problem can be fixed simply by removing the brackets:
data: storage

Uncaught TypeError: Cannot read property 'append' of null

I recreated the ploytly.js dropdown graph here:
https://plot.ly/javascript/dropdowns/#bind-dropdown-events-to-plotlyjs-charts
I copy and pasted the code in my app and it worked perfectly.
Now I just want to duplicate the graph and put it below the original. Here is the html:
<div class="showcase__section" id="bubble">
<div class="spacer --small"></div>
<div id="bubbleplots">
<div class="bubbleplot" data-num="0">
<div class="plot" id="plotdiv"></div>
<div class="control-row">
Country: <select class="countrydata">
</select>
</div>
</div>
</div>
</div>
<div class="showcase__section" id="bubble">
<div class="spacer --small"></div>
<div id="bubbleplots">
<div class="bubbleplot" data-num="0">
<div class="plot1" id="plotdiv1"></div>
<div class="control-row">
Country: <select class="countrydata1">
</select>
</div>
</div>
</div>
I changed 3 of the divs so the javascript can tell them apart.
Below is the javascript. Again, I changed the names of the some the variables of the second graph. Otherwise, the javascript of the first and second graph is identical.
The first graph shows up perfectly in my app, but there's an issue with the second graph. The second graph shows up, and the data is correct on the graph and the popup menu shows up but with no country names. I console.log('currentOption1') of the second graph three separate times.
The first two times the console returns as expected, but the third time it shows 'Uncaught TypeError: Cannot read property 'append' of null'. So the problem lies with
selector.appendChild(currentOption1);
Again,
selector.appendChild(currentOption);
works perfectly with the first graph.
So currentOption1 is null. Why, and how do I fix it?
Here is a link to the two graphs
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv', function(err, rows){
function unpack(rows, key) {
return rows.map(function(row) { return row[key]; });
}
var allCountryNames = unpack(rows, 'country'),
allYear = unpack(rows, 'year'),
allGdp = unpack(rows, 'gdpPercap'),
listofCountries = [],
currentCountry,
currentGdp = [],
currentYear = [];
for (var i = 0; i < allCountryNames.length; i++ ){
if (listofCountries.indexOf(allCountryNames[i]) === -1 ){
listofCountries.push(allCountryNames[i]);
}
}
function getCountryData(chosenCountry) {
currentGdp = [];
currentYear = [];
for (var i = 0 ; i < allCountryNames.length ; i++){
if ( allCountryNames[i] === chosenCountry ) {
currentGdp.push(allGdp[i]);
currentYear.push(allYear[i]);
}
}
};
// Default Country Data
setBubblePlot('Afghanistan');
function setBubblePlot(chosenCountry) {
getCountryData(chosenCountry);
var trace1 = {
x: currentYear,
y: currentGdp,
mode: 'lines+markers',
marker: {
size: 12,
opacity: 0.5
}
};
var data = [trace1];
var layout = {
title: 'GDP per cap according to Country<br>'+ chosenCountry + ' GDP'
};
Plotly.newPlot('plotdiv', data, layout);
};
var innerContainer = document.querySelector('[data-num="0"'),
plotEl = innerContainer.querySelector('.plot'),
countrySelector = innerContainer.querySelector('.countrydata');
function assignOptions(textArray, selector) {
for (var i = 0; i < textArray.length; i++) {
var currentOption = document.createElement('option');
currentOption.text = textArray[i];
selector.appendChild(currentOption);
}
}
assignOptions(listofCountries, countrySelector);
function updateCountry(){
setBubblePlot(countrySelector.value);
}
countrySelector.addEventListener('change', updateCountry, false);
});
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv', function(err, rows){
function unpack(rows, key) {
return rows.map(function(row) { return row[key]; });
}
var allCountryNames = unpack(rows, 'country'),
allYear = unpack(rows, 'year'),
allGdp = unpack(rows, 'gdpPercap'),
listofCountries = [],
currentCountry,
currentGdp = [],
currentYear = [];
for (var i = 0; i < allCountryNames.length; i++ ){
if (listofCountries.indexOf(allCountryNames[i]) === -1 ){
listofCountries.push(allCountryNames[i]);
}
}
function getCountryData(chosenCountry) {
currentGdp = [];
currentYear = [];
for (var i = 0 ; i < allCountryNames.length ; i++){
if ( allCountryNames[i] === chosenCountry ) {
currentGdp.push(allGdp[i]);
currentYear.push(allYear[i]);
}
}
};
// Default Country Data
setBubblePlot('Brazil');
function setBubblePlot(chosenCountry) {
getCountryData(chosenCountry);
var trace1 = {
x: currentYear,
y: currentGdp,
mode: 'lines+markers',
marker: {
size: 12,
opacity: 0.5
}
};
var data = [trace1];
var layout = {
title: 'GDP per cap according to Country<br>'+ chosenCountry + ' GDP'
};
Plotly.newPlot('plotdiv1', data, layout);
};
var innerContainer = document.querySelector('[data-num="0"'),
plotEl = innerContainer.querySelector('.plot1'),
countrySelector = innerContainer.querySelector('.countrydata1');
function assignOptions(textArray, selector) {
for (var i = 0; i < textArray.length; i++) {
var currentOption1 = document.createElement('option');
console.log('currentOption1')
currentOption1.text = textArray[i];
console.log('currentOption1')
selector.appendChild(currentOption1);
console.log('currentOption1')
}
}
assignOptions(listofCountries, countrySelector);
function updateCountry(){
setBubblePlot(countrySelector.value);
}
countrySelector.addEventListener('change', updateCountry, false);
});
var innerContainer = document.querySelector('[data-num="0"')
calls the first dropdown box so I changed it to
var innerContainer = document.getElementById('bubble1')
and it retrieved the correct data from the second set of identical data after I created the 'bubble1' id in the html to differentiate the two.

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);
});

I want to multiply chart data according as array length

I used this ,to multiply doughnut chart according as array(arr) has,but it can't change to object,(data has string type).So chart doesn't appear here..,how fix it
var arr=['HTML','CSS','JS'],i,data;
data ='[';
for(i=0;i<arr.length;i++){
if(i==arr.length-1){
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]}';
}
else{
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]},';
}
}
data += ']';
var dat = data;
window.onload = function () {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat,{
responsive: true,
});
};
//want like this
dat =[{value:"300",color:"#fff",highlight:"#aaa",label:"HTML"},
{value:"200",color:"#fff",highlight:"#aaa",label:"CSS"}];
You are creating your array as a String.
You need to create an array of objects [{},{},{}].
The method used to INSERT a new object in an array is PUSH().
Check the fiddle. Now it´s working OK (move the mouse on the screen to see the chart is there (you will only see it when mouse is over it):
window.onload = function() {
var arr = ['HTML', 'CSS', 'JS'],
i, data;
data = [];
for (i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
} else {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
}
}
var dat = data;
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat, {
responsive: true,
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/nnnick/Chart.js/master/Chart.js"></script>
<canvas id="chart-area"></canvas>

Categories