【问题标题】:Rails prawn chart not rendered completely at the bottom of the pageRails 大虾图表未完全呈现在页面底部
【发布时间】:2016-12-28 14:32:37
【问题描述】:

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

这是我用来渲染图表的代码

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

【问题讨论】:

  • 解决方案我将使用它来确定图表是否适合剩余空间,如果不能,则添加页面并在那里呈现。例如当前光标位置+图表高度>页面底部
  • 什么是页面底部?如果可能的话,你能给我一些代码吗?
  • 我添加了一个“答案”来回答您的评论而不是您的问题,但它应该对两者都有帮助

标签: ruby-on-rails ruby prawn


【解决方案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

免责声明:我从未使用过 squid,所以我唯一不确定的是 g.chart 如果您有问题,请告诉我,我会试着弄清楚。

鱿鱼更新

prawn-grouping gem 不知道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-grouping gem 实例化的Prawn::Document 没有继承squid 方法......但是你的SurveyPdf 实例Prawn::Document 确实继承了squid 方法,所以通过添加@ 987654348@ 逻辑到您的SurveyPdf 类中,现在在您的group 方法中实例化的Prawn::Document 将起作用。

【讨论】:

  • 是的,我在使用 g.chart 时得到了 #<:document:0xb006b084> 的未定义方法 `chart'
  • 好的,我想我已经明白了。您将要从第 7 行复制到第 63 行,从 this file in the grouping gem 复制到您的 survey_pdf.rb。然后从您的应用程序中删除分组宝石并重新运行。如果这有效(很确定它会);我会解释并更新我的答案
  • 所以我尝试了你所说的,但我没有看到这段代码有任何区别。图表应该跳转到下一页,而不是。
  • 而不是 group do |g| 这样做:group :too_tall =&gt; lambda { start_new_page } do |g|。这将强制它根据this example 开始一个新页面
  • 同样的事情......也许将图表移动到跨度块或类似的东西?
【解决方案2】:

为了回答您评论中关于确定页面大小的问题,我将介绍一些有用的方法,因为评论太长了:

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

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

【讨论】:

  • 好吧,我用类似的方法修复它 if (842 - cursor) + 250 > 842 start_new_page 否则 stay_in_same_page
  • @adavia 很高兴你成功了。抱歉,我花了一点时间才回复您,我之前从未使用过 squid,在我提出合理的答案之前,我不得不进行一些源代码审查以确定 chart 是如何实现的。
猜你喜欢
  • 2023-03-02
  • 1970-01-01
  • 2011-12-02
  • 2021-10-01
  • 2012-01-26
  • 1970-01-01
  • 2015-11-17
  • 2019-12-02
  • 2021-12-01
相关资源
最近更新 更多