Подключаем Google Chart Tools с использованием Google Visualization API на Drupal 7

Если Вам понадобилось на сайте вывести какую-либо информацию в виде графиков и диаграмм, то Google предлагает отличное решение этой задачи. Естественно первым делом следует проверить наличие готовых модулей на drupal.org: на момент написания этой статьи я не смог найти модуля, подключающего последнюю версию Google Chart Tools, поэтому решил написать свой небольшой модуль. Пример его использования приведён в конце статьи.

Если Вас устраивает старая версия, то отлично подойдет модуль Google chart API, который автоматически формирует url-ссылку и на основании её возвращает график в виде готового изображения. Поддерживается интеграция с Views. Однако какой-либо толковой документации по использованию представлений и модуля я не нашёл.

Итак, начнём написание своего модуля: в папке /sites/all/modules создаю каталог custom. В этом каталоге необходимо хранить все модули, предназначенные специально для этого сайта - это облегчит жизнь тому, кто будет просматривать Ваш сайт и интересоваться, какие модули загружены с сайта drupal.org, а какие - нет. Теперь в каталоге sites/all/modules/custom создаём подкаталог gcharts, который будет содержать все файлы, связанные с нашим модулем.

Сперва создаём файл gcharts.info:

name = Google Charts
description = Модуль предоставляет функционал построения графиков на основе Google Chart API
core = 7.x
package = Other

Этот файл хранит описание модуля. При использовании русских символов не забывайте переводить кодировку файла в UTF-8 (без BOM).

Основной файл модуля - gcharts.module. Привожу его содержимое с подробными комментариями:

<?php
/**
 * @file
 * Модуль предоставляет функционал построения графиков на основе Google Chart API
 *
 * @author
 * Павел Паршин
 */
 
/**
 * Implements hook_init().
 * Для работы модуля подключаем нужные библиотеки
 */
function gcharts_init() {
    drupal_add_js('https://www.google.com/jsapi');
    drupal_add_js(drupal_get_path('module', 'gcharts') . '/chart.js');
}

/**
 * Implements hook_theme().
 * Сообщаем Drupal о новой функции темизации
 */
function gcharts_theme($existing, $type, $theme, $path) {
    return array(
        'chart' => array(
            'render element' => 'chart',
        ),
    );
}
 
/**
 * БЛОКИ
 */

/**
 * Регистрируем новый блок для вывода графика.
 * Количество блоков можно создавать неограниченное.
 * В этом примере я буду использовать один блок для вывода одного графика.
 * На диаграмме будем выводить количество нод в терминах определенного словаря.
 */
function gcharts_block_info() {
    $blocks['gcharts_1'] = array(
        'info' => 'Количество нод в каждом термине словаря таксономии',
    );
    
    return $blocks;
}

function gcharts_block_view($delta = '') {
    switch ($delta) {
        case 'gcharts_1':
            $block['subject'] = 'Количество нод в каждом термине словаря таксономии';
            // Содержимое блока формируется внутренней функцией _gcharts_count_node_in_term()
            $block['content'] = _gcharts_count_node_in_term();
            break;
    }
    
    return $block;
}

/**
 * Собственно функция темизации.
 *
 * @param $variables
 */
function theme_chart(&$variables) {
    $variables = $variables['chart'];
    
    // Уникальный ID слоя, в который будет вставляться график
    $id = $variables['options']['id'];
    $chart[$id] = array(
        // Передаём массивы данных и настроек для формирования графика
        'data' => $variables['data'],
        'options' => $variables['options'],
    );

    // Тип графика
    $chart[$id]['type'] = $variables['options']['type'];

    drupal_add_js(array('chart' => $chart), 'setting');
    return '<div id="' . $id . '" class="chart-container"></div>';
}

/**
 * ФУНКЦИИ СОЗДАНИЯ ГРАФИКОВ И ДИАГРАММ
 */
 
/**
 * Функция построения диаграммы "Количество нод в каждом термине словаря таксономии"
 * Поиск нод проводим в словаре с VID = 1
 */
