Method: PDF::Charts::StdDev#render_on
- Defined in:
- lib/extensions/pdf-writer/pdf/charts/stddev.rb
#render_on(pdf) ⇒ Object
Draw the standard deviation chart on the supplied PDF document.
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 289 290 291 292 293 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 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/extensions/pdf-writer/pdf/charts/stddev.rb', line 219 def render_on(pdf) raise TypeError, PDF::Writer::Lang[:charts_stddev_data_empty] if @data.empty? data = @data.dup leftover_data = nil loop do # Set up the scale information. scale = [] (@scale.first + @scale.step).step(@scale.last, @scale.step) do |ii| scale << "%01.#{@scale.label.decimal_precision}f" % ii end scales = PDF::Writer::OHash.new scale.each_with_index do |gg, ii| scales[ii] = OpenStruct.new scales[ii].value = gg end # Add information about the scales' locations to the scales # hash. Note that the count is one smaller than it should be, so we're # increasing it. The first scale is the bottom of the chart. scale_count = scale.size + 1 label_height_adjuster = 0 label_height_adjuster = @label.height if @show_labels chart_area_height = @height - label_height_adjuster scale_height = chart_area_height / scale_count.to_f scales.each_key do |index| this_height = scale_height * (index + 1) + @label.height scales[index].line_height = this_height if @scale.show_labels scales[index].label_height = this_height - (@scale.label.text_size / 3.0) end end # How many sections do we need in this chart, and how wide will it # need to be? chunk_width = @datapoint_width num_chunks = data.size widest_scale_label = 0 if @scale.show_labels scales.each_value do |scale| this_width = pdf.text_width(scale.value, @scale.label.text_size) widest_scale_label = this_width if this_width > widest_scale_label end end chart_width = chunk_width * num_chunks total_width = chart_width + widest_scale_label + @scale.label.pad # What happens if the projected width of the chart is too big? # Figure out how to break the chart in pieces. if total_width > @maximum_width max_column_count = 0 base_width = widest_scale_label + @scale.label.pad (1..(num_chunks + 1)).each do |ii| if (base_width + (ii * chunk_width)) > @maximum_width break else max_column_count += 1 end end leftover_data = data.slice!(max_column_count, -1) num_chunks = data.size chart_width = chunk_width * num_chunks total_width = chart_width + widest_scale_label + @scale.label.pad end chart_y = pdf.y - @height + @leading_gap chart_y += (@outer_borders.style.width * 2.0) if @outer_borders if chart_y < pdf.bottom_margin pdf.start_new_page chart_y = pdf.y - @height chart_y += (@outer_borders.style.width * 2.0) if @outer_borders end chart_x = pdf.absolute_x_middle - (total_width / 2.0) + widest_scale_label # Add labels, if needed. if @show_labels pdf.save_state pdf.fill_color! @label.background_color # Draw a rectangle for each label num_chunks.times do |ii| this_x = chart_x + ii * chunk_width pdf.rectangle(this_x, chart_y, chunk_width, @label.height).fill end # Add a border above the label rectangle. if @outer_borders pdf.stroke_style! @outer_borders.style pdf.line(chart_x, chart_y + @label.height, chart_x + chart_width, chart_y + @label.height).stroke end pdf.fill_color! @label.text_color data.each_with_index do |datum, ii| label = datum.label.to_s label_width = pdf.text_width(label, @label.text_size) this_x = chart_x + (ii * chunk_width) + (chunk_width / 2.0) - (label_width / 2.0) this_y = chart_y + (@label.height / 2.0) - (@label.text_size / 3.0) pdf.add_text(this_x, this_y, label, @label.text_size) end pdf.restore_state end if @inner_borders pdf.save_state pdf.stroke_color! @inner_borders.color pdf.stroke_style! @inner_borders.style (num_chunks - 1).times do |ii| this_x = chart_x + (ii * chunk_width) + chunk_width pdf.line(this_x, chart_y, this_x, chart_y + @height).stroke end pdf.restore_state end pdf.save_state if @outer_borders pdf.stroke_color! @outer_borders.color pdf.stroke_style! @outer_borders.style pdf.rectangle(chart_x, chart_y, chart_width, @height).stroke end if @scale.style pdf.save_state pdf.stroke_style! @scale.style scales.each_value do |scale| this_y = chart_y + scale.line_height pdf.line(chart_x, this_y, chart_x + chart_width, this_y).stroke end pdf.restore_state end if @scale.show_labels pdf.save_state scales.each_value do |scale| this_y = chart_y + scale.label_height label_width = pdf.text_width(scale.value, @scale.label.text_size) this_x = chart_x - label_width - @scale.label.pad pdf.fill_color! @scale.label.text_color pdf.add_text(this_x, this_y, scale.value, @scale.label.text_size) end pdf.restore_state end data.each_with_index do |datum, ii| avg_height = datum.average * scale_height stddev_height = datum.stddev * scale_height this_y = chart_y + label_height_adjuster + avg_height this_x = chart_x + (ii * chunk_width) + (chunk_width / 2.0) line_top_y = this_y + (stddev_height / 2.0) line_bot_y = this_y - (stddev_height / 2.0) # Plot the dot if @dot pdf.stroke_color! @dot.color pdf.stroke_style! @dot.style pdf.circle_at(this_x, this_y, (@dot.style.width / 2.0)).fill end # Plot the bar if pdf.stroke_color! .color pdf.stroke_style! .style pdf.line(this_x, line_top_y, this_x, line_bot_y).stroke end # Plot the crossbars if if @dot cb_width = @dot.style.width else cb_width = .style.width end pdf.stroke_color! .color pdf.stroke_style! .style pdf.line(this_x - cb_width, line_top_y, this_x + cb_width, line_top_y).stroke end if if @dot cb_width = @dot.style.width else cb_width = .style.width end pdf.stroke_color! .color pdf.stroke_style! .style pdf.line(this_x - cb_width, line_bot_y, this_x + cb_width, line_bot_y).stroke end end pdf.restore_state pdf.y = chart_y break if leftover_data.nil? data = leftover_data leftover_data = nil end pdf.y end |