Search code examples
rubyredisdashing

How to save and display Dashing historical values?


Currently to setup a graph widget, the job should pass all values to be displayed:

  data = [
    { "x" => 1980, "y" => 1323 },
    { "x" => 1981, "y" => 53234 },
    { "x" => 1982, "y" => 2344 }
  ]

I would like to read just current (the latest) value from my server, but previous values should be also displayed.

It looks like I could create a job, which will read the current value from the server, but remaining values to be read from the Redis (or sqlite database, but I would prefer Redis). The current value after that should be saved to the database.

I never worked with Ruby and Dashing before, so the first question I have - is it possible? If I will use Redis, then the question is how to store the data since this is key-value database. I can keep it as widget-id-1, widget-id-2, widget-id-3 ... widget-id-N etc., but in this case I will have to store N value (like widget-id=N). Or, is there any better way?


Solution

  • I came to the following solution:

    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
    

    Not sure if everything is implemented correctly here, but it works.