Chart.js Label Issue - javascript

So I am making a COVID-19 tracker(For Indian region) web Application using Node.js Express.js and EJS. So the issue i am getting is while creating Chart using library chart.js And I am using this API to fetch data https://api.covid19india.org/data.json .And the chart is for Total Confirmed cases on Y-axis and on X-axis Date (date from the starting of this pandemic till now)
these Informations are fetched from the api .I'm using a for loop to iterate through the array and get the specific data and pusshing it into an empty array dailyDateChnage=[], dailyCnf=[];
and later passing this data into the EJS file analytics.ejs <%=dailyDateChnage%> <%=dailyCnf%>
const dailyDateChange=[],dailyCnf=[];
const url = "https://api.covid19india.org/data.json";
const covidDataApi = axios.get(url).then(function(response) {
covidData = response.data;
for (var i = 0; i < covidData.cases_time_series.length; i++) {
let day = covidData.cases_time_series[i].date;
let cnf = covidData.cases_time_series[i].totalconfirmed;
dailyDateChange.push(day);
dailyCnf.push(cnf);
}
app.get("/analytics", function(req, res) {
res.render("analytics", {
dailyDateChange: dailyDateChange,
dailyCnf: dailyCnf,
});
});
my code for creating a chart using chart.js in file analytics.ejs
<canvas id="myChart"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data:{
labels:[<%=dailyDateChange%>],
datasets: [{
label: 'Daily Confirmed Cases',
data: [<%=dailyCnf%>],
fill:false,
backgroundColor: [
"red"
],
borderColor: [
"red"
],
borderWidth: 2,
pointBorderColor:"red",
pointBackgroundColor:"red",
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
labels:<%=dailyDateChange%> using this label the chart is not rendering [here is an image of the source page the data is being sent but not being rendered2 and an image of the output
but when replacing the labels as labels:<%=dailyCnf%>, the chart is getting rendered. image after replacing the labels
And I have tried converting the date data to string and Converting the date data to millisecond the again converting it to string
nothing has worked for me.
I don't even understand what is this issue
Can someone Explain and provide a solution for this.

When printing dailyDateChange using <%= %> it simply "prints" it as output. Consider this: You use console.log with a string element - you don't get double quotes around it in the output.
But in your code, you want the double quotes around the values of label.
Currently you might be getting something like this:
labels: [10 April, 11 April]
While you need this:
labels: ["10 April", "11 April"]
The simplest method to do so is convert it via JSON.stringify and use <%- %>` instead. The - tag (instead of =) does not escapes the string.
This code should work for you:
labels: <%- JSON.stringify(dailyDateChange) %>
Note that I also removed [] from around label as Stringify does that for us.

Related

How to select and pass array object to data setting of chart.js config?

I have a hidden input
<input type="hidden" id="0" value="10, 12">
and I am using
obj = [document.getElementById('0').value];
in a script tag to retrieve and use the value of the hidden input as the data array in the setting of Chart.js
const data = {
labels: labels,
datasets: [
{
backgroundColor: 'rgb(0, 255, 0)',
data: obj,
barThickness: 50
}]
};
I have read Chart.js unable to display data and Treat getElementById return value as array but both those questions answers suggest converting the object to an array which I have done and it still doesn't work.
Not able to pass array of data to chart.js in React Was a react problem and I tried adapting it but it didn't work either.
The desired output I want can be seen in this code snippet here:
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<body>
<canvas height="100px" id="myChart"></canvas>
<input type="hidden" id="0" value="10, 12">
<script>
obj = [document.getElementById('0').value];
console.log(Array.isArray(obj), obj);
const labels = ['Type 1', 'Type 2'];
const data = {
labels: labels,
datasets: [
{
backgroundColor: 'rgb(0, 255, 0)',
data: [10,12],
barThickness: 50
}]
};
const config = {
type: 'bar',
data: data
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
</script>
</body>
How can I achieve the same solution by somehow selecting the hidden input and passing that array as the data?
I have used console.log(); to confirm that the object is an array and that it has the correct value.
Attempts:
I've tried surrounding the object with [] like so data: [obj], but then nothing gets displayed (probably because it's already an array?)
I've tried converting the array to a list as suggested here: Turn Array Into List With JavaScript but still nothing gets displayed.
I've tried changing the values of the hidden input to be value="'10', '12'" but still nothing gets displayed.
The value of your hidden input is a string.
You are creating an array with a single element containing that string.
You need to split the string first, delimiting by the , character.
Trimming whitespace is also helpful too.
See below.
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<body>
<canvas height="100px" id="myChart"></canvas>
<input type="hidden" id="0" value="10, 12">
<script>
obj = document.getElementById('0').value.replace(" ", "").split(',')
console.log(obj);
const labels = ['Type 1', 'Type 2'];
const data = {
labels: labels,
datasets: [
{
backgroundColor: 'rgb(0, 255, 0)',
data: obj,
barThickness: 50
}]
};
const config = {
type: 'bar',
data: data
};
const myChart = new Chart(
document.getElementById('myChart'),
config
);
</script>
</body>
The line obj = [document.getElementById('0').value]; will result in an array with the string "10, 12" as value. To convert the string to an array try split method: obj = document.getElementById('0').value.split(",");.
Now you have an array with the string values "10" and " 12". Not sure if chat.js can handle this, if not you can use the map funtion to iterate over the vales and covert the to numbers

Highcharts SetData Only Works One Time

I am using a button to change the series on a High Charts graph using the series[0].setData() function. It does change the data and update the graph, but when I try to use a second button to reset my back data, nothing seems to happen. Why can the Series only be updated once?
$('#button').click(function() {
chart.series[0].setData(mydata1);
});
http://jsfiddle.net/9ypsm98a/
EDIT:
Still looking for an answer, but a easy work around is to have the button first use chart.destroy(); then recreate a completely new chart.
The problem is that the array/objects are being passed by reference on first creating the chart. After that, High Charts appears to be only updating the existing objects, overwriting the originals. Try the following jsfiddle. I first create the chart using empty objects. Then the buttons work as expected.
http://jsfiddle.net/308zr285/
var emptyData = [{},{},{}];
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
backgroundColor: null,
type: 'treemap'
},
series: [{
type: "treemap",
layoutAlgorithm: 'squarified',
alternateStartingDirection: true
}],
title: {
text: 'Fruit consumption'
}
});
chart.series[0].setData(emptyData);
});

Highcharts not displaying charts through angular controller

I started playing with highcharts for a project I am doing. Highcharts was displaying properly when I dumped a massive array of data into it, but now that I am trying to parse through groups of data that I retrieved through MongoDB I can't get it to display.
Here is my angular
$scope.retrieveData = function(){
$http.get('/calldata').then(function(response){
$scope.toneDatas = response.data
var idArray = []
angular.forEach($scope.toneDatas, function(value, key) {
idArray.push({id: value._id, social_tone_data: value.social_tone_data})
for (var i = 0; i < idArray.length; i++) {
if (idArray[i].id === value._id) {
console.log(idArray[i].id)
var socialToneName = []
var socialToneScore = []
angular.forEach(value.social_tone_data, function(value, key) {
socialToneScore.push(value.tone_score)
socialToneName.push(value.tone_type)
})
$("#" + value._id).highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: socialToneName
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
data: socialToneScore
}]
});
};
};
})
});
};
When the page loads a get request calls the database and gets the data to be served to the web page, and I am trying for now to get the data group social_tone_data to display on a chart. I have 19 documents in my mongo database and want it so that each time the loop completes, one chart is generated and served to my webpage. I should have 19 charts. I am still playing around with the code but any help is appreciated.
UPDATE
I refactored my code through an angular directive and used the element argument to display on the page.
Some good info using NG-Highcharts.
as others have said, use a directive to modify dom elements, not controller & def not jQuery as updates fall outside of angulars digest loop.
Your example needs the supplemental template/html code to be relevant.

ECharts - Set options to externally loaded arrays

So I am using the library ECharts to create some charts and graphs for various data that I have on a website. This is my first time using the library and I am fairly new to Javascript/jQuery. What I am trying to do is set the xAxis data to the results from a local page which will return a JSON Object with an array containing the days of the week. After I can do this, I then plan to load the Series data in the same way.
The jSON that is returned is this
When I am trying to set the data for xAxis, I am doing it as shown
xAxis: [{
type: 'category',
boundaryGap: false,
data: function(){
$.ajax({
type: "POST",
url: "ajax/getData.php?test=t&graph_last_days=d&days=7",
cache: false,
success: function(result){
return result.data;
//console.log(result.data);
}
});
}
}],
However, I keep getting the error Uncaught TypeError: o.slice is not a function and this error is only being outputted when I try and use this method of setting the data. In addition to this, if I try and make a function to return the data from the external page and set a variable to that, whenever I try and print it to the console it says undefined
If I do not use my method of trying to load the external data and I predefine the data like so
xAxis: [{
type: 'category',
boundaryGap: false,
data: [
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
]
}]
Then there are no errors and it works just fine
Can anyone see the problem?
Seems that after speaking with some people, the only example usage or documentation available is this example they have which is closely related to my question here.
If anyone else wants some examples related to ajax or dynamic data loading with ECharts then here are some (in English) *
Line + Bar
Scatter + Candlestick
Pie + Radar
Helpful tip
If you do not speak Chinese and you are using some sort of translator for their code examples; be aware that it's common for websites such as Google Translate and Bing Translator to incorrectly translate the punctuation used in JS by doing things such as,
Translating arrays with single quotes into arrays with single quotes and double quotes: thus causing syntax errors.
Removing commas (,) from objects.
Changing Semi-colon's (;) into Colon's (:) or even removing them.
complete example for echarts pushing data from Ajax call
data.importPorts -> Array of strings
data.importBD -> Array of Objects { clientanem : [4,5,6,7,3]}
$.get("/Home/Graph1", { clients: "403,300", years: "2012" })
.done(function (data) {
var option = {
tooltip: {
show: true
},
legend: {
data: (function () {
var res = [];
for (var name in data.importBD) {
res.push(name);
};
return res;
})()
},
xAxis: [
{
type: 'category',
data: (function () {
var res = [];
data.importPorts.forEach(function (i) {
res.push(i);
});
return res;
})()
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
}
]
};
for (var name in data.importBD) {
var obj = {
name: name,
type: "bar",
data: data.importBD[name]
};
option.series.push(obj);
}
// Load data into the ECharts instance
imprtChart.setOption(option);
});

C# List data to jqPlot.

I have two C# lists that contain and x-axis and y-axis points.
List<string> xaxis = xAxisData(url);
List<string> yaxis = yAxisData(url);
I want to pass points to my jqPlot script chart so that I can plot them.
Below is my code for .aspx page.
<script type="text/javascript">
$(document).ready(function () {
var x = $('.lclass').html();
var xaxis = ???;
var yaxis = ???;
var plot2 = $.jqplot('chart1', [xaxis], {
title: x,
axesDefaults: {
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
},
seriesDefaults: {
rendererOptions: {
smooth: false
}
},
axes: {
xaxis: {
label: "Date",
numberTicks: 4,
tickOptions: {
formatString: '%MM:%DD'
},
pad: 0
},
yaxis: {
label: "GB"
}
}
});
});
</script>
Any help or guidance is appreciated. Thanks.
there are two general ways to solve this problem
Include the data as part of the rendered ASP.NET page. This is assuming the data will not change while the page is displayed for the user. The exact code to do it depends on technology you use and there is more than one way to do it. E.g. in razor that can be done like this
#Html.Raw(ViewBag.DataAsJson)
where you put the JSON represneation of your data as a string in your ViewBag.To turn your data to a JSON object, you can use NewtonSoft's library
You fetch the data from a RESTful service because you want the data to refresh without needing to refresh the page. Again there is more than one way to do this. One is to implement an ApiController and then in the client side use a AngularJS and $http service to fetch and use the data.

Categories