简体   繁体   中英

Output array of hashes from Ruby on Rails to chart.js

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM