Pull to refresh

Создание привлекательных диаграмм

Reading time 4 min
Views 1.7K
Проблема
Хотелось бы иметь возможность динамической генерации привлекательных диа­грамм на основе данных приложения.
Нам потребуется
  • ImageMagick. Эту библиотеку можно получить по адресу www.imagemagick.org.

  • Привязка Ruby к ImageMagick — RMagick. Устанавливается из gem-пакета rmagick. Настройка ImageMagick и RMagick иногда может вызывать небольшие затруднения. Перед установкой RMagick следует заглянуть в сборник самых распространенных вопросов и ответов по адресу rmagick.rubyforge.org/install-faq.html.Когда все получится, останется только радоваться.

  • Библиотека для построения диаграмм Джефри Грозенбака (Geoffrey Grosen-bach) Beautiful Gruff, которая устанавливается из gem-пакета gruff.


Решение
Давайте посмотрим как использовать Gruff для создания привлека­тельных диаграмм и как включать их в представления наших приложений. Да­вайте сразу же перейдем к делу.
Вся логика диаграмм будет помещена в один контроллер под названием Graph-Controller. Хотя держать логику составления диаграмм в отдельном контроллере и не обязательно, но в данном случае мы именно так и сделаем, чтобы собрать вместе весь код, относящийся к Gruff-библиотеке.
Gruff поддерживает несколько различных типов диаграмм: линейную, объем­ную, с областями, круговую и составную объемную (тут можно посмотреть примеры). Мы начнем с простой круго­вой диаграммы. Обычно диаграмма строится на данных, вычисленных на основе объектов модели или некоторых других статистических данных, относящихся к вашему домену. Чтобы не усложнять пример и сделать его доступным для всех Rails-программистов, в качестве модели данных для диаграмм мы будем исполь­зовать статистические данные нашего приложения.
Давайте к новому классу контроллера GraphController добавим следующее дейст­вие stats():

class GraphController < ApplicationController
   require 'gruff'
   require 'code_statistics'
  
   STATS_DIRECTORIES = [
   %w(Helpers app/helpers),
   %w(Controllers app/controllers),
   %w(APIs app/apis),
   %w(Components components),
   %w(Functional\ tests test/functional),
   %w(Model app/model),
   %w(Unit\ tests test/unit),
   %w(Libraries lib/),
   %w(Integration\ tests test/integration)
   ].collect { |name, dir|
    [ name, "#{RAILS_ROOT}/#{dir}"]
   }.select { |name, dir|
    File.directory?(dir)
   }
   
 def stats
   code_stats = CodeStatistics.new(*STATS_DIRECTORIES)
   statistics = code_stats.instance_variable_get(:@statistics)
   g = Gruff::Bar.new(700)
   g.font = "/Library/Fonts/Arial"
   g.title = «Code Stats»
   g.theme_37signals
   g.legend_font_size = 10
   0xFDD84E.step(0xFF0000, 1500) do |num|
    g.colors << "#%x" % num
   end
   statistics.each do |key, values|
    g.data(key, [values[«codelines»]])
   end
   send_data(g.to_blob,
        :disposition => 'inline',
        :type => 'image/png',
        :filename => 'code_stats.png')
 end
end
* This source code was highlighted with Source Code Highlighter.


Запуск этого действия приведет к появлению красочной диаграммы, изобра­женной на рисунке.
Давайте пройдемся по этому коду. Вначале затребована библиотека Gruff, а затем определено значение константы STATS_DIRECTORIES, позаимствованной из Rake-задачи stats( ), поставляемой с Rails. Ее функция — предоставить список ка­талогов для обработки в классе CodeStatistics.
Теперь перейдем к действию stats( ). В первых двух строчках устанавливается наша модель данных, которая будет передана механизму вычерчивания диаграм­мы. Ввиду отсутствия средств получения доступа к необработанным статистиче­ским данным нам придется прибегнуть к довольно неприглядному трюку и вос­пользоваться методом instance_variable_get(). В вашем приложении эта часть должна быть заменена запросом на выбор той модели, которая для него определена.



Следующие несколько строк потрачены на установку диаграммы. Число 700, переданное конструктору, определяет ширину изображения. Устанавливается шрифт заголовка, а затем выбирается (дополнительно) одна из тем, имеющих­ся в Gruff. Можно также выбрать и другие темы: theme_keynote, theme_rails_keynote и theme_odeo. Затем, поскольку в нашей легенде присутствуют довольно длинные слова, устанавливается размер шрифта легенды. Чтобы завершить установку конфигурации, мы осуществляем циклический перебор шестнадцатеричных зна­чений для установки диапазона цветовых решений диаграммы. При небольшом наборе данных в этом нет необходимости, поскольку используемые по умолча­нию темы располагают достаточным набором цветов, чтобы обеспечить каждую строку данных.
Напоследок мы наполним диаграмму данными, для чего осуществим последо­вательный перебор хэша, содержащего статистику кода, и добавим к диаграмме по одной строке данных на каждый присутствующий в хэше элемент. В качестве второго параметра метода data( ), относящегося к диаграмме, используется массив фактических значений. В данном случае отслеживается только одно значение для каждой строки, но все равно нужно передавать массив, поэтому мы используем одноэлементный массив, содержащий количество строк кода в данном каталоге.
В завершение, чтобы не создавать файл в файловой системе, для потоковой передачи данных изображения браузеру используется встроенный в Rails метод send_data( ).
А если захочется преобразовать эту диаграмму в линейную? Проще некуда! Нужно только в строке, где считывается Gruff::Pie, считать Gruff::Bar. Вот и все! То же самое относится и к другим имеющимся в Gruff типам диаграмм, хотя там есть и типы, не подходящие для нашего двумерного набора данных, например Line и Area.


После того как будут усвоены основы (и правильно установлен ImageMa-gick!), Gruff станет весьма простой и удобной библиотекой для составления диа­грамм. Использование практически неизменного интерфейса для различных ти­пов диаграмм значительно упрощает проведение исследований и экспериментов с этим средством.

P.S.
Чуть побольше про библиотеку можно узнать тут

Кросспост из моего блога
Tags:
Hubs:
+2
Comments 2
Comments Comments 2

Articles