You are here

flot.module in Flot 7

Same filename and directory in other branches
  1. 8 flot.module
  2. 6 flot.module

File

flot.module
View source
<?php

/**
 * Implements hook_requirements().
 */
function flot_requirements($phase) {
  $requirements = array();

  // Check for the flot library.
  if (file_exists(_flot_get_library_path() . '/jquery.flot.js')) {
    $requirements['flot'] = array(
      'value' => t('Flot library found at !path', array(
        '!path' => _flot_get_library_path() . '/jquery.flot.js',
      )),
    );
  }
  else {
    $path = module_exists('libraries') ? 'sites/all/libraries/flot or ' . drupal_get_path('module', 'flot') . '/flot' : drupal_get_path('module', 'flot') . '/flot';
    $requirements['flot'] = array(
      'value' => t('Not installed'),
      'severity' => REQUIREMENT_ERROR,
      'description' => t('The flot library was not installed. !download the flot library and extract it to %path so that the file jquery.flot.js can be found at %flotpath', array(
        '!download' => l('Download', 'http://code.google.com/p/flot/downloads/list', array(
          'attributes' => array(
            'title' => t('Download flot'),
          ),
        )),
        '%path' => $path,
        '%flotpath' => $path . '/jquery.flot.js',
      )),
    );
  }
  $requirements['flot']['title'] = t('Flot Library');
  return $requirements;
}

/**
 * Implements hook_theme().
 */
