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

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

Related

plotly js globals not being available to other function

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>

Javascript readin txt file into chart

I really need some help to figure this out...
I have found a code which plot a chart out of values he gets from a website.
This is close what I would like to achieve.
But I dont want to get the values from the website but from a txt file.
I read that I should use json strings to convert it, but I'm not a programmer so I don't understand how to do such thing.
At the end of my question I have the code that get its value from the internet.
The txt file needs for now to be just easy like:
[[0, 7], [1, 12], [2, 7], [3, 3], [4, 0], [5, 4]]
The code
<!DOCTYPE HTML>
<html>
<head>
<script>
//chart
window.onload = function() {
var dataPoints = [];
var chart = new CanvasJS.Chart("chartContainer", {
theme: "light2",
title: {
text: "Live Data"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
updateData();
// Initial Values
var xValue = 0;
var yValue = 10;
var newDataCount = 6;
function addData(data) {
if (newDataCount != 1) {
$.each(data, function(key, value) {
dataPoints.push({
x: value[0],
y: parseInt(value[1])
});
xValue++;
yValue = parseInt(value[1]);
});
} else {
//dataPoints.shift();
dataPoints.push({
x: data[0][0],
y: parseInt(data[0][1])
});
xValue++;
yValue = parseInt(data[0][1]);
}
newDataCount = 1;
chart.render();
setTimeout(updateData, 1500);
}
function updateData() {
$.getJSON("https://canvasjs.com/services/data/datapoints.php?xstart=" + xValue + "&ystart=" + yValue + "&length=" + newDataCount + "type=json", addData);
}
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
<script src="https://canvasjs.com/assets/script/jquery.canvasjs.min.js"></script>
</body>
</html>
Add the URL for the text file containing the JSON into the updateData function found in your code, replacing "https://www.mywebsite/thetextfile.txt" in the example below with the URL to your text file.
function updateData() {
$.getJSON("https://www.mywebsite/thetextfile.txt", addData);
}

Nest function not summarising values

I want get sum values for my column "Country", i write this code, but i don't see summarize values
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
</head>
<body>
<canvas id="barchart" width="100%" height="40%"></canvas>
<canvas id="piechart" width="100%" height="40%"></canvas>
<script>
d3.csv("brokenstone copy.csv", function(csv_data) {
var nested_data = d3.nest()
.key(function(d) {return d.Country})
.rollup(function(s){
return d3.sum(s,function(d) {
return d.Amount;
})
})
.entries([csv_data]);
console.log(nested_data);
return csv_data;
}).then(makechart);
function colorGen() {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
const transparent = '0.6';
return "rgb(" + r + "," + g + "," + b + "," + transparent + ")";
}
function makechart(csv_data){
// console.log(csv_data);
var prd = [],
amt = [],
frac = [];
csv_data.forEach(element => {
prd.push(element.Country);
amt.push(element.Amount);
});
var alldata = {};
alldata['datasets'] = [];
alldata['labels'] = ['Amount, тн'];
csv_data.forEach(element => {
var sample = {};
sample['data'] = [element.Amount];
sample['backgroundColor'] = colorGen();
sample['label'] = element.Country;
alldata['datasets'].push(sample);
});
var barchart = new Chart('barchart', {
type: 'bar',
data: alldata,
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
fontSize: 16,
text: 'Country by amount, тн'
}
}
});
</script>
</body>
</html>
My data:
Year,Month,Country,Amount
2019,2,Germany,70
2019,3,Germany,65
2019,1,Germany,61
2019,1,Germany,39
2019,1,Italy,11966
2019,5,Italy,2489
2019,1,Italy,2262
2019,6,Germany,139
2019,4,Germany,111
2019,5,Germany,69
2019,6,Germany,67
The problem here is quite simple: all your nested_data nest is inside the row function.
The row function is called for each row in your CSV. As the API says,
If a row conversion function is specified, the specified function is invoked for each row, being passed an object representing the current row (d), the index (i) starting at zero for the first non-header row, and the array of column names.
However, that simply won't work for the nest. The nest() method needs to get all the data array.
That being said, just move the nest to inside the then. As you can see, your nest itself has no issues:
const csv = `Year,Month,Country,Amount
2019,2,Germany,70 2019,3,Germany,65
2019,1,Germany,61
2019,1,Germany,39
2019,1,Italy,11966
2019,5,Italy,2489
2019,1,Italy,2262
2019,6,Germany,139
2019,4,Germany,111
2019,5,Germany,69
2019,6,Germany,67`;
const data = d3.csvParse(csv, d3.autoType);
const nested_data = d3.nest()
.key(function(d) {
return d.Country
})
.rollup(function(s) {
return d3.sum(s, function(d) {
return d.Amount;
})
})
.entries(data);
console.log(nested_data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

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

Remove slice onClick events on Pie Charts in Chart.js

I have a question regarding piecharts on Chart.js.
What would be the best way to remove a slice when clicking on it?
I'm aware the method getSegmentsAtEvent() can be used to read the slice properties.
It's possible to find out which slicing I'm clicking looping through the slices object until a match is found.
Is there a simpler way to achieve it?
tks
This can be achieved using the functions: getSegmentsAtEvent(event) and removeData( index ) Chart.js API
With getSegmentsAtEvent you can recover the segment that has been clicked.
The next step, is to find the index of the slice in the chart. To do the search, you can iterate through all the current segments of the chart and call removeData when it's found. (I think there is no way to directly know the index)
var segments = myChart.segments;
for (var index = 0; index < segments.length; index++) {
if (activeLabel == segments[index].label) {
myChart.removeData(index);
}
}
Full demo:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.2.js"></script>
<script type="text/javascript" src="Chart.js"></script>
<script type="text/javascript">
var data = [
{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}
];
$(document).ready(
function () {
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx).Pie(data);
$("#myChart").click(
function(evt){
var activePoints = myChart.getSegmentsAtEvent(evt);
var activeLabel = activePoints[0].label;
var segments = myChart.segments;
for (var index = 0; index < segments.length; index++) {
if (activeLabel == segments[index].label) {
myChart.removeData(index);
}
}
}
);
}
);
</script>
</head>
<body>
<canvas id="myChart" width="400" height="400"></canvas>
</body>
</html>
Get the onclick property in options of chart.
This onclick event will trigger even when you click outside of pie (anywhere in canvas), so you have to filter it out by using myChart.getElementsAtEvent(event);
Get data of chart and then remove an item using checks(In the following snippet you can only remove china or any country with value less than 50).
Update the chart by using .update() method
Following is the required working snippet
var chart_click_event = function(event) {
debugger;
let activePoints = myChart.getElementsAtEvent(event);
//If you click on empty area this if check will not pass.
if (activePoints[0]) {
let chartData = activePoints[0]['_chart'].config.data;
let idx = activePoints[0]['_index'];
let label = chartData.labels[idx];
let value = chartData.datasets[0].data[idx];
if (label == 'China' || value < 50) {
chartData.labels.splice(idx, 1);
chartData.datasets[0].data.splice(idx, 1);
myChart.update();
}
}
}
var data = [{
data: [50, 55, 60, 33],
backgroundColor: [
"#4b77a9",
"#5f255f",
"#d21243",
"#B27200"
],
borderColor: "#fff"
}];
var options = {
tooltips: {
enabled: true
},
plugins: {
datalabels: {
color: '#fff',
}
},
onClick: chart_click_event
};
var ctx = document.getElementById("pie-chart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['Pakistan', 'China', 'US', 'Canada'],
datasets: data
},
options: options
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#0.7.0"></script>
<canvas id="pie-chart"></canvas>

Categories