Rails虾图未完全呈现在页面底部

时间:2016-12-28 14:32:37

标签: ruby-on-rails ruby prawn

我正在创建一个pdf报告,以便使用" squid"来显示一些数据。宝石。这将允许我在我的pdf中显示图表。 我发现的唯一问题是,当图表不适合页面底部时,它看起来部分渲染,看起来并不好看。知道我该如何解决这个问题?

enter image description here

以下是我用来渲染图表的代码

require 'squid'

class SurveyPdf < Prawn::Document
  def initialize(survey, view)
    super()
    font "#{Rails.root}/app/assets/fonts/roboto-condensed.ttf"

    @survey = survey
    @view = view
    questions
  end

  def questions
    @survey.questions.each do |question|
      text "#{question.title}", size: 20
      text "Answers #{question.answers.size}", size: 15
      if ["single", "select"].include? question.question_type.prefix
        if question.answers.choice_counter.any?
          chart choices: question.answers.choice_counter
        end
      end
      if question.question_type.prefix == "image"
        if question.answers.image_counter.any?
          chart images: question.answers.image_counter
        end
      end
      if question.question_type.prefix == "multiple"
        if question.answers.multiple_choice_counter.any?
          chart choices: question.answers.multiple_choice_counter
        end
      end
      if question.question_type.prefix == "raiting"
        move_down 5
        if question.answers.any?
          text_box "Average rating", size: 12, width: 120, :at => [0,  cursor - 2]
          text_box "#{average_rating(question.answers.rating_average)}", size: 12, width: 120, :at => [4 * 30,  cursor - 2]
        else
          text_box "Average rating", size: 12, width: 120, :at => [0,  cursor - 2]
          text_box "0", size: 12, width: 120, :at => [4 * 30,  cursor - 2]
        end
      end
    end
  end
end

2 个答案:

答案 0 :(得分:1)

对于类似的问题,我使用了prawn-grouping gem

它会预先呈现您放置在group块中的任何内容,以测试它是否适合当前页面。如果没有,它会跳到下一页并呈现。

在你的情况下,你会做类似的事情:

def questions
  @survey.questions.each do |question|
    group :too_tall => lambda { start_new_page } do |g|
      g.text "#{question.title}", size: 20
      g.text "Answers #{question.answers.size}", size: 15
      if ["single", "select"].include? question.question_type.prefix
        if question.answers.choice_counter.any?
          g.chart choices: question.answers.choice_counter
        end
      end
      if question.question_type.prefix == "image"
        if question.answers.image_counter.any?
          g.chart images: question.answers.image_counter
        end
      end
      if question.question_type.prefix == "multiple"
        if question.answers.multiple_choice_counter.any?
          g.chart choices: question.answers.multiple_choice_counter
        end
      end
      if question.question_type.prefix == "raiting"
        move_down 5
        if question.answers.any?
          g.text_box "Average rating", size: 12, width: 120, :at => [0,  cursor - 2]
          g.text_box "#{average_rating(question.answers.rating_average)}", size: 12, width: 120, :at => [4 * 30,  cursor - 2]
        else
          g.text_box "Average rating", size: 12, width: 120, :at => [0,  cursor - 2]
          g.text_box "0", size: 12, width: 120, :at => [4 * 30,  cursor - 2]
        end
      end
    end
  end
end

免责声明:我从未使用鱿鱼所以我唯一不确定的是g.chart如果你让我知道那里有问题,我会试着弄明白。

更新鱿鱼

prawn-grouping宝石并不了解squid方法(如chart)。因此,我们可以从prawn-grouping gem中提取逻辑,并将其直接添加到survey_pdf.rb中。从this file复制第7-63行,然后从您的应用中删除prawn-grouping gem。

如果你很好奇为什么会这样......

Squid使用Prawn::Document.extensions方法强制Prawn::Document继承squid方法。你可以在squid gem代码here on line 37中看到它。

要使prawn-grouping生效,它会在Prawn::Document方法中创建新的group。你可以看到here on line 55。问题是通过Prawn::Document gem实例化的prawn-grouping并未继承squid方法...但SurveyPdf Prawn::Document squid实例继承grouping方法,因此通过将SurveyPdf逻辑添加到Prawn::Document类中,现在group方法中实例化的std::shared_ptr<T>将起作用。

答案 1 :(得分:0)

要回答评论中关于确定页面大小的问题,我会在评论中使用一些有用的方法:

d = Prawn::Document.new
d.y #full page height
d.margin_box.bottom #actually top since prawn starts at the bottom
d.margin_box.absolute_bottom #actual top with margins included
d.margin_box.top #usable page height
d.margin_box.absolute_top #same as #y 
d.cursor #where you are vertically on the page

所以你可以用一些基本的数学来确定合适度:

#this is all chart does excepting chart calls #draw 
#which we don't want to do until we determine if it fits 
c = Squid::Graph.new(d, choices: question.answers.choice_counter) 

#determine if the chart will fit vertically 
#if not start a new page and move to the top
unless d.cursor + c.height < d.margin_box.top
   d.start_new_page
   d.move_cursor_to(0)
end

#draw the chart onto the appropriate page
c.draw

希望这在某种程度上有所帮助