Class: GraphImageDrawer
- Inherits:
-
Object
- Object
- GraphImageDrawer
- Defined in:
- lib/technical_graph/graph_image_drawer.rb
Overview
options parameters: :width - width of image :height - height of image :x_min, :x_max, :y_min, :y_max - default or fixed ranges :xy_behaviour:
-
:default - use them as default ranges
-
:fixed - ranges will not be changed during addition of layers
Constant Summary collapse
- DEFAULT_WIDTH =
default sizes
1600
- DEFAULT_HEIGHT =
1200
- ONE_LAYER_LEGEND_SPACER =
height of 1 layer without font size
5
- @@default_width =
DEFAULT_WIDTH
- @@default_height =
DEFAULT_HEIGHT
Instance Attribute Summary collapse
-
#drawer ⇒ Object
readonly
Returns the value of attribute drawer.
-
#technical_graph ⇒ Object
readonly
Returns the value of attribute technical_graph.
Class Method Summary collapse
-
.height ⇒ Object
Get default graph height.
-
.height=(h) ⇒ Object
Set default graph height.
-
.width ⇒ Object
Get default graph width.
-
.width=(w) ⇒ Object
Set default graph width.
Instance Method Summary collapse
- #antialias ⇒ Object
- #axis_font_size ⇒ Object
-
#best_output_format ⇒ Object
Best output image format, used for testing.
-
#calc_bitmap_x(_x) ⇒ Object
Calculate image X position.
-
#calc_bitmap_y(_y) ⇒ Object
Calculate image Y position.
-
#crate_blank_graph_image ⇒ Object
Create background image.
-
#data_processor ⇒ Object
Calculate everything.
- #draw_legend? ⇒ Boolean
-
#drawing_class ⇒ Object
Which type of drawing class use?.
-
#graph_axis ⇒ Object
Axis processing.
- #height ⇒ Object
- #height=(h) ⇒ Object
-
#initialize(technical_graph) ⇒ GraphImageDrawer
constructor
A new instance of GraphImageDrawer.
-
#layers ⇒ Object
Accessor for DataLayer Array.
- #legend_auto_position ⇒ Object
- #legend_height ⇒ Object
- #legend_margin ⇒ Object
- #legend_width ⇒ Object
- #legend_x ⇒ Object
- #legend_y ⇒ Object
- #logger ⇒ Object
- #one_layer_legend_height ⇒ Object
-
#options ⇒ Object
Accessor for options Hash.
-
#post_dot_drawn(bx, by) ⇒ Object
Used for auto position for legend.
-
#pre_image_create_calculations ⇒ Object
Everything that must be done before creating image.
-
#recalculate_legend_position ⇒ Object
Choose best location.
-
#recalculate_legend_size ⇒ Object
Enlarge legend’s width using legend labels sizes.
-
#render_data_layer(l) ⇒ Object
Render data layer, calculate coords and execute proxy.
-
#render_data_legend ⇒ Object
Render legend on graph.
-
#save_to_file(file) ⇒ Object
Save output to file.
-
#to_format(format) ⇒ Object
Export image.
-
#to_png ⇒ Object
Return binary PNG.
- #to_svg ⇒ Object
- #to_svgz ⇒ Object
- #truncate_string ⇒ Object
- #width ⇒ Object
- #width=(w) ⇒ Object
Constructor Details
#initialize(technical_graph) ⇒ GraphImageDrawer
Returns a new instance of GraphImageDrawer.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 87 def initialize(technical_graph) @technical_graph = technical_graph t = Time.now # drawer type #options[:drawer_class] ||= :rmagick [:drawer_class] ||= :rasem [:width] ||= @@default_width [:height] ||= @@default_height [:axis_value_and_param_labels] = true if [:axis_value_and_param_labels].nil? [:axis_zero_labels] = true if [:axis_zero_labels].nil? [:adjust_axis_to_zero] = true if [:adjust_axis_to_zero].nil? # colors [:background_color] ||= 'white' [:background_hatch_color] ||= 'lightcyan2' [:axis_color] ||= '#000000' # antialias [:antialias] = false if [:antialias].nil? # font sizes [:axis_font_size] ||= 10 [:layers_font_size] ||= 10 [:axis_label_font_size] ||= 10 [:legend_font_size] ||= 10 # legend [:legend] = false if [:legend].nil? [:legend_auto] = true if [:legend_auto].nil? [:legend_x] ||= 50 [:legend_y] ||= 50 [:legend_width] ||= 100 [:legend_margin] ||= 50 # array of all points drawn on graph, used for auto positioning of legend @drawn_points = Array.new logger.debug "initializing #{self.class}" logger.debug " TIME COST #{Time.now - t}" end |
Instance Attribute Details
#drawer ⇒ Object (readonly)
Returns the value of attribute drawer.
232 233 234 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 232 def drawer @drawer end |
#technical_graph ⇒ Object (readonly)
Returns the value of attribute technical_graph.
45 46 47 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 45 def technical_graph @technical_graph end |
Class Method Details
.height ⇒ Object
Get default graph height
155 156 157 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 155 def self.height @@default_height end |
.height=(h) ⇒ Object
Set default graph height
165 166 167 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 165 def self.height=(h) @@default_height = h.to_i if h.to_i > 0 end |
.width ⇒ Object
Get default graph width
150 151 152 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 150 def self.width @@default_width end |
.width=(w) ⇒ Object
Set default graph width
160 161 162 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 160 def self.width=(w) @@default_width = w.to_i if w.to_i > 0 end |
Instance Method Details
#antialias ⇒ Object
169 170 171 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 169 def antialias [:antialias] == true end |
#axis_font_size ⇒ Object
75 76 77 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 75 def axis_font_size [:axis_font_size] end |
#best_output_format ⇒ Object
Best output image format, used for testing
41 42 43 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 41 def best_output_format @technical_graph.best_output_format end |
#calc_bitmap_x(_x) ⇒ Object
Calculate image X position
202 203 204 205 206 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 202 def calc_bitmap_x(_x) l = data_processor.x_max - data_processor.x_min offset = _x - data_processor.x_min return (offset.to_f * width.to_f) / l.to_f end |
#calc_bitmap_y(_y) ⇒ Object
Calculate image Y position
209 210 211 212 213 214 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 209 def calc_bitmap_y(_y) l = data_processor.y_max - data_processor.y_min #offset = _y - data_processor.y_min offset = data_processor.y_max - _y return (offset.to_f * height.to_f) / l.to_f end |
#crate_blank_graph_image ⇒ Object
Create background image
223 224 225 226 227 228 229 230 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 223 def crate_blank_graph_image # reset color banks GraphColorLibrary.instance.reset # calculate some stuff :] pre_image_create_calculations # create drawing proxy @drawer = drawing_class.new(self) end |
#data_processor ⇒ Object
Calculate everything
58 59 60 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 58 def data_processor @technical_graph.data_processor end |
#draw_legend? ⇒ Boolean
173 174 175 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 173 def draw_legend? [:legend] end |
#drawing_class ⇒ Object
Which type of drawing class use?
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 19 def drawing_class if [:drawer_class] == :rasem require 'technical_graph/graph_image_drawer_rasem' return GraphImageDrawerRasem end if [:drawer_class] == :chunky_png require 'technical_graph/graph_image_drawer_chunky' return GraphImageDrawerChunky end if [:drawer_class] == :rmagick and rmagick_installed? require 'technical_graph/graph_image_drawer_rmagick' return GraphImageDrawerRmagick end # default require 'technical_graph/graph_image_drawer_rasem' return GraphImageDrawerRasem end |
#graph_axis ⇒ Object
Axis processing
63 64 65 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 63 def graph_axis @technical_graph.axis end |
#height ⇒ Object
137 138 139 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 137 def height [:height].to_i end |
#height=(h) ⇒ Object
145 146 147 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 145 def height=(h) [:height] = h.to_i if h.to_i > 0 end |
#layers ⇒ Object
Accessor for DataLayer Array
53 54 55 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 53 def layers @technical_graph.layers end |
#legend_auto_position ⇒ Object
185 186 187 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 185 def legend_auto_position [:legend_auto] end |
#legend_height ⇒ Object
193 194 195 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 193 def legend_height [:legend_height] end |
#legend_margin ⇒ Object
197 198 199 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 197 def legend_margin [:legend_margin] end |
#legend_width ⇒ Object
189 190 191 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 189 def legend_width [:legend_width] end |
#legend_x ⇒ Object
177 178 179 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 177 def legend_x [:legend_x] end |
#legend_y ⇒ Object
181 182 183 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 181 def legend_y [:legend_y] end |
#logger ⇒ Object
67 68 69 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 67 def logger @technical_graph.logger end |
#one_layer_legend_height ⇒ Object
279 280 281 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 279 def one_layer_legend_height [:legend_font_size] + ONE_LAYER_LEGEND_SPACER end |
#options ⇒ Object
Accessor for options Hash
48 49 50 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 48 def @technical_graph. end |
#post_dot_drawn(bx, by) ⇒ Object
Used for auto position for legend
270 271 272 273 274 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 270 def post_dot_drawn(bx, by) if legend_auto_position @drawn_points << { :x => bx, :y => by } end end |
#pre_image_create_calculations ⇒ Object
Everything that must be done before creating image
217 218 219 220 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 217 def pre_image_create_calculations # check axis density and enlarge if this option is on graph_axis.axis_distance_image_enlarge end |
#recalculate_legend_position ⇒ Object
Choose best location
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 294 def recalculate_legend_position return unless legend_auto_position logger.debug "Auto position calculation, drawn points #{@drawn_points.size}" # check 8 places: positions = [ { :x => legend_margin, :y => 0 + legend_margin }, # top-left { :x => width/2, :y => 0 + legend_margin }, # top-center { :x => width - legend_margin - legend_width, :y => 0 + legend_margin }, # top-right { :x => legend_margin, :y => height/2 }, # middle-left { :x => width - legend_margin - legend_width, :y => height/2 }, # middle-right { :x => legend_margin, :y => height - legend_margin - legend_height }, # bottom-left { :x => width/2, :y => height - legend_margin - legend_height }, # bottom-center { :x => width - legend_margin - legend_width, :y => height - legend_margin - legend_height }, # bottom-right ] t = Time.now # calculate nearest distance of all drawn points positions.each do |p| p[:distance] = (width ** 2 + height ** 2) ** 0.5 # max distance, diagonal of graph @drawn_points.each do |dp| # calculate drawn point distance to being checked now legend position two_points_distance = ((p[:x] - dp[:x]) ** 2 + (p[:y] - dp[:y]) ** 2) ** 0.5 # modify only if distance is closer if p[:distance] > two_points_distance p[:distance] = two_points_distance end end end logger.debug "auto legend best position distance calc." logger.debug " TIME COST #{Time.now - t}" t = Time.now # chose position with highest distance positions.sort! { |a, b| a[:distance] <=> b[:distance] } best_position = positions.last [:legend_x] = best_position[:x] [:legend_y] = best_position[:y] logger.debug "Best position x #{[:legend_x]}, y #{[:legend_y]}, distance #{best_position[:distance]}" logger.debug " TIME COST #{Time.now - t}" end |
#recalculate_legend_size ⇒ Object
Enlarge legend’s width using legend labels sizes
284 285 286 287 288 289 290 291 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 284 def recalculate_legend_size layers.each do |l| w = l.label.size * [:legend_font_size] [:legend_width] = w if w > legend_width end [:legend_height] = layers.size * one_layer_legend_height end |
#render_data_layer(l) ⇒ Object
Render data layer, calculate coords and execute proxy
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 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 235 def render_data_layer(l) layer_data = l.processed_data t = Time.now # calculate coords, draw text, and then lines and circles coords = Array.new (0...(layer_data.size - 1)).each do |i| ax = layer_data[i].x ax = calc_bitmap_x(ax).round ay = layer_data[i].y ay = calc_bitmap_y(ay).round bx = layer_data[i+1].x bx = calc_bitmap_x(bx).round by = layer_data[i+1].y by = calc_bitmap_y(by).round coords << { :ax => ax, :ay => ay, :bx => bx, :by => by, :dy => layer_data[i].y } end logger.debug "rendering layer of size #{layer_data.size}, bitmap position calculation" logger.debug " TIME COST #{Time.now - t}" t = Time.now # draw using proxy drawer.render_data_layer(l, coords) end |
#render_data_legend ⇒ Object
Render legend on graph
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 340 def render_data_legend return unless draw_legend? recalculate_legend_size recalculate_legend_position x = legend_x y = legend_y legend_data = Array.new layers.each do |l| h = Hash.new h[:color] = l.color h[:label] = l.label h[:x] = x h[:y] = y legend_data << h y += one_layer_legend_height end drawer.legend(legend_data) end |
#save_to_file(file) ⇒ Object
Save output to file
365 366 367 368 369 370 371 372 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 365 def save_to_file(file) t = Time.now drawer.save(file) logger.debug "saving image" logger.debug " TIME COST #{Time.now - t}" end |
#to_format(format) ⇒ Object
Export image
375 376 377 378 379 380 381 382 383 384 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 375 def to_format(format) t = Time.now blob = drawer.to_format(format) logger.debug "exporting image as string" logger.debug " TIME COST #{Time.now - t}" return blob end |
#to_png ⇒ Object
Return binary PNG
387 388 389 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 387 def to_png drawer.to_png end |
#to_svg ⇒ Object
391 392 393 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 391 def to_svg drawer.to_svg end |
#to_svgz ⇒ Object
395 396 397 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 395 def to_svgz drawer.to_svgz end |
#truncate_string ⇒ Object
71 72 73 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 71 def truncate_string [:truncate_string] end |
#width ⇒ Object
133 134 135 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 133 def width [:width].to_i end |
#width=(w) ⇒ Object
141 142 143 |
# File 'lib/technical_graph/graph_image_drawer.rb', line 141 def width=(w) [:width] = w.to_i if w.to_i > 0 end |