Class: Cosmos::Lines

Inherits:
Object show all
Defined in:
lib/cosmos/gui/line_graph/lines.rb

Instance Method Summary collapse

Constructor Details

#initializeLines

Returns a new instance of Lines.



14
15
16
# File 'lib/cosmos/gui/line_graph/lines.rb', line 14

def initialize
  @lines = []
end

Instance Method Details

#add_line(text, y, x = nil, y_labels = nil, x_labels = nil, y_states = nil, x_states = nil, color = 'blue', axis = :LEFT, max_points_plotted = nil) ⇒ Object

Raises:

  • (ArgumentError)


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/cosmos/gui/line_graph/lines.rb', line 210

def add_line(text, y, x = nil, y_labels = nil, x_labels = nil, y_states = nil, x_states = nil, color = 'blue', axis = :LEFT, max_points_plotted = nil)
  # Validate y data
  raise ArgumentError, "GraphView y data was must given in an array-like class" unless y.respond_to?(:[])
  raise ArgumentError, "GraphView y data cannot be empty" if y.empty?
  raise ArgumentError, "GraphView y data must be Numeric" unless y[0].kind_of?(Numeric)

  # Validate x data
  if x.respond_to?(:[])
    raise ArgumentError, "GraphView x and y data must be the same size" unless y.length == x.length
    raise ArgumentError, "GraphView x data must be Numeric" unless x[0].kind_of?(Numeric)
  else
    raise ArgumentError, "GraphView x data was must given in an array-like class" unless x.nil?
  end

  # Validate y_labels data
  if y_labels.respond_to?(:[])
    raise ArgumentError, "GraphView y_labels and y data must be the same size" unless y.length == y_labels.length
  else
    raise ArgumentError, "GraphView y_labels data was must given in an array-like class" unless y_labels.nil?
  end

  # Validate x_labels data
  if x_labels.respond_to?(:[])
    raise ArgumentError, "GraphView x_labels and y data must be the same size" unless y.length == x_labels.length
  else
    raise ArgumentError, "GraphView x_labels data was must given in an array-like class" unless x_labels.nil?
  end

  # Validate y_states data
  unless y_states.respond_to?(:index)
    raise ArgumentError, "GraphView y_states data was must given in an hash-like class" unless y_states.nil?
  end

  # Validate x_states data
  unless x_states.respond_to?(:index)
    raise ArgumentError, "GraphView x_states data was must given in an hash-like class" unless x_states.nil?
  end

  if max_points_plotted and y.length > max_points_plotted
    step = (y.length.to_f / max_points_plotted.to_f).ceil
    y_reduced = LowFragmentationArray.new(max_points_plotted + 1)
    x_reduced = nil
    x_reduced = LowFragmentationArray.new(max_points_plotted + 1) if x
    y_labels_reduced = nil
    y_labels_reduced = LowFragmentationArray.new(max_points_plotted + 1) if y_labels
    x_labels_reduced = nil
    x_labels_reduced = LowFragmentationArray.new(max_points_plotted + 1) if x_labels
    (0..(y.length - 1)).step(step) do |index|
      y_reduced        << y[index].to_f
      x_reduced        << x[index].to_f   if x_reduced
      y_labels_reduced << y_labels[index] if y_labels_reduced
      x_labels_reduced << x_labels[index] if x_labels_reduced
    end
    y_reduced        << y[-1].to_f
    x_reduced        << x[-1].to_f   if x_reduced
    y_labels_reduced << y_labels[-1] if y_labels_reduced
    x_labels_reduced << x_labels[-1] if x_labels_reduced
    y        = y_reduced
    x        = x_reduced
    y_labels = y_labels_reduced
    x_labels = x_labels_reduced
  else
    # Clone data so that we don't modify the user's data
    y        = y.clone_to_f
    x        = x.clone_to_f   if x
    y_labels = y_labels.clone if y_labels
    x_labels = x_labels.clone if x_labels
  end
  unless x
    x = (1..(y.length)).to_a_to_f
  end
  y_labels = y                         unless y_labels
  # x_labels are only set if the formatted time item is used
  y_states = y_states.clone            if y_states
  x_states = x_states.clone            if x_states

  # Update Saved Data
  @lines << [x, y, x_labels, y_labels, x_states, y_states, color, axis, text]
end

#axesSymbol

Returns which axes the lines belong to

Returns:

  • (Symbol)

    :NONE, :LEFT, :RIGHT, or :BOTH



26
27
28
29
30
31
# File 'lib/cosmos/gui/line_graph/lines.rb', line 26

def axes
  return :NONE if @lines.empty?
  return :LEFT if @lines.select {|line| line[7] == :RIGHT}.empty?
  return :RIGHT if @lines.select {|line| line[7] == :LEFT}.empty?
  return :BOTH
end

#clearObject

Clears all line data



19
20
21
# File 'lib/cosmos/gui/line_graph/lines.rb', line 19

def clear
  @lines = []
end

#empty?Boolean

Returns Whether any lines are present.

Returns:

  • (Boolean)

    Whether any lines are present



40
41
42
# File 'lib/cosmos/gui/line_graph/lines.rb', line 40

def empty?
  @lines.empty?
end

#get_display_text(keys, states, labels, index) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
# File 'lib/cosmos/gui/line_graph/lines.rb', line 172

def get_display_text(keys, states, labels, index)
  text = nil
  text = labels[index] if labels
  if states
    text = states.key(keys[index])
    if text
      text = "#{text} (#{keys[index]})"
    end
  end
  return text
end

#get_left_popup_data(x_value, value_delta, ordered_x_values, min, max) ⇒ Array

Returns Popup details for the left Y axis consisting of the x value, y value, x text, y text, item name, color, and axis.

