ftshtw
ftshtw

Reputation: 629

Dynamic ChartJS Chart Updated in Rails with AJAX

I am using Rails 5 and the latest ChartJS library (http://www.chartjs.org/docs/).

What I want to accomplish is to GET the latest 20 items from the SensorReading model and update the Chart with setInterval and AJAX.

I've built the AJAX call and I've loaded the Chart but I fail in two things.

First of of all I get a Syntax Error when reading data from Rails:

SyntaxError: expected expression, got '&'

var labels = ["2016-07-03 10:33:49 +0300", "2016-07-03 10:3

No matter what I tried, they keep to appear with " instead of quotes.

Secondly I am unable to update the Chart, as I need a handler available for the Chart itself to call .update() on it.

index.html.erb

<h1>Dashboard</h1>
<div class="ui divider"></div>

<div class="ui padded grid">
  <div class="four wide column">
    <div class="ui statistic">
      <div class="value">
        <%= @temperature %>.C
      </div>
      <div class="label">
        TEMPERATURE
      </div>
    </div>
    <br>
    <div class="ui statistic">
      <div class="value">
        <%= @humidity %>%
      </div>
      <div class="label">
        HUMIDITY
      </div>
    </div>
  </div>
  <div class="twelve wide column">
    <div class="ui segment">
      <div class="line-chart" style="max-height: 400px; display:block;">
        <canvas id="updating-chart"></canvas>
      </div>
    </div>
  </div>
</div>
<br>


<script>
var labels = <%= @sensor_readings.map(&:created_at) %>;

var canvas = document.getElementById('updating-chart'),
    ctx = canvas.getContext('2d'),
    startingData = {
      labels: labels,
      datasets: [
          {
              fillColor: "rgba(220,220,220,0.2)",
              strokeColor: "rgba(220,220,220,1)",
              pointColor: "rgba(220,220,220,1)",
              pointStrokeColor: "#fff",
              data: <%= @sensor_readings.map(&:temperature) %>
          },
          {
              fillColor: "rgba(151,187,205,0.2)",
              strokeColor: "rgba(151,187,205,1)",
              pointColor: "rgba(151,187,205,1)",
              pointStrokeColor: "#fff",
              data: <%= @sensor_readings.map(&:humidity) %>
          }
      ]
    },
    latestLabel = startingData.labels[6];

// Reduce the animation steps for demo clarity.
var myLiveChart = new Chart(ctx , {
    type: "line",
    data: startingData,
    animationSteps: 15
});

setInterval(function(){
  // Add two random numbers for each dataset
  //myLiveChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
  myLiveChart.update(); // Calling update now animates the position of March from 90 to 50.
}, 5000);

</script>

dashboard.js

var ready = function(){

  setInterval(refreshSensorReadings, 3000);

  function refreshSensorReadings(){
    console.log("--> Called");
    $.rails.ajax({
      type: "GET",
      dataType: 'script',
      url: "/sensor_readings_chart_data.js",
      success: function(result){
        //$('.line-chart').html(result);
        console.log(result);
      }
    });
  };


};

$(document).on('turbolinks:load', ready);

route

get 'sensor_readings_chart_data', to: 'sensor_readings#chart_data'

sensor_readings_controller.rb

def chart_data
    @sensor_readings = SensorReading.last(20)
    respond_to do |format|
      format.json { head :no_content }
      format.js  
    end
  end

Any advice will be appreaciated.

Upvotes: 2

Views: 960

Answers (1)

Roman Kiselenko
Roman Kiselenko

Reputation: 44360

Try the html_safe method:

Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed. It is your responsibilty to ensure that the string contains no malicious content. This method is equivalent to the raw helper in views. It is recommended that you use sanitize instead of this method. It should never be called on user input.

 datasets: [
      {
          fillColor: "rgba(220,220,220,0.2)",
          strokeColor: "rgba(220,220,220,1)",
          pointColor: "rgba(220,220,220,1)",
          pointStrokeColor: "#fff",
          data: <%= @sensor_readings.map(&:temperature).html_safe %>
      },
      {
          fillColor: "rgba(151,187,205,0.2)",
          strokeColor: "rgba(151,187,205,1)",
          pointColor: "rgba(151,187,205,1)",
          pointStrokeColor: "#fff",
          data: <%= @sensor_readings.map(&:humidity).html_safe %>
      }
  ]

Upvotes: 2

Related Questions