I am trying to populate a highchart in jade(with javascript) with JSON data send from node.js. I do this by adding JavaScript in jade, this works fine with static data as shown below:
var series = [
{
name: 'Tokyo',
data: [7.0]
}
];
Now I want to add JSON data from node.js. I implemented the following:
app.get('/chart', function(req,res){
var chartData = [
{
name: 'Tokyo',
data: [7.0]
}
];
res.render('chart', {
chart: chartData
});
});
When I print chartData in console, the output is the same as the static data. When I set(in jade)
var series = '#{chart}' I get an empty highchart.
The problem seems to be the JSON from node js. Highcharts gives as many series as there are characters, which means jade/javascript is not parsing the JSON correctly, but character by character instead(each character is new object). I have printed chartData from node.js to my console, showing the following:
[ { name: 'Tokyo', data: [ 7 ] } ]
I have tried JSON.stringify in my node js file, but this returns invalid JSON as follows:
var series = '[{"name":"Tokyo","data":[7]}]';
How can I get my chart to work with the JSON returned from node.js?
I figured out how to solve this. In node js:
var chartData = [];
chartData.push({
name: 'Tokyo'
data: [7.0]
});
res.render('chart', {
chart: chartData
});
My mistake was in Javascript within Jade, when parsing the JSON. Following solved the problem:
!{JSON.stringify(chart)}
If you're having trouble outputting proper JSON, try the JSON.stringify method.
app.get('/chart', function(req,res){
var chartData = [
{
name: 'Tokyo',
data: [7.0]
}
];
res.render('chart', {
chart: JSON.stringify(chartData, null, 4)
});
});
Related
Good morning.
I need to do the following: Update a stacked line chart using a function in javascript that takes a 2d array ([[0,1],[0,2],...]).
My page is running in a Java fx webview so I can dynamically update my data. All the examples I've seen so far create a predefined X axis and pass the y values accordingly, I wanted to pass the two values together to plot a line on the chart.
How could I make this function? It's the first time I use echarts so I'm lost.
I even managed to do something similar but when plotting the chart it was all wrong.
Char Image
var option = {
xAxis: {
type: "value",
},
yAxis: {
type: "value",
},
series: [
{
type: "line",
data: [],
},
],
};
vibrationStackedLineChart.setOption(option);
function updateEchart(dataArray) {
// Parse the JSON string back into a 2D int array
var data = JSON.parse("[" + dataArray + "]");
// Update the chart with the new data
vibrationStackedLineChart.setOption({
series: [
{
data: data,
},
],
});
}
Java function with array 2d
I'm having some trouble preparing data from my Ruby on Rails project for use in chart.js, when using time as a second axis.
I've looked at various other questions and managed to get very close, but am having issues with exporting the data in a format that chart.js can recognise.
Thanks for your help!
Issue
I need the data to be printed in this form:
data: [
{"x":1567006282000,"y":145},
{"x":1567009767000,"y":120},
{"x":1567009838000,"y":130}
]
But am currently getting the following:
data: [
{"x":1567006282000,"y":145},
{"x":1567009767000,"y":120},
{"x":1567009838000,"y":130}
]
Current Attempt
I am creating the array as follows from within my controller, where reading_time and obs.heart_rate are integers, I think this is creating an array of hashes:
...
#hr.push ( { :x => reading_time, :y => obs.heart_rate } )
...
I then print this in my view, converting to json so that it would in theory work with the javascript library chart.js:
...
data: <%= #hr.to_json %>,
...
Pretty sure my issue is somewhere in the two lines above, but the full code is below in case it is needed.
Full Code
This is how I am creating (what I think) is an array of hashes within my controller:
def chart
# Load observations for specific patient
#observations = Observation.where(:patient_id => params[:patient_id]);
# Prep arrays
#readings = []
#hr = []
# Cycle through all observations for this patient
#observations.each do |obs|
# Convert created time to integer
# Multiple by 1000 as chart.js expects milliseconds while ruby uses seconds from UNIX epoch
reading_time = obs.created_at.to_i * 1000
# Add time to array so we can use this for the labels
#readings.push(reading_time)
# Create hash of time and observation value
hr_temp = {:x => reading_time , :y => obs.heart_rate }
# Push hash to the array
#hr.push( hr_temp )
# Repeat for other obserations - blood pressure, oxygen sats, etc
end
end
And finally how I am then printing that within my view:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js" integrity="sha256-xKeoJ50pzbUGkpQxDYHD7o7hxe0LaOGeguUidbq6vis=" crossorigin="anonymous"></script>
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var scatterChart = new Chart(ctx, {
type: 'line',
data: {
labels: <%= #readings %>,
datasets: [{
label: 'Heart Rate',
data: <%= #hr.to_json %>,
borderWidth: 1
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
parser: 'X', // parse x values as unix timestamp
tooltipFormat: 'MMM Do, \'YY'
},
}]
}
}
});
</script>
Working Example
This is a working hard coded example showing what I am aiming for.
var ctx = document.getElementById('myChart').getContext('2d');
var scatterChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [{
label: 'Heart Rate',
data: [
{"x":1567006282000,"y":145},
{"x":1567009767000,"y":120},
{"x":1567009838000,"y":130}
]
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {
parser: 'X', // parse x values as unix timestamp
tooltipFormat: 'MMM Do, \'YY'
},
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js" integrity="sha256-xKeoJ50pzbUGkpQxDYHD7o7hxe0LaOGeguUidbq6vis=" crossorigin="anonymous"></script>
<canvas id="myChart" width="400" height="400"></canvas>
Due to rendering, which uses to_s under the hood which could cause some encoding issues while rendering from a string type object. You should try using using html_safe method on the object returned by #hr.to_json like #hr.to_json.html_safe
I am trying to feed data to highcharts client. Currently highcharts expects data in below format.
[
[1515122457593,47,64.17,12.77,23.91,15969798],
[1515122497615,23.91,47.97,14.19,30.81,15969798],
[1515122537619,30.81,49.42,13.34,27.76,15969798],...
]
However, I could not find a way to store in same format in MongoDB. I think one possibility is as below.
{
{ "_id": 1, "time":1515122457593, "O":47, "H":64.17, "L":12.77, "C":23.91, "V":15969798 },
{ "_id": 2, "time":1515122497615, "O":23.91, "H":47.97, "L":14.19, "C":30.81, "V":15969798 },
{ "_id": 3, "time":1515122537619, "O":30.81, "H":49.42, "L":13.34, "C":27.76, "V":15969798 },
...
}
My questions are in both directions.
Direction 1: How do I make above mongodb friendly json format to be read by Highcharts OHLC.
Direction 2: How do I store Highcharts friendly data series in Mongodb?
Kindly share example as I could not find online any snippets that could help and all my trials are in vain. I got a hint here, but could not develop it further for my OHLC format (I am newbie to JS and webdev)
Highcharts.chart('container', {
chart: {
type: 'column'
},
xAxis: {
categories: ['Green', 'Pink']
},
series: [{
data: [{
name: 'Point 1',
color: '#00FF00',
y: 1
}, {
name: 'Point 2',
color: '#FF00FF',
y: 5
}]
}]});
You should be able to achieve the exact document structure required by Highcharts using the below schema:
var schema = new Schema({
data: [[Number]] // array of array of numbers
})
I'm trying to plot a Chart using Google's Visualization API using some data returned from a database by a PHP script. My data is a JSON object in the format:
jsonObject = {
"routes":[{
"name":"Route 0",
"chart":{
"x":[ /* array of x values */ ],
"y":[ /* array of y values */ ]
}
},{
"name":"Route 1",
"chart":{
"x":[ /* array of x values */ ],
"y":[ /* array of y values */ ]
}
}]};
I'm trying to plot a chart of each member of jsonObject.routes individually using the following code:
function drawChart() {
var baseChart = jsonObject.routes[1].chart; // Want to manipulate this value to plot different sets of data
var chartData = [];
for (var g = 0; g < baseChart.x.length; g++) {
var dataPoint = {
c: [
{ v: baseChart.x[g] },
{ v: baseChart.y[g] },
]
};
chartData.push(dataPoint);
}
var dataJson = {
cols: [
{ role: "domain", type: "number", label: "Distance" },
{ role: "data", type: "number", label: "Main Route" },
],
rows: chartData
};
var dataTable = new google.visualization.DataTable(dataJson);
var chart = new google.visualization.AreaChart(document.getElementById('chart'));
var options = {};
chart.draw(dataTable, options);
}
However, whenever I try to access the latter objects of the jsonObject.route array, it seems to be pulling data for every object in the jsonObject.route array prior to it as well.
I've included a link to a Fiddle with a sample dataset at the bottom; the chart is fine when only plotting jsonObject.routes[0], but when trying to plot jsonObject.routes[1] it will plot the data from jsonObject.routes[0] too.
I suspect this is more of an issue with my Javascript code rather than with the Google Visualization API, but I've been pulling my hair out with it and can figure out why it's pulling data from all the elements in that array. Many thanks for any help!
Link to Fiddle
not sure i completely follow the question...
looking at the fiddle, the one chart seems to draw fine,
just need to sort the data to fix funny looking area
dataTable.sort([{column: 0}]);
see following snippet in order to draw separate charts for each --> jsonObject.routes
google.charts.load('current', {
callback: function () {
jsonObject.routes.forEach(function (route) {
var chartData = [];
route.chart.dist.forEach(function (x, index) {
chartData.push({
c: [
{v: x},
{v: route.chart.ele[index]}
]
});
});
var dataJson = {
cols: [
{ role: "domain", type: "number", label: "Distance" },
{ role: "data", type: "number", label: "Main Route" },
],
rows: chartData
};
var dataTable = new google.visualization.DataTable(dataJson);
dataTable.sort([{column: 0}]);
var options = {};
var container = document.getElementById('chart_div').appendChild(document.createElement('div'));
var chart = new google.visualization.AreaChart(container);
chart.draw(dataTable, options);
});
},
packages:['corechart']
});
note: definition of jsonObject is excluded above
AND
when building a working fiddle, i noticed that since jsonObject is so large,
once you leave the page and comeback,
the fiddle breaks it up into chunks, which then breaks the code
and only one chart is drawn
here is a working fiddle with far less data
Hello friends I'm trying to draw the chart using javascript function the data comes into JSON array format like
[[1432116687000,5100],[1432116991000,5100],[1432117291000,5100],[1432117591000,5100],[1432117894000,5100],[1432118199000,5100],[1432118499000,5100],[1432118800000,5100],[1432119100000,5100],[1432119404000,5100],[1432119648000,5100],[1432119950000,5100],[1432120250000,5100],[1432120550000,5100],[1432120850000,5100],[1432121154000,5100],[1432121154000,5100]]
But I'm getting an error
Highcharts Error #15
Highcharts expects data to be sorted
This happens when you are trying to create a line series or a stock chart where the data is not sorted in ascending X order. For performance reasons, Highcharts does not sort the data, instead it is required that the implementer pre-sorts the data.
please help me to fix it
function drawChart(data){
console.log(data);
var date = [];
var ttc = [];
var series = [];
for(var i=0; i<data.length; i++){
//date.push(data[i][0]);
//console.log(date);
//ttc.push(parseInt(data[i][1]));
//console.log(ttc);
series.push([data[i][0],parseInt(data[i][1])]);
}
//console.log(data[i][1]);
//var series = (series);
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'Area Per TCC'
},
yAxis: {
title: {
text: 'TTC'
}
},
series: [{
name: 'TCC',
data: series
}]
});
} ;