Class: RCharts::GraphHelper::GraphBuilder

Inherits:
ElementBuilder show all
Defined in:
app/helpers/rcharts/graph_helper/graph_builder.rb

Overview

RCharts Graph Builder

A GraphBuilder object contains a hash of data and allows you to render the various parts of a graph using the contained data. This is the object yielded when using GraphHelper#graph_for. For example:

<%= graph_for @annual_sales do |graph| %>
  <%= graph.series do |series| %>
    <%= series.line %>
  <% end %>
<% end %>

Here, the graph variable is a yielded GraphBuilder object. You can then render a line chart from the annual sales data by calling #series to obtain a Series::SeriesBuilder which can iterate over the series present in the data, and then calling Series::SeriesBuilder#line to render a line for the series points.

The GraphBuilder object allows rendering as many or few elements of the graph as necessary while still maintaining coherence between them.

Like form builders, you can subclass GraphBuilder to extend it with custom behaviour. Perhaps you want the legend to be placed at the top by default, for example:

class MyGraphBuilder < RCharts::GraphHelper::GraphBuilder
  def legend(**options, &)
    super(**options.merge(placement: :top, &)
  end
end

Then you can use the new builder with GraphHelper#graph_for:

<%= graph_for @annual_sales, builder: MyGraphBuilder do |graph| %>
  <%= graph.legend do |series| %>
    <%= series.symbol %>
    <%= series.name %>
  <% end %>
<% end %>

Instance Method Summary collapse

Methods inherited from ElementBuilder

#render_in

Instance Method Details

#axis(*name) ⇒ Object

Renders an axis for a set of points. The name is a key such as :x and optionally an index that defaults to 0 if not provided. Yields the value of each tick on the axis so you can format it appropriately.

<%= graph_for @annual_sales do |graph| %>
  <%= graph.axis :y, label: 'Primary Y axis' do |value| %>
    <%= number_with_delimiter value %>
  <% end %>
  <%= graph.axis :y, 1, label: 'Secondary Y axis' do |value| %>
    <%= number_with_delimiter value %>
  <% end %>
  <%= graph.axis :x, label: 'Primary X axis' do |value| %>
    <%= value %>
  <% end %>
  <%= graph.axis :x, 1, label: 'Secondary X axis' do |value| %>
    <%= value %>
  <% end %>
<% end %>

Options

:label

The axis title

:character_scaling_factor

The scaling factor for character width on a vertical axis. In this case, label width is calculated using the width of zero in the current font multiplied by the maximum number of text characters for any label, so you can use this option to make adjustments according to your average character width ratio to zero. The default is 1.0.

:breakpoints

Related to the character scaling factor, these are used to determine the point at which labels rotate or disappear. The defaults are: hiding: { even: 1.1, odd: 0.6 }, rotation: { half: 1.0, full: 0.9 }.



136
137
138
139
140
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 136

def axis(*name, **, &)
  axes.fetch(*name).then do |axis|
    render Axes::AxisElement.new(name: axis.name, index: axis.index, ticks: axis.ticks, horizontal: axis.horizontal?, **), &
  end
end

#axis_optionsObject

:attr_accessor: options for the layout axes



50
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 50

attribute :axis_options, default: -> { {} }

#categories(builder: Categories::CategoryBuilder, data: {}, html: {}) ⇒ Object

Renders the categories present in the data. For each category yields a Categories::CategoryBuilder which contains the category:

<%= graph_for @annual_sales do |graph| %>
  <%= graph.categories do |category| %>
    <%= category.bar %>
  <% end %>
<% end %>

Like GraphHelper#graph_for, you can use the :builder key to use a custom builder subclass, :data to set data attributes, and :html to set other HTML attributes, while other options are passed through to the builder.

See Categories::CategoryBuilder for more information.



99
100
101
102
103
104
105
106
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 99

def categories(builder: Categories::CategoryBuilder, data: {}, html: {}, **, &)
  tag.svg class: 'category-container', data:, **html do
    composition.values.each_with_index do |(name, category), index|
      concat render builder.new(layout_axes: composition.axes, name:, category:, index:,
                                values_count: composition.values.count, series_options:, **), &
    end
  end
end

#graphableObject

:attr_accessor: data used to render the graph



40
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 40

attribute :graphable, default: -> { {} }

#gutterObject

:attr_accessor: gutter value determining the length of short ticks



45
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 45

attribute :gutter, :float, default: 10.0

#legend(placement: 'bottom') ⇒ Object

Renders the legend. For each series yields a LegendEntryBuilder.

<%= graph_for @annual_sales do |graph| %>
  <%= graph.legend do |series| %>
    <%= series.symbol %>
    <%= series.name %>
  <% end %>
<% end %>

See LegendEntryBuilder for more information.

Options

:placement

The placement of the legend (top, bottom, left, right). Defaults to 'bottom'.



177
178
179
180
181
182
183
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 177

def legend(placement: 'bottom', **, &)
  tag.ul class: 'legend', data: { placement: } do
    series_options_with_defaults.each_key.with_index do |key, index|
      concat legend_item_tag_for(key, index, **, &)
    end
  end
end

#rules(*name, short: false, emphasis: nil) ⇒ Object

Renders rules for an axis. The name is a key such as :x and optionally an index that defaults to 0 if not provided. Rules are both the full-length lines that span the entire width or height of the plot, as well as the much shorter lines that mark each category (e.g. for a bar chart). Rules can also be emphasized, e.g. for 0 in a chart which has both positive and negative values.

<%= graph_for @annual_sales do |graph| %>
  <%= graph.rules :y, emphasis: :zero? %>
  <%= graph.rules :x, short: true %>
  <%= graph.rules :x, 1, short: true %>
<% end %>

Options

:short

Whether to render short rules (e.g. for bar chart categories)

:emphasis

A callable predicate that determines whether a rule should be emphasized



154
155
156
157
158
159
160
161
162
163
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 154

def rules(*name, short: false, emphasis: nil, **)
  tag.svg class: 'grid' do
    axes.fetch(*name).then do |axis|
      axis.ticks.each do |position, value|
        concat render RuleElement.new(short:, position:, value:, emphasis:, gutter:, axis_index: axis.index,
                                      horizontal_axis: axis.horizontal?, **)
      end
    end
  end
end

#series(*names, builder: Series::SeriesBuilder, data: {}, html: {}) ⇒ Object

Renders one or more series present in the data. For each series yields a Series::SeriesBuilder which contains the series:

<%= graph_for @annual_sales do |graph| %>
  <%= graph.series do |series| %>
    <%= series.line %>
  <% end %>
<% end %>

The default is to iterate over all series, but you can specify a subset by passing the series names as arguments.

<%= graph_for @annual_sales do |graph| %>
  <%= graph.series :baseline_prediction, :actual do |series| %>
    <%= series.line %>
  <% end %>
<% end %>

Like GraphHelper#graph_for, you can use the :builder key to use a custom builder subclass, :data to set data attributes, and :html to set other HTML attributes, while other options are passed through to the builder.

See Series::SeriesBuilder for more information.



76
77
78
79
80
81
82
83
84
85
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 76

def series(*names, builder: Series::SeriesBuilder, data: {}, html: {}, **, &)
  tag.svg class: 'series-container', data:, **html do
    selected_series(only: names).each do |key|
      concat render builder.new(name: key, index: series_options_with_defaults.keys.index(key),
                                series_options: series_options_with_defaults.fetch(key, {}),
                                composition:,
                                **), &
    end
  end
end

#series_optionsObject

:attr_accessor: display options for each series



55
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 55

attribute :series_options, default: -> { {} }

#tooltipsObject

Renders the tooltips. For each category yields a Tooltips::TooltipBuilder.

<%= graph_for @annual_sales do |graph| %>
  <%= graph.tooltips do |category| %>
    <div class="tooltip-inner-content">
      <div class="tooltip-title">
        <%= category.name %>
      </div>
      <dl class="tooltip-items">
        <%= category.series class: 'tooltip-item' do |series| %>
          <dt>
            <%= series.symbol %>
            <%= series.name %>
          </dt>
          <dd>
            <%= number_to_human series.value %>
          </dd>
        <% end %>
      </dl>
    </div>
  <% end %>
<% end %>

See Tooltips::TooltipBuilder for more information.



208
209
210
211
212
# File 'app/helpers/rcharts/graph_helper/graph_builder.rb', line 208

def tooltips(**, &)
  tag.svg class: 'tooltips', width: '100%', xmlns: 'http://www.w3.org/2000/svg' do
    composition.values.each_key { concat tooltip_tag_for(it, **, &) }
  end
end