Time Series Chart

Create reactive graphs using reflexes and javascript sprinkles to control drawing behavior
Loading...

Explanation

Produce interactive graphs using your favorite charts library and reflexes for manipulating attributes like data sources, axis scopes etc.

  • Demonstrates the use of an afterReflex to trigger a custom JavaScript redraw
  • Chart data is serialized into a data attribute through the reflex, to be available for Chartkick to redraw

Code (54 LOC)

ERB (24 LOC)
app/views/time_series/_demo.html.erb (24 LOC)
<% chart_data = @metrics_entries.map { |entry| [entry.date, entry[@current_data_source]] } %>
<div class="row" data-controller="time-series" data-time-series-chart-data="<%= chart_data.to_json %>">
<div class="col-9">
<%= column_chart chart_data, id: "chart" %>
</div>
<div class="col-3">
<div class="form-check">
<%= radio_button_tag "data_source", "response_time", @current_data_source == :response_time, class: "form-check-input", data: {reflex: "input->TimeSeriesReflex#set_data_source"} %>
<%= label_tag "data_source", "Response time", class: "form-check-label" %>
</div>
<div class="form-check">
<%= radio_button_tag "data_source", "requests_per_second", @current_data_source == :requests_per_second, class: "form-check-input", data: {reflex: "input->TimeSeriesReflex#set_data_source"} %>
<%= label_tag "data_source", "Requests per second", class: "form-check-label" %>
</div>
<div class="form-group mt-4">
<%= label_tag "start_date", "Start date" %>
<%= date_field_tag "start_date", @start_date, min: MetricsEntry.minimum(:date), max: @end_date, class: "form-control", data: {reflex: "input->TimeSeriesReflex#set_start_date"} %>
</div>
<div class="form-group">
<%= label_tag "end_date", "End date" %>
<%= date_field_tag "end_date", @end_date, min: @start_date, max: MetricsEntry.maximum(:date), class: "form-control", data: {reflex: "input->TimeSeriesReflex#set_end_date"} %>
</div>
</div>
</div>
JavaScript (9 LOC)
app/javascript/controllers/time_series_controller.js (9 LOC)
import ApplicationController from './application_controller'
export default class extends ApplicationController {
afterReflex (element, reflex, error) {
Chartkick.charts['chart'].updateData(
JSON.parse(this.data.get('chart-data'))
)
Chartkick.charts['chart'].redraw()
}
}
Ruby (21 LOC)
app/models/metrics_entry.rb (2 LOC)
class MetricsEntry < ApplicationRecord
end
app/controllers/time_series_controller.rb (8 LOC)
class TimeSeriesController < ApplicationController
def show
@current_data_source = session[:data_source] || :response_time
@start_date = session[:start_date] || MetricsEntry.minimum(:date)
@end_date = session[:end_date] || MetricsEntry.maximum(:date)
@metrics_entries = MetricsEntry.where(date: @start_date..@end_date)
end
end
app/reflexes/time_series_reflex.rb (11 LOC)
class TimeSeriesReflex < ApplicationReflex
def set_data_source
session[:data_source] = element.value.to_sym
end
def set_start_date
session[:start_date] = Date.parse(element.value)
end
def set_end_date
session[:end_date] = Date.parse(element.value)
end
end