function flot_theme() {
  return array(
    'flot_graph' => array(
      'variables' => array(
        'element' => NULL,
        'data' => NULL,
        'options' => NULL,
        'zoom' => NULL,
      ),
    ),
  );
}
function template_preprocess_flot_graph(&$variables) {
  static $n = 0;
  $zoom = isset($variables['addselectionfilter']) && $variables['addselectionfilter'] || isset($variables['zoom']) && $variables['zoom'];
  $data = array();
  if (isset($variables['data'])) {
    $data = $variables['data'];
  }
  if (!isset($variables['element']['style'])) {
    $variables['element']['style'] = "width:100%;height:200px";
  }
  $options = new stdClass();
  if (isset($variables['options'])) {
    $options = (object) $variables['options'];
  }
  $variables['element']['class'] = isset($variables['element']['class']) ? $variables['element']['class'] . ' flot' : 'flot ';
  if ($zoom) {
    $variables['element']['class'] = isset($variables['element']['class']) ? $variables['element']['class'] . ' flot-with-zoom' : 'flot-with-zoom';
    $variables['element']['id'] = 'flot-view-zoomable-' . $n++;
    $options->selection['mode'] = 'x';
  }
  else {
    if (!isset($variables['element']['id'])) {
      $n++;
      $variables['element']['id'] = 'flot-auto-identifier-' . $n;
    }
  }
  if (isset($variables['legend']) && $variables['legend']) {
    if (!isset($options->legend)) {
      $options->legend = new stdClass();

      // Default position bottom
      $options->legend->show = TRUE;
      $options->legend->position = 'ne';
    }
    else {
      $options->legend->show = TRUE;
      if (!isset($options->legend->position)) {
        $options->legend->position = 'ne';
      }
    }
  }
  else {
    if (!isset($options->legend)) {
      $options->legend = new stdClass();
    }
    $options->legend->show = FALSE;
  }
  $variables['options'] = $options;
  $legend_element = array();
  if (isset($options->legend) && isset($options->legend->position) && $options->legend->position == 'bottom' && !isset($options->legend->container)) {
    $variables['element']['legendid'] = $variables['element']['id'] . '-legend';
    $options->legend->container = '#' . $variables['element']['legendid'];
    $options->legend->containerid = $variables['element']['legendid'];
    $legend_element = array(
      'id' => $variables['element']['legendid'],
      'class' => array(
        'legend',
        'legend-bottom',
      ),
    );
  }
  flot_add_js('core');
  if (isset($options->selection)) {
    flot_add_js('selection');
  }
  if (isset($options->series->pie->show) && $options->series->pie->show || isset($options->pie) && $options->pie) {
    $options = (object) ((array) new flotStylePie() + (array) $options);
    flot_add_js('pie');
  }
  foreach ($variables['data'] as $s => $serie) {
    if (isset($serie->stack)) {
      flot_add_js('stack');
    }
    if (isset($serie->bars->order)) {
      flot_add_js('orderBars');
    }
  }
  $jsdata = '
    jQuery(document).ready(function() {
      Drupal.flot[\'' . str_replace('-', '_', $variables['element']['id']) . '\'] = {};
      Drupal.flot[\'' . str_replace('-', '_', $variables['element']['id']) . '\'][\'flot\'] = jQuery.plot(jQuery("#' . $variables['element']['id'] . '"), ' . drupal_json_encode((array) $data) . ', ' . drupal_json_encode($options) . ');
      Drupal.flot[\'' . str_replace('-', '_', $variables['element']['id']) . '\'][\'options\'] = ' . drupal_json_encode((array) $options) . ';
      Drupal.flot[\'' . str_replace('-', '_', $variables['element']['id']) . '\'][\'data\'] = ' . drupal_json_encode((array) $data) . ';
    });
  ';
  drupal_add_js($jsdata, array(
    'type' => 'inline',
    'scope' => 'footer',
  ));
  $variables['element'] = array(
    'graph' => array(
      'style' => $variables['element']['style'],
      'class' => isset($variables['element']['class']) ? array(
        $variables['element']['class'],
      ) : array(),
      'id' => $variables['element']['id'],
    ),
  );
  $zoom_element = array();
  if ($zoom && (!isset($options->series->pie->show) || $options->series->pie->show == FALSE)) {
    $zoom_options = clone $options;
    $zoom_data = $data;
    if (!isset($zoom_options->series)) {
      $zoom_options->series = new stdClass();
    }
    if (!isset($zoom_options->grid)) {
      $zoom_options->grid = new stdClass();
    }
    if (!isset($zoom_options->series->points)) {
      $zoom_options->series->points = new stdClass();
    }
    if (!isset($zoom_options->series->lines)) {
      $zoom_options->series->lines = new stdClass();
    }
    $zoom_options->series->points->show = FALSE;
    $zoom_options->series->lines->lineWidth = 1;
    $zoom_options->series->shadowSize = 0;
    $zoom_options->grid->hoverable = FALSE;
    $zoom_options->selection['mode'] = 'x';
    $zoom_options->legend->show = FALSE;
    if (isset($zoom_options->xaxis)) {
      unset($zoom_options->xaxis->min);
      unset($zoom_options->xaxis->max);
    }
    if (isset($zoom_options->yaxis)) {
      unset($zoom_options->yaxis->min);
      unset($zoom_options->yaxis->max);
      unset($zoom_options->yaxis->autoscaleMargin);
    }
    foreach ($zoom_data as &$zdata) {
      if (isset($zdata->lines) || isset($zdata->bars) || isset($zdata->pie)) {
        if (!isset($zdata->points)) {
          $zdata->points = new stdClass();
        }
        $zdata->points->show = FALSE;
      }
    }
    $jszoomdata = '
      jQuery(document).ready(function() {
        Drupal.flot[\'' . str_replace('-', '_', $variables['element']['graph']['id'] . '-zoom') . '\'] = {};
        Drupal.flot[\'' . str_replace('-', '_', $variables['element']['graph']['id'] . '-zoom') . '\'][\'flot\'] = jQuery.plot(jQuery("#' . $variables['element']['graph']['id'] . '-zoom' . '"), ' . drupal_json_encode((array) $zoom_data) . ', ' . drupal_json_encode($zoom_options) . ');
        Drupal.flot[\'' . str_replace('-', '_', $variables['element']['graph']['id'] . '-zoom') . '\'][\'options\'] = ' . drupal_json_encode((array) $zoom_options) . ';
        Drupal.flot[\'' . str_replace('-', '_', $variables['element']['graph']['id'] . '-zoom') . '\'][\'data\'] = ' . drupal_json_encode((array) $zoom_data) . ';
      });
    ';
    drupal_add_js($jszoomdata, array(
      'type' => 'inline',
      'scope' => 'footer',
    ));
    $width = array();
    preg_match('/width:(.*)px;/', $variables['element']['graph']['style'], $width);
    $zoom_element = array(
      'id' => $variables['element']['graph']['id'] . '-zoom',
      'style' => 'width:' . $width[1] . 'px;height:100px',
      'class' => array(
        'flot-zoom',
      ),
    );
  }
  $variables['element']['zoom'] = $zoom_element;
  $variables['element']['legend'] = $legend_element;
}

/**
 * Main flot graphing function
 *
 * @param $element
 *   An associative array to define a placeholder element. If an 'id' is
 *   omitted one will be generated, If no 'style' is specified and width and
 *   height style will be added. In short you can just pass an empty array and
 *   everything will still work. This argument is essentially optional and has
 *   been kept as the first argument to remain consistant with flots own api.
 * @param $data
 *   The data series for the graph. Optional. See flot's API.txt for more
 *   details. This module defines the flotData class which can  be used or
 *   extended to make generating data objects simpler.
 * @param $options
 *   Options to pass to flot. Optional. See flot's API.txt for more details.
 * @param $loader
 *   Allows alterative loading of flot data. If 'FALSE' data will passed
 *   directly to an invocation of $.plot(). Otherwise the contents of $loader
 *   should be js.
 *
 * @return
 *   The placeholder element
 */
function theme_flot_graph($variables) {
  $element = $variables['element'];
  $output = array(
    'graph' => array(
      '#type' => 'container',
      '#attributes' => $element['graph'],
    ),
    'zoom' => array(
      '#type' => 'container',
      '#attributes' => $element['zoom'],
    ),
    'legend' => array(
      '#type' => 'container',
      '#attributes' => $element['legend'],
    ),
  );
  return drupal_render($output);
}

/**
 * Helper to add flot's js
 */
function flot_add_js($type = 'core') {
  drupal_add_js(drupal_get_path('module', 'flot') . '/flot.utils.js');
  static $added = array();
  $path = _flot_get_library_path();
  if (!isset($added['core']) && ($type = 'core')) {
    $forie = array(
      '#type' => 'markup',
      '#markup' => '<!--[if IE]><script language="javascript" type="text/javascript" src="' . base_path() . $path . '/excanvas.js"></script><![endif]-->',
    );
    drupal_add_html_head($forie, 'flot');
    drupal_add_js($path . '/jquery.flot.js');
    drupal_add_js('Drupal.flot = {};', 'inline');
    drupal_add_css(drupal_get_path('module', 'flot') . '/flot.legend.css');
    $added['core'] = TRUE;
  }
  if (!isset($added['stack']) && $type == 'stack') {
    drupal_add_js($path . '/jquery.flot.stack.js');
    $added['stack'] = TRUE;
  }
  if (!isset($added['pie']) && $type == 'pie') {
    drupal_add_js($path . '/jquery.flot.pie.js');
    drupal_add_css(drupal_get_path('module', 'flot') . '/flot.pie.css');
    $added['pie'] = TRUE;
  }
  if (!isset($added['selection']) && $type == 'selection') {
    drupal_add_js($path . '/jquery.flot.selection.js');
    $added['selection'] = TRUE;
  }
  if (!isset($added['orderBars']) && $type == 'orderBars') {
    drupal_add_js(drupal_get_path('module', 'flot') . '/js/jquery.flot.orderBars.js');
    $added['orderBars'] = TRUE;
  }
}
function _flot_get_library_path() {
  if (module_exists('libraries') && libraries_get_path('flot')) {
    $path = libraries_get_path('flot');
  }
  if (!isset($path)) {
    $path = drupal_get_path('module', 'flot') . '/flot';
  }
  return $path;
}

/**
 * Data class for the flot API.
 *
 * Make some nested objects to keep things simple when creating a data series.
 */
class flotData {
  public $data;
  public $series;
  function __construct($data) {
    $this->data = $data;
    $this->series = new stdClass();
    $this->series->lines = new stdClass();
    $this->series->bars = new stdClass();
    $this->series->points = new stdClass();
    $this->series->pie = new stdClass();
    $this->grid = new stdClass();
  }

}

/**
 * Style class for the flot API.
 *
 * Provides some sensible defaults and helper methods for managing axes.
 */
class flotStyle {

  // Use flot's default colors: public $colors;
  public $grid;
  public $series;
  function __construct() {
    $this->series = new stdClass();
    $this->series->lines = new stdClass();
    $this->series->bars = new stdClass();
    $this->series->points = new stdClass();
    $this->series->pie = new stdClass();

    // Use flot's default colors: $this->colors = array('#666', '#999', '#ccc');
    $this->shadowSize = 0;
    $this->grid = new stdClass();
    $this->grid->labelMargin = 0;
    $this->grid->tickColor = '#eee';
    $this->grid->backgroundColor = '#f8f8f8';
    $this->grid->borderWidth = 0;
    $this->grid->hoverable = TRUE;
    $this->grid->autoHighlight = TRUE;
    $this->grid->clickable = FALSE;
  }
  function axis_ticks($axis = 'yaxis', $ticks = array()) {
    if (count($ticks)) {
      $this->{$axis} = new stdClass();
      $this->{$axis}->ticks = $ticks;
    }
  }
  function axis_range($axis = 'yaxis', $range = array(), $granularity = 0) {
    if (count($range)) {
      $this->{$axis} = new stdClass();
      $this->{$axis}->min = min($range);
      $this->{$axis}->max = max($range);
      if (is_numeric($granularity) && $granularity != 0) {
        $tickSize = ($this->{$axis}->max - $this->{$axis}->min) / $granularity;
        $this->{$axis}->tickSize = floor($tickSize);
      }
    }
  }
  function createPie() {
    $this->series->pie = new flotPie();
  }

}

/*
 * Parent class for Flot elements
 */
class flot {
  function __construct($settings = NULL) {
    if (is_array($settings)) {
      foreach ($settings as $key => $setting) {
        if (!empty($setting) && $setting !== 0) {
          $this->{$key} = $setting;
        }
      }
    }
  }

}

/**
 * Basic line style class for the flot.
 */
class flotLine extends flot {
  function __construct($settings = NULL) {
    $this->show = TRUE;
    $this->lineWidth = 1;
    parent::__construct($settings);
  }

}

/**
 * Basic bar style class for the flot.
 */
class flotBar extends flot {
  function __construct($settings = NULL) {
    $this->show = TRUE;
    $this->lineWidth = 4;
    $this->fill = 0.5;
    parent::__construct($settings);
  }

}

/**
 * Points style class for the flot.
 */
class flotPoint extends flot {
  function __construct($settings = NULL) {
    $this->show = TRUE;
    $this->lineWidth = 1;
    $this->fill = 0.1;
    parent::__construct($settings);
  }

}

/**
 * Basic pie style class for the flot.
 */
class flotPie extends flot {
  function __construct($settings = NULL) {
    $this->label = new stdClass();
    $this->label->background = new stdClass();
    $this->show = TRUE;
    $this->radius = 1;
    $this->label->show = TRUE;
    $this->label->radius = 2 / 3;
    $this->label->threshold = 0.1;
    $this->label->background->opacity = 1;
    parent::__construct($settings);
  }

}

/**
 * Legacy: Datapoints
 */
class flotStyleLine extends flotStyle {
  function __construct() {
    parent::__construct();
    $this->series->lines->show = TRUE;
    $this->series->lines->lineWidth = 1;
    $this->series->lines->fill = 0.1;
  }

}
class flotStyleBar extends flotStyle {
  function __construct() {
    parent::__construct();
    $this->series->bars->show = TRUE;
    $this->series->bars->lineWidth = 0;
    $this->series->bars->fill = 0.5;
  }

}
class flotStylePoint extends flotStyle {
  function __construct() {
    parent::__construct();
    $this->series->points->show = TRUE;
    $this->series->points->lineWidth = 1;
    $this->series->points->fill = 0.1;
  }

}
class flotStylePie extends flotStyle {
  function __construct() {
    parent::__construct();
    $this->series->pie->show = TRUE;
    $this->series->pie->radius = 1;
    $this->series->pie->label = new stdClass();
    $this->series->pie->label->show = TRUE;
    $this->series->pie->label->radius = 2 / 3;
    $this->series->pie->label->threshold = 0.1;
    $this->series->pie->label->background = new stdClass();
    $this->series->pie->label->background->opacity = 1;
  }

}

Functions

Namesort descending Description
flot_add_js Helper to add flot's js
flot_requirements Implements hook_requirements().
flot_theme Implements hook_theme().
template_preprocess_flot_graph
theme_flot_graph Main flot graphing function
_flot_get_library_path

Classes

Namesort descending Description
flot
flotBar Basic bar style class for the flot.
flotData Data class for the flot API.
flotLine Basic line style class for the flot.
flotPie Basic pie style class for the flot.
flotPoint Points style class for the flot.
flotStyle Style class for the flot API.
flotStyleBar
flotStyleLine Legacy: Datapoints
flotStylePie
flotStylePoint