Module: Sincerely::ChartHelper
- Defined in:
- app/helpers/sincerely/chart_helper.rb
Constant Summary collapse
- DANGER_COLOR =
'#d4183d'- STATE_COLORS =
{ 'draft' => '#9ca3af', 'accepted' => '#b9e0b8', 'delivered' => '#10b981', 'opened' => '#78c6cc', 'clicked' => '#bdd9db', 'bounced' => DANGER_COLOR, 'rejected' => DANGER_COLOR, 'complained' => DANGER_COLOR, 'delayed' => '#f97316' }.freeze
- DEFAULT_COLOR =
'#6b7280'- LINE_CHART =
{ width: 800, height: 220, padding_left: 45, padding_right: 20, padding_top: 20, padding_bottom: 30 }.freeze
- DONUT_RADIUS =
68
Instance Method Summary collapse
- #donut_segment_data(notifications_by_state) ⇒ Object
- #line_chart_area_points(points_str, values, config) ⇒ Object
- #line_chart_config(series, labels) ⇒ Object
- #line_chart_points(values, config) ⇒ Object
- #state_color(state) ⇒ Object
Instance Method Details
#donut_segment_data(notifications_by_state) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'app/helpers/sincerely/chart_helper.rb', line 59 def donut_segment_data(notifications_by_state) total = notifications_by_state.values.sum circumference = 2 * Math::PI * DONUT_RADIUS offset = 0 notifications_by_state.map do |state, count| dash_length = circumference * (count.to_f / total) visible_dash = [dash_length + 0.5, circumference].min segment = { state:, count:, color: state_color(state), visible_dash:, gap: [circumference - visible_dash, 0].max, offset: -offset } offset += dash_length segment end end |
#line_chart_area_points(points_str, values, config) ⇒ Object
53 54 55 56 57 |
# File 'app/helpers/sincerely/chart_helper.rb', line 53 def line_chart_area_points(points_str, values, config) bottom_y = config[:padding_top] + config[:plot_height] last_x = config[:padding_left] + ((values.length - 1) * config[:x_step]) "#{config[:padding_left]},#{bottom_y} #{points_str} #{last_x},#{bottom_y}" end |
#line_chart_config(series, labels) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 |
# File 'app/helpers/sincerely/chart_helper.rb', line 33 def line_chart_config(series, labels) plot_width = LINE_CHART[:width] - LINE_CHART[:padding_left] - LINE_CHART[:padding_right] plot_height = LINE_CHART[:height] - LINE_CHART[:padding_top] - LINE_CHART[:padding_bottom] max_value = [series.values.flatten.max || 0, 1].max magnitude = 10**Math.log10(max_value).floor max_y = [((max_value.to_f / magnitude).ceil * magnitude).to_i, 1].max x_step = labels.length > 1 ? plot_width.to_f / (labels.length - 1) : plot_width LINE_CHART.merge(plot_width:, plot_height:, max_y:, x_step:) end |
#line_chart_points(values, config) ⇒ Object
45 46 47 48 49 50 51 |
# File 'app/helpers/sincerely/chart_helper.rb', line 45 def line_chart_points(values, config) values.each_with_index.map do |value, i| x = config[:padding_left] + (i * config[:x_step]) y = config[:padding_top] + config[:plot_height] - (value.to_f / config[:max_y] * config[:plot_height]) "#{x.round(2)},#{y.round(2)}" end.join(' ') end |
#state_color(state) ⇒ Object
29 30 31 |
# File 'app/helpers/sincerely/chart_helper.rb', line 29 def state_color(state) STATE_COLORS[state.to_s] || DEFAULT_COLOR end |