function _gcharts_count_node_in_term() {
    // Ищем все ноды в словаре с ID = 1
    // Для каждого термина определяем его имя и количество нод в нём
    $query = db_select('taxonomy_index', 't');
    $query->innerJoin('taxonomy_term_data', 'd', 't.tid = d.tid');
    $query->leftJoin('taxonomy_vocabulary', 'v', 'd.vid = v.vid');
    $query->condition('v.vid', 1);
    $query->fields('t', array('nid', 'tid'))
          ->fields('d', array('vid', 'name'))
          ->fields('v', array('vid'))
          ->groupBy('tid');
                
    $query->addExpression('COUNT(nid)', 'count_of_nodes');
    
    $nodes = $query->execute()->fetchAll();

    // Добавляем настройки вывода графика
    $chart['options'] = array(
        'id' => 'gcharts_count_node_in_term',
        'type' => 'PieChart',
        'width' => 510,
        'height' => 300,
        'title' => 'Количество нод в каждом термине словаря таксономии',
    );
    
    // Формируем массив данных: количество нод | имя термина таксономии
    foreach($nodes as $key => $node) {
        $chart['data']['#data'][$key]['value'] = $node->count_of_nodes;
        $chart['data']['#data'][$key]['name'] = $node->name;
    }

    // Имя и тип данных в колонках таблицы
    $chart['data']['#cols'][0]['label'] = 'Name_of_theme';
    $chart['data']['#cols'][0]['type'] = 'string';
    $chart['data']['#cols'][1]['label'] = 'Count_of_promises';
    $chart['data']['#cols'][1]['type'] = 'number';
    
    return theme('chart', array('chart' => $chart));
}

Подробная документация по данным в Google Chart Tools - DataTables and DataViews.

Теперь создаём последний файл - chart.js. Его содержимое:

(function($) {
   google.load('visualization', '1.0', {'packages':['corechart']});

   Drupal.behaviors.gcharts = {
     attach: function(context, settings) {
       $('.chart-container:not(.chart-processed)').once(function () {
         var id = this.id;
         google.setOnLoadCallback(function() { drawChart(id); });
       });
     }
   }

  /**
   * Получаем информацию о настройках и данных для построения графиков
   */
  function drawChart(id) {
    var attributes = Drupal.settings.chart[id];
    var data = attributes['data'];
    var googleoptions = {
          title: attributes['options']['title'],
          width: attributes['options']['width'],
          height: attributes['options']['height']
        };
    var type = attributes['type'];

    // Создаём таблицу данных.
    var googledata = new google.visualization.DataTable();
    // Колонки
    for (value in data['#cols']) {
      googledata.addColumn(data['#cols'][value]['type'], data['#cols'][value]['label']);
    }
    // Строки
    for (value in data['#data']) {
        var count = parseInt(data['#data'][value]['value']);
        googledata.addRow([data['#data'][value]['name'], count]);
    }

    var chart = getVisualizationObject(type, id);
    chart.draw(googledata, googleoptions);

    return chart;
  }

  function getVisualizationObject(type, id) {
    var chart = false;

    switch(type) {
      case 'PieChart':
        chart = new google.visualization.PieChart(document.getElementById(id));
        break;
      case 'BarChart':
        chart = new google.visualization.BarChart(document.getElementById(id));
        break;
      case 'AreaChart':
        chart = new google.visualization.AreaChart(document.getElementById(id));
        break;
      case 'BubbleChart':
        chart = new google.visualization.BubbleChart(document.getElementById(id));
        break;
      case 'CandlestickChart':
        chart = new google.visualization.CandlestickChart(document.getElementById(id));
        break;
      case 'ColumnChart':
        chart = new google.visualization.ColumnChart(document.getElementById(id));
        break;
      case 'ComboChart':
        chart = new google.visualization.ComboChart(document.getElementById(id));
        break;
      case 'Gauge':
        chart = new google.visualization.Gauge(document.getElementById(id));
        break;
      case 'GeoChart':
        chart = new google.visualization.GeoChart(document.getElementById(id));
        break;
      case 'LineChart':
        chart = new google.visualization.LineChart(document.getElementById(id));
        break;
      case 'ScatterChart':
        chart = new google.visualization.ScatterChart(document.getElementById(id));
        break;
      case 'SteppedAreaChart':
        chart = new google.visualization.SteppedAreaChart(document.getElementById(id));
        break;
      case 'Table':
        chart = new google.visualization.Table(document.getElementById(id));
        break;
      case 'TreeMap':
        chart = new google.visualization.TreeMap(document.getElementById(id));
        break;
    }

    return chart;
  }
})(jQuery);

Модуль готов. Можно добавлять свои функции и блоки для вывода нужной информации.

По поводу вставки HTML-кода в надписи к графикам: весь код преобразуется в обычный текст на стороне Google, поэтому использование html-тегов невозможно.

Теги: