Reputation: 3293
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!
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}
]
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.
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>
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>
Upvotes: 1
Views: 551
Reputation: 4533
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
Upvotes: 2