Returns:

  • (Array)

    Popup details for the left Y axis consisting of the x value, y value, x text, y text, item name, color, and axis



67
68
69
# File 'lib/cosmos/gui/line_graph/lines.rb', line 67

def get_left_popup_data(x_value, value_delta, ordered_x_values, min, max)
  get_popup_data(left(), x_value, value_delta, ordered_x_values, min, max)
end

#get_right_popup_data(x_value, value_delta, ordered_x_values, min, max) ⇒ Array

Returns Popup details for the right Y axis consisting of the x value, y value, x text, y text, item name, color, and axis.

Returns:

  • (Array)

    Popup details for the right Y axis consisting of the x value, y value, x text, y text, item name, color, and axis



72
73
74
# File 'lib/cosmos/gui/line_graph/lines.rb', line 72

def get_right_popup_data(x_value, value_delta, ordered_x_values, min, max)
  get_popup_data(right(), x_value, value_delta, ordered_x_values, min, max)
end

#left_y_axis?Boolean

Returns true if there are lines on the left y axis.

Returns:

  • (Boolean)

    true if there are lines on the left y axis



50
51
52
# File 'lib/cosmos/gui/line_graph/lines.rb', line 50

def left_y_axis?
  !left().empty?
end

#left_y_value_rangeRange

Returns The range of left Y axis values.

Returns:

  • (Range)

    The range of left Y axis values



97
98
99
# File 'lib/cosmos/gui/line_graph/lines.rb', line 97

def left_y_value_range
  y_value_range(left())
end

#legendArray

Returns Information needed to create the legend including the item name, axis, and color.

Returns:

  • (Array)

    Information needed to create the legend including the item name, axis, and color



35
36
37
# File 'lib/cosmos/gui/line_graph/lines.rb', line 35

def legend
  @lines.collect {|line| [line[8], line[6], line[7]] }
end

#num_linesInteger

Returns Number of lines that are present.

Returns:

  • (Integer)

    Number of lines that are present



45
46
47
# File 'lib/cosmos/gui/line_graph/lines.rb', line 45

def num_lines
  return @lines.length
end

#right_y_axis?Boolean

Returns true if there are lines on the right y axis.

Returns:

  • (Boolean)

    true if there are lines on the right y axis



54
55
56
# File 'lib/cosmos/gui/line_graph/lines.rb', line 54

def right_y_axis?
  !right().empty?
end

#right_y_value_rangeRange

Returns The range of right Y axis values.

Returns:

  • (Range)

    The range of right Y axis values



101
102
103
# File 'lib/cosmos/gui/line_graph/lines.rb', line 101

def right_y_value_range
  y_value_range(right())
end

#single_line_with_x_statesHash|nil

If there is a single line defined with states the states will be returned. Otherwise return nil.

Returns:

  • (Hash|nil)

    The states or nil



206
207
208
# File 'lib/cosmos/gui/line_graph/lines.rb', line 206

def single_line_with_x_states
  return @lines.length == 1 && @lines[0][4]
end

#unique_y_states(axis) ⇒ Hash|nil

Search through all the lines on the given left or right y axis for defined states. If each line has identical states return the states else return nil.

Parameters:

  • Axis (Symbol)

    which must be :LEFT or :RIGHT

Returns:

  • (Hash|nil)

    The states for the given axis or nil



190
191
192
193
194
195
196
197
198
199
200
# File 'lib/cosmos/gui/line_graph/lines.rb', line 190

def unique_y_states(axis)
  lines = left() if axis == :LEFT
  lines = right() if axis == :RIGHT
  raise "axis must be :LEFT or :RIGHT" unless lines
  states = lines.collect{|line| line[5] }.uniq
  if states.length == 1
    return states[0]
  else
    return nil
  end
end

#x_min_max_labelsArray<Numeric, Numeric, String, String>

Returns the x axis minimum and maximum values along with their labels (if there are any labels).

Returns:



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/cosmos/gui/line_graph/lines.rb', line 123

def x_min_max_labels
  x_max = 1
  x_min = -1
  x_max_label = nil
  x_min_label = nil

  unless @lines.empty?
    # Use maximum and minimum values for x_max and x_min
    line_max_values = []
    line_min_values = []
    line_max_labels = []
    line_min_labels = []
    @lines.each do |x_values, y_values, x_labels, y_labels, x_states, y_states, color|
      maximum, maximum_index = x_values.max_with_index
      line_max_values << maximum
      minimum, minimum_index = x_values.min_with_index
      line_min_values << minimum

      # If there are labels then use them directly
      if x_labels
        line_max_labels << x_labels[maximum_index]
        line_min_labels << x_labels[minimum_index]
      else # Put in max and min as place holders
        line_max_labels << maximum
        line_min_labels << minimum
      end
    end
    x_max, x_max_index = line_max_values.max_with_index
    x_min, x_min_index = line_min_values.min_with_index
    x_max_label        = line_max_labels[x_max_index]
    # If the label equals the max it was a placeholder so set to nil
    x_max_label        = nil if x_max_label == x_max
    x_min_label        = line_min_labels[x_min_index]
    # If the label equals the min it was a placeholder so set to nil
    x_min_label        = nil if x_min_label == x_min

    if x_min == x_max
      if x_min == 0.0
        x_max = 1
        x_min = -1
      else
        x_max = x_max + 1
        x_min = x_min - 1
      end
    end
  end
  return [x_min, x_max, x_min_label, x_max_label]
end

#x_statesHash|nil

Returns the x line states

Returns:

  • (Hash|nil)

    Line states or nil if none found



61
62
63
# File 'lib/cosmos/gui/line_graph/lines.rb', line 61

def x_states
  @lines.collect {|line| line[4] }.compact.uniq[0]
end