How to: Store data to and display from database

and7ey edited this page Mar 5, 2016 · 3 revisions

The Dashing by default just displays the data just received. If you would like to store the data received and then send it to your widget, you may use Redis datastore.

The job should be modified to store and read the data, see below the example how to do it with simple Number widget:

require 'redis' # https://github.com/redis/redis-rb
redis_uri = URI.parse(ENV["REDISTOGO_URL"])
redis = Redis.new(:host => redis_uri.host, :port => redis_uri.port, :password => redis_uri.password)

SCHEDULER.every '20s', :first_in => 0 do |job|
  rand_value = rand(1000) # replace this line with the code to get your data
  prev_value = redis.get("widget-id-prev-value") # read previous value from the Redis datastore
  redis.set("widget-id-prev-value", rand_value) # store current value to the Redis datastore

  send_event('karma', { current: rand_value, last: prev_value })
end

Below is the more complex code to keep and display historical values for Graph widget:

require 'redis' # https://github.com/redis/redis-rb
redis_uri = URI.parse(ENV["REDISTOGO_URL"])
redis = Redis.new(:host => redis_uri.host, :port => redis_uri.port, :password => redis_uri.password)

if redis.exists('widget-id-history')
    points_history = redis.lrange('widget-id-history', 0, 9) # get latest 10 records
    points = []
    (1..points_history.count).each do |i|
        points << { x: i, y: points_history[i-1].to_i }
    end
    last_x = points.last[:x]
else
    points = []
    last_x = 0
end

SCHEDULER.every '10s', :first_in => 0 do |job|
  if points.count > 9 # display 10 records only
    points.shift
  end
  last_x += 1
  rand_value = rand(50) # replace this line with the code to get latest value
  points << { x: last_x, y: rand_value }
  redis.lpush('widget-id-history', rand_value)

  send_event('convergence', points: points)
end

And even more complex code to do the same with Bar Chart (please note that Bar Chart doesn't support update of labels currently, so the code below acts just an example of multiple values store/read usage):

require 'redis' # https://github.com/redis/redis-rb
redis_uri = URI.parse(ENV["REDISTOGO_URL"])
redis = Redis.new(:host => redis_uri.host, :port => redis_uri.port, :password => redis_uri.password)

if redis.exists('values_x') && redis.exists('values_y')
    values_x = redis.lrange('values_x', 0, 9) # get latest 10 records
    values_y = redis.lrange('values_y', 0, 9) # get latest 10 records
else
    values_x = []
    values_y = []
end

SCHEDULER.every '10s', :first_in => 0 do |job|
  rand_data = (Date.today-rand(10000)).strftime("%d-%b") # replace this line with the code to get your data
  rand_value = rand(50) # replace this line with the code to get your data
  values_x << rand_data
  values_y << rand_value

  redis.multi do # execute as a single transaction
    redis.lpush('values_x', rand_data)
    redis.lpush('values_y', rand_value)
    # feel free to add more datasets values here, if required
  end

  data = [
    {
      label: 'dataset-label',
      fillColor: 'rgba(220,220,220,0.5)',
      strokeColor: 'rgba(220,220,220,0.8)',
      highlightFill: 'rgba(220,220,220,0.75)',
      highlightStroke: 'rgba(220,220,220,1)',
      data: values_y.last(10) # display last 10 values only
     }
  ]
  options = { scaleFontColor: '#fff' }

  send_event('barchart', { labels: values_x.last(10), datasets: data, options: options })
end